首页 > 解决方案 > 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).

随机列表确实得到排序。区别从何而来?

标签: prologquicksorthigher-order-functions

解决方案


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

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


推荐阅读