I upgraded a project from VIP 7.5 to VIP 9 then VIP 10.
Some code written for VIP 7.5 leads in the new versions to an infinite loop: the following example illustrates this behavior.
Code: Select all
class facts
style_blue : integer := 13.
token : (unsigned Id, string T, integer Z) nondeterm.
clauses
token(1, "niveau", 3).
token(2, "n°", 10).
token(3, "8", 14).
token(4, "5", 0).
class predicates
p1 : ().
p10 : (string T) determ.
p100 : (unsigned Id, integer S).
clauses
% updates the token facts
p1() :-
L = [ Id || token(Id, _, _) ],
Len = list::length(L),
I = fromTo(1, convert(unsigned, Len)),
token(I, T, _),
if p10(T) then
p100(I, style_blue)
end if,
fail().
p1().
% no update condition
p10(T) :-
hasDecimalDigits(T),
!.
% updates the fact
p100(Id, Z) :-
retract(token(Id, T, _)),
!,
assert(token(Id, T, Z)).
p100(_, _).
VIP 7.5 : when a fact is asserted, the fail() predicate backtracks a second time to the same fact which has been put at the bottom of the stack of the facts by the assert() predicate. At the next step, the fail() predicate backtracks to the fromTo() predicate and increments the value of the variable "I".
VIP 9 -10 : when a fact is asserted and then put to the bottom of the stack, the fail() predicate always backtracks to the same fact and the value of the "I" variable does not change anymore. It is easy to get around to this trouble : the first part of p1() collecting the fact's Id variables to update, the second part updating them.
It is as if, In the first case, the system "knows" that it reached the bottom of the fact's stack, and then can go to the next step. In the second case, it does not.
I'm curious to know why this modification, and what is the right behavior ?