0

An infinite loop is generated when the inferential motor is activated to make the necessary inferences.

The rules and facts have been defined according to a specific syntax for the meta-interpreter I am using.

The rule is a quintuple in which the second field is the consequence of the rule while the third field are the conditions for activating a rule.

The cycle is caused by the updating of the id (I1) through the term nextID, which I used to make sure that each assert the id is incremented This is my knowledge base:

Rules:

rule(1,[gn(Name,Surname,I1),retract(nextID(I)),nextID(I1)],
and([person(Name,Surname),nextID(I),call_p(I1 is I+1),Name=='john']),1,1).

Facts:

fact(1,nextID(0),1).
fact(2,person(john,black),1).

How should I modify the rule in such a way that the infinite loop is not created?

false
  • 10,264
  • 13
  • 101
  • 209
  • no it's not syntax error – user3062889 Jan 29 '19 at 16:59
  • 2
    `nextID (0)` is invalid syntax. It should be `nextID(0)`. It's the same with all other compound terms (except for `Name == 'john'`). – repeat Jan 29 '19 at 17:08
  • You can't have a space between the functor and the left parenthesis when writing a compound term in Prolog. So, for example, you want, `fact(1, nextID(0), 1).` not `fact (1, nextID (0), 1).` But since you've evidently run this code and encountered a loop, I suppose how you've entered it here isn't how it is in reality. – lurker Jan 29 '19 at 17:09
  • the spaces are derived from the copy and paste but I assure you that in the code there are not. – user3062889 Jan 29 '19 at 17:10
  • and then the spaces would have returned syntax error while in my case the syntax is correct but the problem is in execution – user3062889 Jan 29 '19 at 17:11
  • the spaces were generated for entering the question on google translate. `call_p` is a command of meta-interpreter that makes comparisons and assignments between numerical variables – user3062889 Jan 29 '19 at 17:19
  • https://stackoverflow.com/help/how-to-ask – false Jan 29 '19 at 17:24

1 Answers1

0

From your description of the rule fields, I would expect a different formulation for that rule:

rule(
    1,
    [retract(nextID(I)), call_p(I1 is I+1), assertz(nextID(I1), gn(Name,Surname,I1)], 
    and([person(Name,Surname), Name == 'john']),
    1,
    1
).

This would be equivalent to:

IF
    person(Name,Surname), Name == 'john'
THEN
    retract(nextID(I)), call_p(I1 is I+1),
    assertz(nextID(I1), gn(Name,Surname,I1)

But it's hard to tell exactly without knowing the details of your rule engine.

Update

Given the formulation of facts, notably fact(1,nextID(0),1), I wouldn't expect, however, that the embedded calls to retract/1 and assertz/1 would work. Isn't call_p/1 the escape mechanism to call Prolog goals from rules?

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • the effect of the execution is that it continually creates new nextIDs so the rule is always invoked. I would like the loop to stop after the `gn` assert and the `nextID` update – user3062889 Jan 29 '19 at 17:26
  • Wouldn't that be the case with the alternative rule formulation that I suggest in my answer? – Paulo Moura Jan 29 '19 at 17:32
  • the second field of the rule is used only for `assert` and `retract`, to perform the assert it is sufficient to insert the fact to assert without specifying the command `assert`, while for `retract` it is necessary to specify it. `call_p (I1 is I + 1)` is to be placed in the third field of the rule otherwise `call_p` is considered a compound term. – user3062889 Jan 29 '19 at 17:45
  • Is it possible to use `retractall` instead of `retract`? – Paulo Moura Jan 29 '19 at 18:28