Fri 05 Nov 2010 02:51:04 AM UTC, original submission:
While porting an interpreter for our JStar programming language from GNU Prolog to GnuPrologJava, I noticed several strange behaviours related to not finding previously asserted clauses.
In essence, one can do assertz(foo(Term)), but then later foo(Var) does not pick up Term. Simple examples work okay, but once abolish or retract are used, they stop working.
The attached speed.pl file illustrates the bug.
The initialization of setup(2), creates two tuples: strictBefore(0,1) and strictBefore(1,2). So the complete_transitive_closure predicate should add strictBefore(0,2) and then stop. But on the second time around it fails to find strictBefore(0,2), so keeps on adding it an infinite number of times until some stack overflows.
[the 'added assertz' lines are from a Java print statement
that I added to Predicate_assertz, and count=N shows the size
of the 'clauses' list for that predicate].
------------- example output from bug_abolish.pl ---------
loading source file: speed
added assertz clause: strictBefore(1,2) :- true count=1
added assertz clause: strictBefore(0,1) :- true count=2
added assertz clause: transitive_closure_continue(maybe) :- true count=1
added assertz clause: strictBefore(0,2) :- true count=3
added assertz clause: transitive_closure_continue(yes) :- true count=2
added assertz clause: transitive_closure_continue(maybe) :- true count=1
added assertz clause: strictBefore(0,2) :- true count=4
added assertz clause: transitive_closure_continue(yes) :- true count=2
added assertz clause: transitive_closure_continue(maybe) :- true count=1
added assertz clause: strictBefore(0,2) :- true count=5
added assertz clause: transitive_closure_continue(yes) :- true count=2
added assertz clause: transitive_closure_continue(maybe) :- true count=1
added assertz clause: strictBefore(0,2) :- true count=6
...
---------------------------------------------------------
Interestingly, the slightly simpler bug_okay.pl works correctly, even though it is performing exactly the same operations on the strictBefore predicate. So I conjecture that the abolish of the other predicate is somehow related to the bug.
----------- output from bug_okay.pl ------------------
loading source file: bug_okay
added assertz clause: strictBefore(1,2) :- true count=1
added assertz clause: strictBefore(0,1) :- true count=2
added assertz clause: strictBefore(0,2) :- true count=3
stopping with status 1
If I change from abolish to retract, the bug is still there.
(See bug_retract.pl).
This is a show stopper bug for the kinds of programs we're trying to get working in gnuprologjava. I'm really keen to see it fixed, because gnuprologjava offers a nice integration of Prolog and Java, which would be ideal for our purposes.
Thanks
Mark Utting
Waikato University.
|