prolog - 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).
随机列表确实得到排序。区别从何而来?
解决方案
编译谓词的第二个子句时,除了编译 lambda 表达式时它是一个变量之外,qsort/2
没有其他信息。H
lambda 表达式中出现的任何在本地 lambda 参数中找不到的变量都必须使用该{}/1
构造进行声明。但是,在顶级解释器上运行查询时,在解释 lambda 表达式时,H
它已被绑定,因此不再是变量({}/1
不需要使用构造)。
请注意,这里有几个细节超出了 lambda 库本身的范围:(1) 编译器是否在编译时识别出您正在调用带有 lambda 表达式参数的元谓词?(2) 如何解释顶级查询?完整的查询是首先完全编译还是元解释?这些细节取决于系统本身。
推荐阅读
- numpy - 使用自定义数据集进行逻辑回归
- r - 模拟分位数回归中给定 tau = 0.5 和 X 值的响应变量 y
- mfc - MkParseDisplayName 返回无效语法
- c# - 红隼定制
- javascript - 在命名组中获取多个结果
- swift - 在关联类型对象上使用 KeyPaths
- javascript - 在此示例中,如何将数组对象与正则表达式匹配?
- azure-web-app-service - 无法使用 MSI 实现对 azure 存储容器 (blob) 的 azure Web 应用服务访问
- mininet - Iperf 客户端在使用 TCLinks 的 Mininet 中报告吞吐量过高
- android - 如何通过将键设置为字符串来使用recyclerview-selection?