Как динамически переписать ограничения CLP(FD), чтобы помочь reification
Мой вопрос связан с этой (теперь 1-летней) публикацией, касающейся вопросов реификации в программе CLP(FD): ссылка
Файл пролога, который я передаю движку SWI, программно записывается на лету, основываясь на некоторых данных, которые пользователи могут добавлять / редактировать / удалять с помощью другого приложения (то же самое, которое впоследствии вызывает движок).
Я хочу обнаружить некоторые особые случаи, чтобы динамически переписать ограничения, чтобы помочь "движку" найти наименьшие возможные домены. Пример:
constr(X,Y,Z) :-
X in {1,2,3,4,5,6,7},
Y in {3,5,7},
Z in {1,2},
((X #= 3)) #==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)),
((Z #= 1)) #<==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)).
Если я позвоню constr(3,Y,Z).
, Я получил Z #= 1
или же Z #= 2
,
Одним из решений является автоматическая замена двух последних строк на
((X #= 3)) #==> T,
((Z #= 1)) #<==> T,
T #<==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)).
С этим я получаю Z #= 1.
Беда в том, что я могу иметь это:
((X #= 3)) #==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)),
((Z #= 1)) #<==> ((Y mod 7 #= 0) #\/ (Y mod 3 #= 0)).
Как это обнаружить? Может ли двигатель Prolog помочь мне сделать это? Я думал, что могу программно заменить каждый правый операнд переменной reification:
((X #= 3)) #==> J,
((Z #= 1)) #<==> K,
J #<==> ((Y mod 3 #= 0) #\/ (Y mod 7 #= 0)),
K #<==> ((Y mod 7 #= 0) #\/ (Y mod 3 #= 0)).
Но в этом случае возникает та же проблема "овеществления".
Спасибо за вашу помощь.