2016-01-13 77 views
4

我需要知道變量是否在給定的規則中被實例化,但我不被允許使用var(X),並且不知道如何去做。
具體來說,我的規則得到4個參數(P,A,B,C)。
如果P,A,B,C被實例化,那麼我的規則應該「返回」真如果(A + B)mod(P)= C(mod(P))。
如果A B和C中的一個沒有被賦值,我應該返回它的值,以保證(A + B)mod(P)= C(mod(P))。例如,如果C未被實例化,則規則應該「返回」(A + B)mod(P)爲C,並且如果A或B未被實例化則類似的行爲。編寫每條規則很容易,但是如果我不知道變量是否被實例化,我怎麼知道我處於哪種情況?如前所述,我不能使用var(X)或number(X)等等,我只能假設P總是被實例化。
在此先感謝!如何檢查變量是否在Prolog中實例化?

+0

您不允許使用'號(X)'? – BretC

+0

@BretC OP狀態,* ...我不能使用'var(X)'或'number(X)'等等。 – lurker

回答

4

手動測試是否實例化了某些東西,這使得很難正確處理實踐中可能出現的所有情況。幾乎總是,對於某些你沒有想過的實例化模式,你的結果代碼會表現不正確。

幸運的是,這樣的問題有一個聲明性的解決方案:約束在所有情況下都能正常工作,不管是什麼實例化,什麼都不是。

例如,使用您的Prolog系統的CLP(FD)的約束解決您的任務:

:- use_module(library(clpfd)). 

same_sum_mod(A, B, C, P) :- 
    (A+B) mod P #= C mod P. 

它正常工作在所有方向上,例如:

?- same_sum_mod(1, 2, 3, 3). 
true. 

?- same_sum_mod(1, B, 3, 2). 
1+B#=_G823, 
_G823 mod 2#=1. 

?- same_sum_mod(1, 2, 3, P). 
P in inf..-1\/1..sup, 
3 mod P#=_G855, 
3 mod P#=_G855. 

而且還要檢查出現以下情況,其中B最初是而非已實例化,但其已知,而con straint解算器可以推斷出單個允許解:

 
?- B in 0..1, same_sum_mod(1, B, 3, 2). 
B = 0. 

這種情況下不能用簡單的實例化的檢查處理,但是需要約約束推理。

有關CLP(FD)約束條件的更多信息,請參閱

4

我認爲@mat答案絕對是解決您的問題的方法。

不過,如果你想檢查一個變量是否不是實例不使用內置謂詞VAR/1,它正是這麼做的(由於一些限制,例如,你的老師明確禁止它),你可以用雙重否定兩次測試的能力,勢必沒有真正實例化它,如果它沒有綁定變量:

not_inst(Var):- 
    \+(\+(Var=0)), 
    \+(\+(Var=1)). 

測試用例:

?- not_inst(X). 
true. 
?- not_inst(a). 
false. 
+0

正確的方法是用'var/1'和' nonvar/1'。我認爲你應該提到,如果有人通過谷歌回答這個問題,並且不停地閱讀OP說他們被禁止使用這些謂詞。 –

+1

@DanielLyons:爲了以防萬一,以粗體添加了一些評論。也許我應該完全刪除答案? – gusbro

+0

不,我喜歡這個。請保留! –

相關問題