具有递增组件的动态Prolog谓词

use*_*889 3 global-variables prolog swi-prolog prolog-assert

我有一个知识库,由一组规则组成,每个规则的头部在某些条件发生时执行复杂术语的断言或撤销.

我怎样才能确保Id每个都递增 assert(term(Id,A,B,C))

rep*_*eat 5

假设你不关心Id(在收回id_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)).

样本使用(适用于SWI-Prolog 8.0.0和SICStus Prolog 4.5.0):

?- id_person(I,P).
false.

?- assertz_person(joan), id_person(I,P).
I = 0, P = joan.

?- assertz_person(al), assertz_person(ian), id_person(I,P).
   I = 0, P = joan
;  I = 1, P = al
;  I = 2, P = ian.

  • 我认为你不需要`nextID(I),retract(nextID(I))`,我认为`retract(nextID(I))`就足够了. (3认同)

Pau*_*ura 5

当您断言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)).
Run Code Online (Sandbox Code Playgroud)

调用asserta/1将使最新的断言子句term/3成为第一个在被调用时被检索的子句,如上所述,所有参数都是未绑定的,从而提供对最后一次计数的访问.然而,该解决方案假定条款不是任意缩回的.