[英]How to query Rules in prolog?
我有以下代碼:
word(aa, a, a).
word(ab, a, b).
word(ac, a, c).
word(ad, a, d).
word(bb, b, b).
word(bc, b, c).
word(bd, b, d).
word(cc, c, c).
word(cd, c, d).
word(dd, d, d).
word(dc, d, c).
null(a).
crossword(A, B, C, D) :-
word(A, AC, AD),
word(B, BC, BD),
word(C, AC, BC),
word(D, AD, BD),
A \== B,
B \== C,
A \== C,
B \== D,
C \== D,
writeln(A-B-C-D),
null(b).
這是一個序言代碼,用於獲取填充2x2單詞表的所有可能方式,如下所示:
我想知道如何查詢此代碼以獲取所有答案。我不知道null(a)
和null(b)
是什么?
這是現有代碼的細分。
word(aa, a, a).
...
word(dd, d, c).
word(dc, d, c).
這些定義了word
事實,這些word
事實似乎列出了有效的“單詞”。 多余的第二個和第三個參數似乎是多余的,因為(a)它們很容易從第一個參數派生,並且(b)在所示程序中的任何地方都沒有使用(從摘錄中不清楚是否還有其他部分)程序)。 還不清楚為什么同時列出了cd
和dc
,但沒有為其他“單詞”給出這種對稱關系。
null(a).
這是一個事實,例如“ a
為null
”,但由於上下文有限,其語義尚不清楚。
crossword(A, B, C, D) :-
這是一個謂詞crossword/4
,它接受4個參數。 產生這些爭論的原因尚不清楚(見下文)。
word(A, AC, AD),
word(B, BC, BD),
word(C, AC, BC),
word(D, AD, BD),
上面的4行代碼收集了4個單詞事實。 在使用AC
, AD
等時,您會看到一種依賴關系,在這種依賴關系中,可以確保一對單詞跨過,而另一對單詞則是當您在黑板上向下讀相同的單詞時得到的。
A \== B,
B \== C,
A \== C,
B \== D,
C \== D,
上面的5行代碼確保了所收集的單詞事實之間存在一些差異。 同樣,語義還不清楚,因為它允許A
和D
成為相同的單詞(考慮到其他限制,在其他情況下可能無法實現)。 如果這些不等式測試中的任何一項失敗,則將回溯到上述word/3
查詢中,以收集至少一個不同的詞事實,並且Prolog將重試不等式檢查。
writeln(A-B-C-D),
這將寫出滿足以上所有不等式的當前“單詞”四邊形。
null(b).
這將測試(查詢) null(b)
事實,該事實將失敗,因為未將null(b)
建立為事實或可從null(X)
任何給定規則派生。 如果失敗,Prolog將再次回溯,一直到通過word/3
查詢收集另一組單詞事實。
當用完word/3
查詢的所有組合(其中的每個都提供了幾個單詞事實之一作為解決方案)后,在用writeln
顯示了所有可能性之后,整個crossword/4
謂詞將失敗並結束。 因此,當您發出查詢時, crossword(A, B, C, D).
,它會根據以上內容使用writeln
不斷迭代和顯示每個潛在的解決方案,直到不再存在解決方案並最終導致失敗(意味着不再有解決方案)。
正如我在評論中提到的那樣,這段代碼有點奇怪。 例如,將null(b)
用作無效事實會導致代碼通過回溯保持迭代。 可能最初的目的是在需要時將事實null(a)
更改為null(b)
以“關閉迭代”。 有點像“迭代標志”。 根據給定的信息不確定。
構造代碼的另一種方法是:
crossword(A, B, C, D) :-
word(A, AC, AD),
word(B, BC, BD),
word(C, AC, BC),
word(D, AD, BD),
A \== B,
A \== C,
B \== C,
B \== D,
C \== D.
當用crossword(A, B, C, D)
,Prolog會分別為您提供每個解決方案,直到找不到更多解決方案,或者您告訴它停止為止。 您可以使用setof
在列表中一次收集所有結果:
setof(A-B-C-D, crossword(A, B, C, D), Solutions).
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.