Prolog 如果输入不正确,如何创建无限列表?
我编写了一个函数,告诉用户,给定输入的列表,列表是否已排序。但是,如果用户输入一个变量作为输入,而不是列表,我希望输出一个无限列表。我该怎么办?这是当前的代码Prolog 如果输入不正确,如何创建无限列表?,prolog,Prolog,我编写了一个函数,告诉用户,给定输入的列表,列表是否已排序。但是,如果用户输入一个变量作为输入,而不是列表,我希望输出一个无限列表。我该怎么办?这是当前的代码 ordered([]). ordered([_]). ordered([X,Y|Ys]) :- X =< Y , ordered( [Y|Ys] ). 我还想让变量像这样创建无限列表 ? ordered(L). L = []; L = [_1322] ; L = [_1322, _1323] ; L = [_1322, _1323
ordered([]).
ordered([_]).
ordered([X,Y|Ys]) :- X =< Y , ordered( [Y|Ys] ).
我还想让变量像这样创建无限列表
? ordered(L).
L = [];
L = [_1322] ;
L = [_1322, _1323] ;
L = [_1322, _1323, _1324] ;
L = [_1322, _1323, _1324, _1325].
列表应增加,直到用户退出,如图所示
列表应增加,直到用户退出,如图所示
解决方案:
ordered([]).
ordered([_]).
ordered([X,Y|Ys]) :- X #=< Y , ordered( [Y|Ys] ).
有序([])。
有序的。
有序([X,Y | Ys]):-X#=
编辑:
算术表达式X小于或等于Y。在对整数进行推理时,替换(变量列表应具有哪些属性?安东·达尼洛夫目前接受的答案是,
[3,2,1]
不是有序列表:
?- List = [A, B, C], List = [3, 2, 1], ordered(List).
false.
?- List = [A, B, C], ordered(List), List = [3, 2, 1].
List = [3, 2, 1],
A = 3,
B = 2,
C = 1 ;
false.
但它也表示,[3,2,1]
是有序列表的一个实例:
?- List = [A, B, C], List = [3, 2, 1], ordered(List).
false.
?- List = [A, B, C], ordered(List), List = [3, 2, 1].
List = [3, 2, 1],
A = 3,
B = 2,
C = 1 ;
false.
从逻辑上看,这是一个矛盾。从程序上看,这很好,但这可能不是最好的解决方案,但我相信它可以让您了解如何做您需要的事情。在SWI Prolog中,谓词
freeze(+Var,:Goal)
延迟Goal
的执行,直到Var
被绑定
ordered([]).
ordered([_]).
ordered([X,Y|R]) :-
freeze( X,
freeze( Y,
( X @=< Y,
ordered([Y|R]) ) ) ).
对于无限列表,您需要“使用”其前缀:
take([]).
take([_|R]) :- take(R).
下面是一个无限列表的示例:
?- ordered(L), take(L).
L = [] ;
L = [_375396] ;
L = [_376366, _376372],
freeze(_376366, freeze(_376372, (_376366@=<_376372, ordered([])))) ;
L = [_377472, _377478, _377484],
freeze(_377472, freeze(_377478, (_377472@=<_377478, ordered([_377484])))) ;
L = [_378590, _378596, _378602, _378608],
freeze(_378590, freeze(_378596, (_378590@=<_378596, ordered([_378602, _378608])))) ;
L = [_379720, _379726, _379732, _379738, _379744],
freeze(_379720, freeze(_379726, (_379720@=<_379726, ordered([_379732, _379738, _379744]))))
?-有序(L),取(L)。
L=[];
L=[u 375396];
L=[[U 376366,[U 376372],
冻结(_376366,freeze(_376372,(_376366@=以下操作成功:?-ordered(List),List=[3,2,1]。
从逻辑角度看,这并不好。当用户试图找到第二个解决方案时,以下查询会导致堆栈溢出错误:?-ordered(List),List=[1,2,3]。
。是的。这是因为ordered(List)
尝试生成越来越多的解决方案:长度为4、5、6等的列表,直到无穷大。这些列表中没有一个与[1、2、3]相统一
,但是Prolog会一直尝试,直到内存满为止。没有办法用一个生成无限多个解决方案的谓词来解决这个问题。除非它像你的一样懒惰,我喜欢!看我的解决方案,它甚至可以用于查询?-有序(List),List=[1,2,3]。
递归调用不应该是有序的([Y | R])
?否则我想您会接受[1,2,0]
。是的!谢谢!我已经纠正了这个错误。
?- ordered([1,2,3]).
true.
?- ordered([1,2,3,0]).
false.
?- ordered(L), L=[1,2,3].
L = [1, 2, 3] ;
false.
?- ordered(L), L=[1,2,3,0].
false.
take([]).
take([_|R]) :- take(R).
?- ordered(L), take(L).
L = [] ;
L = [_375396] ;
L = [_376366, _376372],
freeze(_376366, freeze(_376372, (_376366@=<_376372, ordered([])))) ;
L = [_377472, _377478, _377484],
freeze(_377472, freeze(_377478, (_377472@=<_377478, ordered([_377484])))) ;
L = [_378590, _378596, _378602, _378608],
freeze(_378590, freeze(_378596, (_378590@=<_378596, ordered([_378602, _378608])))) ;
L = [_379720, _379726, _379732, _379738, _379744],
freeze(_379720, freeze(_379726, (_379720@=<_379726, ordered([_379732, _379738, _379744]))))