所以
?- canCall(mary, Person).
工作并终止和
?- canFind(mary, Person).
也可以工作和终止。但不知何故
?- canCall(mary, Person), canFind(mary, Person).
不会终止。可能是什么原因?
答案 0 :(得分:5)
(你的意思是:查询单独终止,但有时它们的连接不会终止)
您在这里发现了Prolog终止属性的一个非常基本的方面。让我们看看以下纯 1 程序:
canFind(mary, john).
canCall(mary, bob).
canCall(A, B) :-
canCall(B, A).
?- canCall(mary, Person).
Person = bob
; ...
?- canFind(mary, Person).
Person = john.
一切都很好看!让我们检查一下这个代码,这样每个人都可以使用它。现在你的倒霉的同事试图:
?- canCall(mary, Person), canFind(mary, Person).
* LOOPS *
哦不,这循环!也许我只需要重新排列目标:
?- canFind(mary, Person), canCall(mary, Person).
* LOOPS *
再次!
当然,你不开心了。毕竟,你努力测试了这段代码。它终止了。还是做到了?
这是Prolog中最令人困惑的事情之一:我们在这里(至少)有两种不同的终止查询的概念。您测试的那个(有时)称为存在性终止。但是,我建议简单地称之为找到答案。你经历过的时候非常脆弱。
如果查询不仅找到答案,而且全部,并完成查询,那么这称为通用终止或只是终止。如果Prolog程序员说查询终止,则意味着它终止普遍。
那么我们如何观察全面终止呢?只需要求所有答案。在GNU-Prolog中,键入 a 。在其他系统中,你必须锤击 SPACE 或; 返回直到它完成,或者你疲惫的眼睛或你的腕管阻止它。
?- canCall(mary, Person).
Person = bob
; Person = bob
; Person = bob
; Person = bob
; Person = bob
; ...
所以在这里我们看到有无限多的答案(实际上,我们有限的人必须证明这一点,但暂时相信我。)
是否有更便宜的观察方式?没有所有这些答案文本的墙壁?您可以通过添加一个永远不会成立的条件来“关闭”答案, false
。
所以请改为:
?- canCall(mary, Person), false.
此类查询的结果可能是什么?它永远不会是true
。如果它终止,它只能是false
。因此,通过此查询,我们只需测试程序 的终止属性。
现在,两个(通用)终止查询的连接将始终终止。所以这种终止更加健壮。
通用终端还有很多很酷的特性。例如,您可以根据需要交换子句的顺序(即事实和规则):无论它们处于什么顺序,所有程序都共享完全相同的终止属性。
另一个原因是,您可以借助failure-slice轻松找到程序中的非终止来源。用this one开始阅读。
在面向命令的编程语言中,这个概念并不容易出现。但是,对于迭代器,你有非常相似的概念:如果迭代器产生第一个项目,那将对应于存在性终止,如果产生有限的许多项目,也就是说,如果在有限多个next
之后它完成了,那就会对应于通用终止。那种。
1实际上,在不纯的程序中,你有各种荒谬的行为。因此,考虑它们毫无意义。
答案 1 :(得分:0)
我猜,当您单独运行时,col = ss.GetActiveCol();
row = ss.GetActiveRow();
会统一为两个不同的值。检查一下。