Mark Green
Mark Green

Reputation: 1330

Creating a bidirectional rule in CHR and CLP/FD

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?

Upvotes: 0

Views: 85

Answers (1)

user27815
user27815

Reputation: 4797

Maybe something like:

:- use_module(library(chr)).
:- chr_type color ---> red ; blue.

:- chr_constraint thing_color_value(?any, ?color, ?int).

thing_color_value(T,red,V) <=> var(V)|thing_color_value(T,red,5).
thing_color_value(T,C,5) <=> var(C)|thing_color_value(T,red,5).

Upvotes: 0

Related Questions