Здесь есть несколько проблем, давайте начнем с самого очевидного:
Проблемы моделирования
У вас есть отношение (result/2
, возможно, не лучшее название), и предполагается, что это отношение моделируется, когда decline
и когда offer
должны быть истинными. Прежде чем читать вашу программу, я предпочитаю спросить Пролог:
?- result(X, decline), result(X, offer).
X in 11..20 ;
false.
Таким образом, для значений от 11 до 20 ваше отношение неоднозначно. Если вы хотите принять решение, сначала исправьте это отношение. Собственно, я бы начал с
- лучшее название для отношения, которое проясняет, что это отношение
- без повелительного словоблудия (например,
Input
или императивы)
- более компактная формулировка, вам не нужно столько
(=)/2
целей в вашей программе. Вместо этого вы можете написать это так:
heigth_decision(I, decline) :-
I #< 10.
Ответы и успех против решений в CLP
И есть еще одна проблема, более фундаментальная. На самом деле это гораздо серьезнее, поскольку все приведенные до сих пор SO-ответы полностью игнорируют этот аспект. Это понятие ответов и успеха и, с другой стороны, понятие решений.
Когда вы задаете запрос на Прологе, вы получаете ответ. Такой ответ может содержать решения, например ответ L = [_,_]
, который содержит бесконечно много решений. Или ответ может содержать ровно одно решение, например Decision = decline
. Но если вы используете ограничения вроде library(clpfd)
, между ними гораздо больше.
Теперь вы можете получить конечное количество решений:
?- abs(X) #< 3.
X in -2..2.
Или бесконечно много:
?- X #> Y.
Y#=<X+ -1.
Но вы также можете получить ровно одно решение, которое не похоже на одно:
?- 2^X #= 1.
2^X#=1.
Итак, просто повторим это: у нас есть ровно одно решение в целых числах, но для Пролога это слишком сложно. Мы получили ответ, который гласил: Да, это все правда, при условии, что весь этот мелкий шрифт верен.
Хуже того, иногда мы получаем ответы, в которых нет решения.
?- X^X#=0.
X^X#=0.
Если бы Пролог был достаточно умным, он бы ответил false
. Но он не всегда может быть таким умным просто потому, что вы можете легко формулировать неразрешимые проблемы. Такой ответ иногда называют несоответствием. Немецкое понятие Scheinlösung (~ поддельное решение, но с менее негативным подтекстом) передает идею немного лучше.
Таким образом, ответ может содержать решения, но некоторые ответы вообще не содержат решений. По этой причине успех цели не может считаться существованием решения! То есть все SO-ответы, предлагающие какую-то фиксацию как (;) / 2 if-then-else, once / 1 или! / 0, неверны, если они принимают успех как решение. Чтобы убедиться в этом, попробуйте их:
?- X^X#=0, result(X,decline).
X in 11..sup,
X^X#=0 ;
false.
?- X^X#=0, result(X,offer).
X in 0..20,
X^X#=0.
Так как же теперь можно быть в чем-то уверенным?
Вы можете рассчитывать на провал гола.
Вы можете попробовать labeling/2
, но это работает только на конечных доменах.
Вы можете использовать call_residue_vars/2
и copy_term/3
, чтобы определить, есть ли ограничения, "торчащие"
К сожалению, вы не можете полностью полагаться на верхний уровень SWI, который скрывает ограничения, не связанные с переменными в ответе. Только SICStus отображает их правильно.
person
false
schedule
23.11.2012
Input=15
, то вторая цель больше не должна рассматриваться, что означает, что все возможные ответы должны быть просто[decline]
, верно? - person Fred Foo   schedule 22.11.2012Result=decline
, еслиInput in 11..sup
иResult=offer
, еслиInput in 0..10
- person ri5b6   schedule 22.11.2012