Prolog:如何删除谓词中的对称值
Prolog: How do I remove symmetrical values in predicates
我有一个关于删除对称值的问题
我的谓词。这些谓词在我的数据库中,我使用了
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)).
但是,这删除了我数据库中的所有谓词,我不知道如何
以防止这种情况。
如果有人能帮助我,我将不胜感激!
谢谢。
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)) ).
我有一个关于删除对称值的问题 我的谓词。这些谓词在我的数据库中,我使用了 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)).
但是,这删除了我数据库中的所有谓词,我不知道如何 以防止这种情况。
如果有人能帮助我,我将不胜感激!
谢谢。
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)) ).