As an example. Suppose that everything which is red has value 5. I write the following:
:- use_module(library(chr)).
:- use_module(library(clpfd)).
:- chr_type color ---> red ; blue.
:- chr_constraint hasColor(?any, ?color).
:- chr_constraint hasValue(?any, ?int).
hasColor(Thing, red) <=> hasValue(Thing, X), X #= 5.
hasColor(Thing, blue) <=> hasValue(Thing, X), X #\= 5.
hasColor(moose, red)
correctly produces the inferenced output hasColor(moose, red), hasValue(moose, 5)
.
However, I would then like the inference to work the other way too; to specify that if something has value 5, it must be red. Currently, hasValue(moose, 5)
is accepted as a constraint but produces no inference. But adding the rule:
hasValue(Thing, 5) ==> hasColor(Thing, red).
causes any invocation of hasValue(moose, 5)
to lock up completely and stack overflow, apparently causing an infinite loop, even though ==>
states that the rule “calls its body exactly once”.
I appreciate that I have not stated that a Thing can have only one color or value (I am not sure how I would do this), but repeatedly adding the constraint that moose
is red
and has value 5
should surely not change the constraint set.
How can I enable the system to perform this inference correctly in both directions?