Вызов правила в прологе


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

    move(X,Y):-
      X is X+1,
      Y is Y-2.
    move(X,Y):-
      X is X+2,
      Y is Y-1.

В консоли я посылаю move (2,2) например и надеюсь, что возвращает 3,0 и 4,1, но возвращает false.

2 2

2 ответа:

Вам нужно использовать новые переменные и добавлять новые параметры, такие как:

move(X, Y, New_X, New_Y):-
      New_X is X+1,
      New_Y is Y-2.

Это потому, что при вызове move(2,2) x и Y создаются экземпляры со значением 2, и они не могут измениться, поэтому вы можете передать две новые неустановленные переменные, которые будут возвращены в виде экземпляров.

Например, теперь, если вы вызовете: move(2,2,X,Y)
X, Y будет создан экземпляр (когда предикат возвратит / преуспеет), и предикат вернет вам правильные значения в X, Y .

В дополнение к ответу, предоставленному @coder (+s (0)), я бы предложил использовать библиотеку(clpfd), парное представление для координат и имя, которое отражает, какой аргумент является чем, например, from_to/2. Тогда ваш предикат может выглядеть примерно так:

:- use_module(library(clpfd)).

from_to(X-Y,X1-Y1):-
   X1 #= X+1,
   Y1 #= Y-2.
from_to(X-Y,X1-Y1):-
   X1 #= X+2,
   Y1 #= Y-1.

Использование clpfd позволяет использовать предикат в обоих направлениях, например: я нахожусь в позиции 3-4, куда я могу переместиться?

   ?- from_to(3-4,T).
T = 4-2 ? ;
T = 5-3

Или: я на позиции 3-4, откуда я мог прийти откуда?

   ?- from_to(F,3-4).
F = 2-6 ? ;
F = 1-5

Последний случай не работает, если вы определяете свой предикат с помощью is/2, так как в этом случае ожидается, что выражение с правой стороны будет создано:

   ?- X is 3+4.
X = 7
   ?- 7 is X+4.
     ERROR!!
     INSTANTIATION ERROR- in arithmetic: expected bound value
   ?- 7 is 3+X.
     ERROR!!
     INSTANTIATION ERROR- in arithmetic: expected bound value