在Prolog中,如何对用符号和谓词链表示的偶数和奇数进行排序?

时间:2018-02-12 17:13:15

标签: prolog knowledge-management

标题可能很模糊,只看代码

number(one, odd).
number(two, even).
number(three, odd).
number(four, even).
number(five, odd).

greaterThan(five, four).
greaterThan(four, three).
greaterThan(three, two).
greaterThan(two, one).

if_larger(A,B):- elder_than(A,B).
if_larger(A,B):- elder_than(A,X),greaterThan(X,B).

even(A):- number(A, even).
odd(A):- number(A, odd).

largest(A):-
    not(greaterThan(_,A)).

largestEven(A):-
    even(A),
    not((if_larger(X,A), even(X))).

largestOdd(A):-
    odd(A),
    not((if_larger(X,A), odd(X))).

如何按以下顺序对数字进行排序:一,三,五,二,四。

我认为解决方案应采用以下形式,但我无法弄明白。

next(A, Next):- 
    odd(A), odd(Next),
    ...

next(A, Next):- 
    even(A), even(Next),
    ...

next(A, Next):- 
    odd(A), even(Next),
    ...

或者,是否可以生成列表,例如[一,三,五,二,四]。

1 个答案:

答案 0 :(得分:0)

我会回答我自己的问题。我们的想法是使用final / 3构建所有数字的列表,然后在数字列表中应用插入排序。

实施

number(five, odd).
number(one, odd).
number(two, even).
number(three, odd).
number(four, even).

greaterThan(five, four).
greaterThan(four, three).
greaterThan(three, two).
greaterThan(two, one).

even(A):- number(A, even).
odd(A):- number(A, odd).

is_larger(A,B):- greaterThan(A,B).
is_larger(A,B):- greaterThan(A,X),is_larger(X,B).

% the order considered even and odd
% which is odd before even, small before large
in_order(A,B):- odd(A), even(B).
in_order(A,B):- odd(A), odd(B), is_larger(B,A).     % smaller numbers comes first
in_order(A,B):- even(A), even(B), is_larger(B,A).   % smaller numbers comes first


% apply insertion sort on A 
insertion_sort(A,B):- sort_helper(A, [], B).
sort_helper([], OldList, OldList).
sort_helper([H|T], OldList, Result):- insert(H, OldList, NewList), sort_helper(T, NewList, Result).

% insert(A,L,Result) put A into L 
insert(A, [], [A]).
insert(A, [H|T], [A,H|T]):- in_order(A,H).
insert(A, [H|T], [H|NewList]):- not(in_order(A,H)), insert(A, T, NewList).

% Interface
oddEvenSortedList(OddEvenSortedList):- findall(A, number(A,_), Numbers), insertion_sort(Numbers, OddEvenSortedList).

结果

?- ['number.pl'].
true.

?- oddEvenSortedList(OddEvenSortedList).
OddEvenSortedList = [one, three, five, two, four].

这个问题实际上是我学校作业的修改版本。最初的问题是Prolog中的皇室继承。我已经问过很多朋友如何解决这个问题,最后得到了这个解决方案。我也会在这里发布原始问题。

  

旧的皇家继承规则规定,在沿着女性线的考虑之前,按照出生顺序沿着男性线传递宝座 - 同样根据出生顺序。伊丽莎白女王,英国君主,有四个后代;即:查尔斯王子,安娜公主,安德鲁王子和爱德华王子 - 按出生顺序列出。