具有递增组件的动态Prolog谓词
我有一个由一组规则组成的知识库,当某些情况发生时,每个规则的头部执行复杂术语的断言或收回 如何确保具有递增组件的动态Prolog谓词,prolog,global-variables,swi-prolog,prolog-assert,Prolog,Global Variables,Swi Prolog,Prolog Assert,我有一个由一组规则组成的知识库,当某些情况发生时,每个规则的头部执行复杂术语的断言或收回 如何确保Id随时间递增 assert(术语(Id,A,B,C))?假设您不关心Id中的孔(在收回Id\u person/2子句时发生),您可以执行以下操作: :- dynamic nextID/1. :- dynamic id_person/2. nextID(0). assertz_person(P) :- nextID(I), retract(nextID(I)), I1 is I+
Id
随时间递增
assert(术语(Id,A,B,C))
?假设您不关心Id
中的孔(在收回Id\u person/2
子句时发生),您可以执行以下操作:
:- dynamic nextID/1.
:- dynamic id_person/2.
nextID(0).
assertz_person(P) :-
nextID(I),
retract(nextID(I)),
I1 is I+1,
assertz(nextID(I1)),
assertz(id_person(I,P)).
:-动态nextID/1。
:-动态id_person/2。
nextID(0)。
资产管理人(P):-
nextID(I),
收回(下一个(I)),
I1是I+1,
assertz(nextID(I1)),
资产(个人(I,P))。
示例使用(与SWI Prolog 8.0.0和SICStus Prolog 4.5.0配合使用):
?身份证持有人(I,P)。
错。
-资产人(joan),身份人(I,P)。
I=0,P=joan。
-资产人(al)、资产人(ian)、身份人(I、P)。
I=0,P=joan
; I=1,P=al
; I=2,P=ian。
当您为
term/3
谓词断言子句时,其中第一个参数是唯一(整数)标识符,因此不需要辅助动态谓词来表示当前计数器。您只需执行以下操作:
:- dynamic(term/3).
assert_term(A, B, C) :-
( term(Id, _, _, _) ->
NextId is Id + 1
; NextId is 1
),
asserta(term(NextId, A, B, C)).
调用
asserta/1
将使term/3
的最新断言子句在调用时成为第一个被检索的子句,如上所述,所有参数都未绑定,从而提供对最后一次计数的访问。但是,此解决方案假设这些子句没有被任意收回。是的,我会依次收回。收回
呢?由此产生的“漏洞”应该如何处理?有趣的是:SWI Prolog@GuyCoder。(1) 我不认为“身份”标签有帮助。(2) “顺序”是多余的。“递增”指“+1”;不是“+2”;不是“+1.5”。@GuyCoder。不过,我确实认为你加上“顺序”有些好处。这是一个措辞上的问题。。。多个增量是按顺序进行的,但我认为不太可能出现误解。assert/1
是遗留的assertz/1
(或asserta/1
)是标准配置。另外,通过使用initialization/1
指令初始化当前\u id/1
谓词,可以避免if-then-else构造。@PauloMoura。正确的!旧习惯:)初始化指令(在本例中)比一个简单的事实好吗?(这是一个额外的概念。)我认为你不需要同时使用nextID(I)和retract(nextID(I))
,我认为retract(nextID(I))
就足够了。@DanielLyons。好主意。但是SICStus手册()让我有点不安,我明天会检查一下。谢谢如果nextID/1
是不确定的,这将是有问题的,但是如果没有线程,它应该只有一个解决方案。如果您有线程,那么无论如何您都会遇到其他问题(您需要一个关键部分或一个锁)。
:- dynamic(term/3).
assert_term(A, B, C) :-
( term(Id, _, _, _) ->
NextId is Id + 1
; NextId is 1
),
asserta(term(NextId, A, B, C)).