Библиотека 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 в комментариях.

Другие вопросы по тегам