3

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

我怎样才能确保Id每增加一次 assert(term(Id,A,B,C))

4

2 回答 2

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)).

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

于 2019-01-29T00:06:52.320 回答
5

假设您不关心Id(在撤回id_person/2子句时发生)中的漏洞,您可以这样做:

:- 动态 nextID/1。
:- 动态 id_person/2。
下一个 ID(0)。

assertz_person(P) :-
   下一个 ID(I),
   收回(nextID(I)),
   I1 是 I+1,
   断言(nextID(I1)),
   断言(id_person(I,P))。

示例使用(适用于 SWI-Prolog 8.0.0 和 SICStus Prolog 4.5.0):

?- id_person(I,P)。
错误的。

?- assertz_person(joan), id_person(I,P)。
我 = 0,P = 琼。

?- assertz_person(al)、assertz_person(ian)、id_person(I,P)。
   我 = 0,P = 琼
; 我 = 1,P = 人
; I = 2,P = 伊恩。
于 2019-01-28T22:32:30.730 回答