SWI-Prolog 分区谓词在 REPL 中的工作方式与在程序中不同
SWI-Prolog partition predicate works differently in REPL than in programme
我使用 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).
随机列表确实得到了排序。哪里不一样?
当我在[X,O]>>compare(O,X,H)
前面添加{H}/
时它起作用了。可能是顶层不需要(但允许)预期行为的错误。不过我也不是很清楚,欢迎有识之士解答。
编译 qsort/2
谓词的第二个子句时,除了在编译 lambda 表达式时它是一个变量外,没有关于 H
的信息。在本地 lambda 参数中找不到的 lambda 表达式中出现的任何变量都必须使用 {}/1
结构声明。但是,当 运行 您在顶级解释器中查询时,在解释 lambda 表达式时,H
已绑定,因此不再是变量(使用 {}/1
构造不必要)。
请注意,这里有几个细节在发挥作用,它们超出了 lambda 库本身的范围:(1) 编译器是否在编译时识别出您正在调用带有 lambda 参数的元谓词表达? (2) 如何解释顶级查询?完整查询是首先完全编译还是元解释?这些细节取决于系统本身。
我使用 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).
随机列表确实得到了排序。哪里不一样?
当我在[X,O]>>compare(O,X,H)
前面添加{H}/
时它起作用了。可能是顶层不需要(但允许)预期行为的错误。不过我也不是很清楚,欢迎有识之士解答。
编译 qsort/2
谓词的第二个子句时,除了在编译 lambda 表达式时它是一个变量外,没有关于 H
的信息。在本地 lambda 参数中找不到的 lambda 表达式中出现的任何变量都必须使用 {}/1
结构声明。但是,当 运行 您在顶级解释器中查询时,在解释 lambda 表达式时,H
已绑定,因此不再是变量(使用 {}/1
构造不必要)。
请注意,这里有几个细节在发挥作用,它们超出了 lambda 库本身的范围:(1) 编译器是否在编译时识别出您正在调用带有 lambda 参数的元谓词表达? (2) 如何解释顶级查询?完整查询是首先完全编译还是元解释?这些细节取决于系统本身。