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
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?