使用setarg/3
的SWI-prolog文档heavily recommend against:
此谓词可用于对项的破坏性分配,将它们用作逻辑外的存储仓。始终要尽量避免使用setarg / 3,因为许多Prolog系统不支持setarg / 3,并且必须非常小心地防止意外复制和意外复制术语。
我不确定我是否理解,setarg/3
的“额外逻辑”是什么?我知道,诸如cuts和findnsols之类的事情是多余的,因为它们依赖于Prolog使用的搜索顺序的隐式知识,改变术语的论点有什么不好呢?
答案 0 :(得分:6)
很容易看出,使用setarg/3
违反了谓词所期望的最基本的声明性属性。
例如,考虑查询:
?- T = f(a), T = f(b). false.
声明性地,我们希望添加约束(即 goal )最多可以减少,当然永远不会扩展解决方案集。对吧?
对吗?
好吧,考虑:
?- T = f(a), setarg(1, T, b), T = f(b). T = f(b).
因此,添加约束已对查询进行了概括:它以前失败了,现在成功了(无条件)。
在日常任务中,这类似于以下情况:
A:我想点一份甜点。
B:对不起,我们没有甜点了。
A:好的,那我想点甜点和咖啡。
B:您在这里:甜点和咖啡。
如果在真实的餐厅中进行对话,肯定会发现大多数人都非常不寻常。
因此,setarg/3
被称为不纯谓词:单调的一阶推理不能应用于它。