我有一個關于在謂詞中洗掉對稱值的問題。這些謂詞在我的資料庫中,我使用 assertz 將它們添加到那里。
所以我有:
foo(a,b).
foo(b,a).
foo(c,d).
foo(e,f).
foo(f,e).
我正在嘗試洗掉
foo(b,a).
foo(f,e).
我試圖制定這個規則:
remove :- foo(A,B),foo(B,A),retract(foo(B,A)).
但是,這會洗掉我資料庫中的所有謂詞,我不知道如何防止這種情況發生。
如果有人能幫助我,我將不勝感激!
謝謝你。
uj5u.com熱心網友回復:
Retract/1有兩種不同的語意:
- 立即更新視圖:回溯時,無法再看到收回的子句(它們立即變得不可見)。
- 邏輯更新視圖:回溯時,仍然可以看到撤回的子句(它們僅在下一個謂詞呼叫中變得不可見)。此更新視圖是 ISO 標準。
例如,在邏輯更新視圖中,當謂詞remove/1被呼叫時:
- 首先它看到
foo(a,b)并且foo(b,a)因此它縮回foo(b,a)。 - 隨后,在回溯,它認為
foo(b,a)和foo(a,b),因此它也縮回foo(a,b)。
為了解決這個問題,您可以使用 ISO 內置謂詞once/1(防止回溯)。
:- dynamic foo/2.
foo(a,b).
foo(b,a).
foo(c,d).
foo(e,f).
foo(f,e).
remove :-
once( ( foo(A, B),
foo(B, A),
retract(foo(B, A)) ) ).
要僅收回一個對稱事實,您可以問:
?- listing(foo), remove, listing(foo).
:- dynamic foo/2.
foo(a, b).
foo(b, a). % <== only this fact is retracted!
foo(c, d).
foo(e, f).
foo(f, e).
:- dynamic foo/2.
foo(a, b).
foo(c, d).
foo(e, f).
foo(f, e).
true.
要收回所有對稱事實,您可以定義:
remove_all_sym :-
( remove
-> remove_all_sym
; true ).
例子:
?- listing(foo), remove_all_sym, listing(foo).
:- dynamic foo/2.
foo(a, b).
foo(b, a). % <== this fact is retracted!
foo(c, d).
foo(e, f).
foo(f, e). % <== this fact is retracted!
:- dynamic foo/2.
foo(a, b).
foo(c, d).
foo(e, f).
注意更好的選擇是避免將對稱事實插入資料庫:
assert_foo(A, B) :-
( foo(B, A)
-> true
; assertz(foo(A, B)) ).
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/380082.html
