David Tonhofer
David Tonhofer

Reputation: 15338

CHR in SWI Prolog: Rule guard containing "just removed" constraint does not return, blows stack

A little test code with no particular meaning:

:- use_module(library(chr)).
:- chr_constraint foo/1, bar/1, anyone/2.

foo(X) \ bar(Y) <=> anyone(X,Y).

anyone(_,Y) <=> bar(Y) | writef("bar(%w) exists\n",[Y]).
anyone(_,Y) <=> writef("bar(%w) does not exist\n",[Y]). 

If the above is consulted from the SWI Prolog command line and then run with:

?- foo(8),bar(10).

there is overflow after some time:

Could not reenable global-stack
Could not reenable global-stack
ERROR: Out of global-stack.
ERROR: No room for exception term.  Aborting.
Could not reenable global-stack
ERROR: Out of global-stack.
ERROR: No room for exception term.  Aborting.
ERROR: Execution Aborted
% Execution Aborted

However, if the code for the second rule is changed by moving the test for bar from the guard ot the head:

:- use_module(library(chr)).
:- chr_constraint foo/1, bar/1, anyone/2.

foo(X) \ bar(Y) <=> anyone(X,Y).

anyone(_,Y),bar(Y) <=> writef("bar(%w) exists\n",[Y]).  % changed!
anyone(_,Y) <=> writef("bar(%w) does not exist\n",[Y]).

then execution terminates:

?- foo(8),bar(10).
bar(10) does not exist
foo(8).

Is this an accident of the implementation? It does seem a bit dicey.

Furthermore, the above code was written because I wanted to test whether the constraint to be removed from the store (here, bar(Y)) would be available in the body of the rule. Apparently not, it is already gone when the rule body executes; but is this implementation dependent or a necessary or specified behaviour of CHR?

Upvotes: 0

Views: 112

Answers (0)

Related Questions