2016-01-13 2 views
4

Мне нужно знать, создается ли переменная в заданном правиле, но мне не разрешено использовать var (X) и не имеют понятия о том, как это сделать.
В частности, мое правило получает 4 параметра (P, A, B, C).
Если создаются экземпляры P, A, B, C, то мое правило должно «возвращать» истинное iff (A + B) mod (P) = C (mod (P)).
Если один из A B и C не является isntantiated, я должен вернуть, какое значение это гарантирует, что (A + B) mod (P) = C (mod (P)). так, например, если C не создается, правило должно «возвращать» (A + B) mod (P) в виде C и аналогичное поведение, если A или B не создаются. Написание каждого правила легко, но как я могу узнать, в каком из случаев я нахожусь, если я не знаю, была ли создана переменная или нет? как уже упоминалось ранее, я не могу использовать var (X) или число (X) и т. д., я могу только предположить, что P всегда создается.
Заранее благодарим!Как проверить, создана ли переменная в Prolog?

+0

вам разрешают использовать 'номер (X)'? – BretC

+0

@BretC состояния OP, * ... Я не могу использовать 'var (X)' или 'number (X)' и т. Д. * – lurker

ответ

4

Тестирование вручную, независимо от того, было ли оно создано, очень сложно правильно обрабатывать все случаи, которые могут возникнуть на практике. Почти всегда ваш результирующий код будет вести себя некорректно для определенных шаблонов создания, о которых вы не думали.

К счастью, существует такое декларативное решение для таких проблем: Ограничения работают правильно во всех случаях, независимо от того, что создается, а что нет.

Например, используйте CLP (FD) ограничения вашей системы Пролога, чтобы решить вашу задачу:

:- use_module(library(clpfd)). 

same_sum_mod(A, B, C, P) :- 
    (A+B) mod P #= C mod P. 

Он правильно работает во всех направлениях, например:

?- same_sum_mod(1, 2, 3, 3). 
true. 

?- same_sum_mod(1, B, 3, 2). 
1+B#=_G823, 
_G823 mod 2#=1. 

?- same_sum_mod(1, 2, 3, P). 
P in inf..-1\/1..sup, 
3 mod P#=_G855, 
3 mod P#=_G855. 

А также проверить в следующем случае, когда B изначально не, но его домен известен, а con straint решатель может вывести единственное допустимое решение:

 
?- B in 0..1, same_sum_mod(1, B, 3, 2). 
B = 0. 

Таких случаи не могут быть обработаны с помощью простых проверок инстанцирования, но требует рассуждений о ограничениях.

См. для получения дополнительной информации о ограничениях CLP (FD).

4

Я думаю, что ответ @mat - это, безусловно, способ решить вашу проблему.

Однако, если вы хотите, чтобы проверить, является ли переменный не экземпляр без использования встроенного предиката вара/1, который делает именно то, что (из-за некоторые ограничения, например, ваш учитель явно запретил), вы можете использовать двойное отрицание дважды тест на способность связана с переменной без действительно инстанцировании его, если он не связан: случаи

not_inst(Var):- 
    \+(\+(Var=0)), 
    \+(\+(Var=1)). 

тестов:

?- not_inst(X). 
true. 
?- not_inst(a). 
false. 
+0

Правильный способ сделать это с помощью 'var/1' и' nonvar/1'. Я думаю, вы должны упомянуть, что в случае, если кто-то завершает этот ответ через Google и не перестает читать OP, заявив, что им запрещено использовать эти предикаты. –

+1

@ DanielLyons: добавлены некоторые комментарии, выделенные жирным шрифтом на всякий случай. Может быть, я должен полностью удалить ответ? – gusbro

+0

Нет, мне это нравится. Пожалуйста, держи! –

Смежные вопросы