Какие операторы и предикаты можно использовать с clp(fd)?

Во-первых, в документации clp(fd) упоминается:

В современных системах на Прологе арифметические ограничения включают и заменяют низкоуровневые предикаты над целыми числами. Основное преимущество арифметических ограничений состоит в том, что они являются истинными отношениями и могут использоваться во всех направлениях. Для большинства программ арифметические ограничения являются единственными предикатами, которые вам когда-либо понадобятся в этой библиотеке.

Во-вторых, в ранее заданном вопросе было упомянуто, что include/3 несовместим с clp(fd).

Означает ли это, что при написании пролога с помощью библиотеки clp(fd) можно использовать только операторы clp(fd) и предикаты clp(fd)?

Кроме того, например, почему include/3 несовместим с clp(fd)? Это потому, что не использует операторы clp(fd)? Чтобы использовать include/3 в коде clp(fd), нужно ли переписывать версию, в которой используются операторы и ограничения clp(fd)?

Вы видели Понимание кода CLP(FD) Prolog задачи N-ферзей, в частности утверждение в самом конце, those predicates generate constraints that are maintained internally ? Это должно дать вам еще некоторые необходимые знания.

Guy Coder 11.01.2023 14:25
Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
2
1
119
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Include/3 не обязательно должен быть несовместим с clpfd (или любым другим использованием атрибутивных переменных ) - зависит от безопасного (для целей программы, а не обязательно "логически чистого") использования атрибутивных переменных. Например.:

:- use_module(library(clpfd)).

test_include(F) :-
    L = [N1, N2, N3, N4],
    N1 #< 2,
    N2 #> 5,
    N3 #< 3,
    N4 #> 8,
    include(gt_3_fd, L, F).

gt_3_fd(I) :-
    I #> 3.

Результат в swi-прологе:

?- test_include(F).
F = [_A, _B],
_A in 6..sup,
_B in 9..sup.

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

Как только переменные являются непеременными/заземленными в зависимости от варианта использования (clpfd работает с целыми числами, а не, например, с составными терминами, поэтому непеременная достаточно хороша), тогда переменные также можно использовать вне clpfd. Пример:

?- I = 5,  I > 4, I @> 4, I #> 4.
I = 5.

Оператор , такой как >, использует фактическое значение переменной и игнорирует любые атрибуты, которые могли быть добавлены к переменной, например. клпфд.

Логическая чистота, например. добавление ограничений к элементам в списке L после include/3, а не перед ним, является отдельной проблемой и также относится к переменным без атрибутов.

Вкратце: программа может использовать некоторые целые числа с clpfd и некоторые целые числа вне clpfd, т. е. смесь. Это нормально, пока различие между внутренним и внешним применяется последовательно, пока оно актуально (поскольку, например, маркировка будет давать фактические значения).

Да я вижу. Если я правильно понимаю, я могу использовать любой предикат, если я непротиворечив в переменных и операторах, которые я использую с ними. Просто чтобы уточнить, скажем, я использую предикат из библиотеки p(X) :- X > 5., смогу ли я вызвать его из моего кода clp(fd) с помощью X in 1..5, p(X). или это не сработает, потому что предикат p не использует оператор сравнения #>?

nich 11.01.2023 02:44
X > 5 выдает ERROR: Arguments are not sufficiently instantiated, если X в этот момент имеет значение var - swi-prolog.org/pldoc/doc_for?object=var/1
brebs 11.01.2023 08:49

Как вы можете отличить приведенный выше случай от «незначительного» варианта, скажем, N4 #< 8, где вы получаете неправильный результат?

false 11.01.2023 10:52

@false Я бы обвинил программиста в том, что он не использует овеществление, если овеществление (например, tfilter вместо include, как вы упомянули) требуется в этот момент для правильной работы программы :-) Или, возможно, перепишите программу, чтобы использовать include после переменных были созданы экземпляры.

brebs 11.01.2023 11:58

В том то и смысл, что они несовместимы.

false 11.01.2023 14:07

@false Я думаю, наша разница в том, что меня интересует программа, которая работает (т.е. отвечает заявленным требованиям), тогда как вы продвигаете логически чистый стиль, который имеет свое применение, но для большинства вопросов о Прологе на этом сайте , является излишним и показал бы Пролог новичкам слишком сложным и медленным.

brebs 11.01.2023 14:32

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

false 11.01.2023 14:34

...так что это не имеет ничего общего с чистым стилем как таковым. Подумайте о (=\=)/2, который просто безопасен, но чрезвычайно ограничен.

false 11.01.2023 14:35

Когда мы говорим о «совместимости», мы всегда имеем в виду «совместимость в общем случае», мы никогда не имеем в виду «совместимость иногда» или «совместимость при благоприятных условиях». Таким образом, include/3 совместим с clpfd тогда и только тогда, когда он никогда не бывает с ним несовместим.

repeat 14.01.2023 10:39

На первый взгляд код, который вы представляете, кажется логичным. Но если заглянуть глубже, он развалится. Почему? Это зависит от внутренних деталей реализации используемой вами библиотеки clpfd. Учтите, что (#>)/2 может оставить после себя остаточные цели. В вашем надуманном примере нет, а вообще может!

repeat 14.01.2023 10:47

@repeat Заметьте, я не утверждаю, что include всегда безопасно использовать. Но говорить, что это всегда небезопасно, неправильно.

brebs 14.01.2023 11:36

Конечно, но OTOH тоже никто не говорит, что «это всегда небезопасно». Центральный вопрос: на какие свойства может положиться пользователь include/3? Таким образом, в данном контексте «небезопасный» означает не «никогда не безопасный», а «не всегда безопасный». Пользователь не может полагаться на include/3 безопасность с clpfd (не зная деталей внутренней реализации, которые, кстати, могут быть изменены), поэтому мы говорим: «(в целом) include/3 небезопасно использовать с clpfd».

repeat 14.01.2023 11:51
почему include/3 несовместим с clp(fd)?
?- X = 1, include(#\=(1),[0,X,2],Xs), X = 1.
   X = 1,
   Xs = [0,2].     % looks good
?-        include(#\=(1),[0,X,2],Xs), X = 1.
   false, unexpected.
?-        include(#\=(1),[0,X,2],Xs).   % generalization
   Xs = [0,X,2],
   X in inf..0/2..sup
;  unexpected. % missing second answer

Итак, (#\=)/2 работает в этом случае, только если он достаточно конкретизирован. Как вы можете быть уверены, что это так? Ну, нет прямого безопасного теста. И, таким образом, вы получите неправильные результаты в определенных случаях. Пока эти примеры помещаются в одну строку, довольно легко обнаружить ошибку. Но с большей программой это практически невозможно. Из-за этого ограничения и include/3 несовместимы.

Выходом из ситуации было бы создание ошибок инстанцирования в случаях с недостаточным инстанцированием, но в контексте clpfd это довольно сложно. Другие встроенные предикаты, такие как (=\=)/2, делают это, и их применимость ограничена.

?- X = 1, include(=\=(1),[0,X,2],Xs), X = 1.
   X = 1,
   Xs = [0,2].
?-        include(=\=(1),[0,X,2],Xs), X = 1.
   instantiation_error.    % much better than an incorrect answer

Безопасный вариант include/3 — это tfilter/3 из library(reif). Но прежде чем использовать его, я рекомендую вам прочитать это.

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