[英]Prolog clause terminates individually, but not together
所以
?- canCall(mary, Person).
工作並終止,
?- canFind(mary, Person).
也可以工作並終止。 但是不知何故
?- canCall(mary, Person), canFind(mary, Person).
不終止。 可能是什么原因?
(您實際上的意思是: 查詢會個別終止,但有時它們的連詞不會終止)
您在這里發現了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中鍵入 。 在其他系統中,您將不得不敲擊SPACE或; 返回直到完成,或者疲勞的眼睛或腕管將其阻止。
?- canCall(mary, Person).
Person = bob
; Person = bob
; Person = bob
; Person = bob
; Person = bob
; ...
因此,在這里我們看到有無限多個答案(實際上,我們有限的生物必須證明這一點,但暫時要相信我)。
有沒有便宜的方法可以觀察到這一點? 沒有答案的牆嗎? 您可以通過添加永遠不會成立的條件“ false
”來“關閉”答案。
因此,請問:
?- canCall(mary, Person), false.
這樣查詢的結果是什么? 永遠不可能是true
。 如果終止,則只能為false
。 因此,與此查詢我們簡單地只測試程序的終止性質。
現在,兩個(通用)終止查詢的結合將始終終止。 因此,這種終止更加健壯。
通用終端還有許多其他很酷的特性。 例如,您可以根據需要交換子句的順序(即事實和規則):不管子句的順序如何,所有程序都共享完全相同的終止屬性。
另一個是,您可以借助故障切片輕松地在程序中找到不終止的來源。 開始閱讀這一本 。
在面向命令的編程語言中,這個概念並不容易出現。 但是,對於迭代器,您有非常相似的概念:如果迭代器產生第一個項目,則該項目對應於存在終止;如果產生了有限的多個項目,即,如果在有限的多個next
完成后,則該變量對應於通用終止。 的種類。
1實際上,在不純正的程序中,您有各種各樣的荒謬行為。 因此,考慮它們是沒有意義的。
我猜,當您單獨運行時, Person
統一為兩個不同的值。 檢查一下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.