如何将结果写在列表中而不是在序言中打印出来

时间:2018-10-08 14:13:51

标签: list prolog

我正在写一个谓词,用于成对查找更大的数字。如果该号码没有配对-它将被添加。

write_list([A|[]]):- write(A).
write_list([A, B|Tail]) :- ((A>B, write(A));(A<B,write(B))), nl, 
write_list([B|Tail]).

我的问题是,我无法弄清楚如何将结果写到另一个列表中,而不是打印出结果:

write_list([1,2,6,8,5], X).
X = [2,6,8,8,5].

1 个答案:

答案 0 :(得分:2)

write仅将内容打印到标准输出,而不将其“屈服”到结果列表。在Prolog中,唯一产生值的方法是通过统一。

因此,您需要定义谓词maxpair/2,而不是 write_list/1

谓词因此如下:

:- use_module(library(clpfd)).

maxpair([A], [A]).
maxpair([A, B|Tail], [H|T]) :-
    H #= max(A, B),
    maxpair([B|Tail], T).

第一个子句说单例列表的maxpair/2是该单例列表。后者表示包含两个或多个列表的列表的maxpair/2是一个以前两个元素的最大值开头的列表,我们递归到列表的尾部。

上面的内容也可以反向列出。例如:

?- write_list(L, [5, 3, 2, 1]).
L = [5, 3, 2, 1] ; 
false.
?- write_list(L, [1, 4, 2, 5]).
false.
?- write_list(L, [3, 3, 5, 5]).
L = [_542, _548, _554, 5],
_542 in inf..3,
3#=max(_542, _548),
_548 in inf..3,
3#=max(_548, _554),
_554 in inf..3 ;
false.
?- write_list(L, [3, 5, 5, 4]).
L = [_1128, _1134, 5, 4],
_1128 in inf..3,
3#=max(_1128, _1134),
_1134 in inf..3 ;
false.

因此,根据情况,它可以:

  1. 完全重建列表;
  2. 用一些带有间隔的变量构造一个列表;或
  3. 证明不可能构造这样的列表。