Создание двунаправленного правила в CHR и CLP / FD

В качестве примера. Предположим, что все, что красное, имеет значение 5. Я пишу следующее:

:- 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) правильно производит логический вывод hasColor(moose, red), hasValue(moose, 5).

Однако я бы хотел, чтобы вывод работал и в обратном направлении; чтобы указать, что если что-то имеет значение 5, оно должно быть красным. В данный момент,hasValue(moose, 5)принимается как ограничение, но не дает никаких выводов. Но добавив правило:

hasValue(Thing, 5) ==> hasColor(Thing, red).

вызывает любое обращение к hasValue(moose, 5) для полной блокировки и переполнения стека, по-видимому, вызывая бесконечный цикл, хотя ==> утверждает, что правило "вызывает свое тело ровно один раз".

Я понимаю, что я не заявлял, что вещь может иметь только один цвет или значение (я не уверен, как бы это сделать), но неоднократно добавлял ограничение, которое moose является red и имеет ценность 5 определенно не должен изменять набор ограничений.

Как я могу позволить системе правильно выполнять этот вывод в обоих направлениях?

1 ответ

Может что-то вроде:

:- 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).
Другие вопросы по тегам