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]))))