Создание двунаправленного правила в 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).