Получить Prolog, чтобы дать все возможности для арифметики

Мне было интересно, можно ли в прологе заставить его переборщить все возможные вычисления для чего-то вроде этого:

6 is Z + Q

Z = 1 Q = 5
Z = 2 Q = 4
Z = 3 Q = 3

person user3667111    schedule 22.11.2016    source источник


Ответы (2)


Подход «генерируй и тестируй» также работает. Конечно, вам все еще нужны некоторые ограничения, например:

?- between(1, 6, X), % X is an integer between 1 and 6
   between(1, 6, Y), % Y is an integer between 1 and 6
   X =< Y,           % X is not larger than Y
   X + Y =:= 6.      % the sum is 6
X = 1, Y = 5 ;
X = 2, Y = 4 ;
X = Y, Y = 3 ;
false.

Порядок подзапросов имеет значение, так что вы могли бы также назвать его «сгенерировать-затем-тестировать». Если вы не боитесь жестко закодировать некоторые ограничения, могут быть способы избежать генерации некоторых значений и сделать некоторые тесты ненужными, например:

?- between(1, 6, X), % X is an integer between 1 and 6
   between(X, 6, Y), % Y is an integer between X and 6
   X + Y =:= 6.      % the sum is 6
X = 1, Y = 5 ;
X = 2, Y = 4 ;
X = Y, Y = 3 ;
false.

Вы должны понимать, что пойти по этому пути достаточно далеко — это примерно то же самое, что реализовать решатель ограничений, такой как, например, CLP (FD).

person Community    schedule 23.11.2016

Я предлагаю использовать, если ваш Пролог поддерживает его, решатель конечной области.

Я обычно использую GProlog, и я могу получить то, что вы просите, с помощью чего-то вроде

fd_domain([A, B], 1, 100),
6 #= A + B,
fd_labeling([A, B]),

где fd_domain/3 задает домен для переменных A и B (от 1 до 100), 6 #= A + B задает ограничение (A + B равно 6) и fd_labelling/1 получает все возможные вычисления.

В Swi-Prolog немного иначе.

Прежде всего, вы должны загрузить библиотеку CLP(FD) с помощью

:- use_module(library(clpfd)).

Чтобы установить переменные и домен, вы можете написать

Vars = [A, B],
Vars ins 1..100,

Установка ограничения равна

6 #= A + B,

и чтобы получить все возможные комбинации, вы можете написать

label(Vars),
person max66    schedule 23.11.2016