Библиотека SWI Prolog Clpfd - Реификация
Я готовлюсь к экзамену по логике и изучаю некоторые прошлые статьи из моего курса. Я сталкивался с вопросом относительно овеществления и разместил это ниже;
Проиллюстрируйте reification, используя его для выражения свойства, что переменная B может принимать значение 1 или 8.
После прочтения некоторых ресурсов и просмотра руководства по SWI для Пролога, я по-прежнему нахожу концепцию reification довольно запутанной (в первую очередь, в изучении Java, поэтому переход к изучению Пролога был трудным). Это довольно смущает необходимость использовать логическую логику в запросе пролога.
Без этого я должен был бы написать следующий код (который, как я знаю, слишком длинный, чтобы быть правильным ответом);
B in 1..8, B #\= 2,B #\= 3,B #\= 4,B #\= 5,B #\= 6,B #\= 7.
Был бы очень признателен, если бы кто-то мог показать мне вышеупомянутый запрос, но с использованием reification.
3 ответа
Из документации:
Ограничения в /2, #=/2, #\=/2, #/2, #==/2 могут быть уточнены, что означает отражение их истинных значений в логические значения, представленные целыми числами 0 и 1. Пусть P и Q обозначают ограничения reifiable или логические переменные, тогда:
...
P #\/ Q True iff either P or Q
...
Для тебя это кажется P
является B #= 1
а также Q
является B #= 8
Итак, вы в конечном итоге:
?- B #= 1 #\/ B #= 8.
B in 1\/8.
Как видите, вы на самом деле не используете утвержденные значения. Вы просто используете reification как обходной способ объявления домена вашей переменной. Ответ на ваш запрос, B in 1 \/ 8
, это то, что вы, вероятно, использовали бы напрямую, если бы хотели сказать, что "B - это 1 или 8". Если вы внимательно посмотрите на документациюin/2
, вы должны увидеть, что домен может быть целым числом, диапазоном Lower .. Upper
или союз Domain1 \/ Domain2
, В вашем случае оба домена представляют собой одно целое число, 1 и 8.
PS: Как только вы идете по этой дороге, почему бы и нет
?- B in 1..8 #/\ #\ B in 2..7.
B in 1\/8.
B находится в [1,8], а B отсутствует в [2,7].
Возможности безграничны:)
Сначала попробуйте ваш запрос:
? - B в 1..8, B #\= 2,B #\= 3,B #\= 4,B #\= 5,B #\= 6,B #\= 7.Б в 1 \ / 8.
Это говорит о том, что ваш запрос эквивалентен единственной цели B in 1\/8
,
Из этого вы видите, что вам не нужно повторение, чтобы выразить, что конечная переменная домена равна 1 или 8.
Реификация позволяет вам подтвердить истинность значения ограничения. Например, вы можете сказать:
? - T #<==> B в 1\/8. Т в 0..1, B в 1\/8#<==>T.?- T #<==> B в 1\/8, B = 3. Т = 0, B = 3.
Из второго запроса вы видите, что если B = 3
, затем T = 0
потому что ограничение B in 1\/8
не в этом случае.
Изменение ограничения может быть полезно, если вы хотите рассуждать о самих ограничениях. Например, это позволяет вам выразить, что определенное количество элементов списка должно быть равно заданному целому числу. Я оставляю решение этого как более значимое упражнение, чтобы понять овеществление.
Первоначально я думал так же, как @Boris и @mat. Но после некоторого размышления над вопросом мне пришло другое возможное толкование задачи. Однако имейте в виду, что я не знаком с вашим материалом курса, так что это очень умозрительно. При этом, возможно, в описании задачи предлагается написать предикат, который оценивается как истинное, если указанное выше свойство имеет значение, или ложное в противном случае. Подобный предикат может быть определен как:
val_either_or_t(X,Y,Z,true) :-
( X#=Y ; X#=Z).
val_either_or_t(X,Y,Z,false) :-
X #\= Y,
X #\= Z.
Я признаю, что название немного неуклюже, но я не мог придумать лучшего. В любом случае, он выполняет свою работу в соответствии с интерпретацией задачи, которую я описал выше:
?- val_either_or_t(X,1,8,T).
T = true,
X = 1 ? ;
T = true,
X = 8 ? ;
T = false,
X in inf..0\/2..7\/9..sup
?- val_either_or_t(X,Y,Z,T).
T = true,
X = Y,
X in inf..sup ? ;
T = true,
X = Z,
X in inf..sup ? ;
T = false,
X#\=Z,
X#\=Y
Я пришел к этой идее, потому что в последнее время я играл с некоторыми предикатами, которые я нашел в Stackru, и мне пришло в голову, что задача может быть направлена в направлении, где описанное свойство может использоваться как условие с такими предикатами., Например, с if_/3, который я много использовал с (=)/3 в условии, но почему бы не использовать его с чем-то вроде val_either_or_t/4. Рассмотрим следующий минимальный пример:
a(condition_was_true).
b(condition_was_false).
somepredicate(X,Y) :-
if_(val_either_or_t(X,1,8),a(Y),b(Y)).
С соответствующим запросом:
?- somepredicate(X,Y).
X = 1,
Y = condition_was_true ? ;
X = 8,
Y = condition_was_true ? ;
Y = condition_was_false,
X in inf..0\/2..7\/9..sup
Этот пример, конечно, не имеет особого смысла и предназначен только для того, чтобы проиллюстрировать, как можно использовать приведение данного свойства. Также я использую атомы true
а также false
уточнять значения в отношении использования их с if_/3. Тем не менее, вы также можете использовать 1
а также 0
оценить истинность, как в примере с @ mat. Просто замените 4-й аргумент в определении val_either_or_t / 4 на 1
а также 0
соответственно. Кроме того, вы также можете найти изящество этой идеи, предложенной @repeat в комментариях.