SWI-Prolog 分区谓词在 REPL 中的工作方式与在程序中的工作方式不同



我这样使用 SWISH 进行快速排序:

qsort([],[]).
qsort([H|T],S) :-
partition([X,O]>>compare(O,X,H),T,L,E,G),
qsort(L,A),
qsort(G,Z),
append([A,[H|E],Z],S).
main :-
length(L,22),
maplist(random(0,9),L),
qsort(L,S),
maplist(writeln,[L,S]).

它无法正常工作。输入和输出列表相同。但是,当我在右侧的 REPL 中运行它时:length(S,22), maplist(random(0,9),S),[H|T]=S, partition([X,O]>>compare(O,X,H),T,L,E,G).

随机列表确实会被排序。区别在哪里?

编译qsort/2谓词的第二个子句时,除了编译 lambda 表达式时它是一个变量之外,没有关于H的信息。在 lambda 表达式中出现的任何变量如果在本地 lambda 参数中找不到,则必须使用{}/1构造进行声明。但是,在顶级解释器上运行查询时,当解释 lambda 表达式时,H已被绑定,因此不再是变量(因此不需要使用{}/1构造(。

请注意,这里有几个细节超出了 lambda 库本身的范围:(1( 编译器是否在编译时识别出您正在使用一个参数是 lambda 表达式的元谓词?(2( 如何解释顶级查询?完整查询是首先完全编译还是元解释?这些详细信息取决于系统本身。

当我在[X,O]>>compare(O,X,H)前面添加{H}/时,它有效。可能是顶级不需要(但允许(它用于预期行为的错误。但我不确定,所以欢迎知情人士的回答。

最新更新