ArthurJ
ArthurJ

Reputation: 11

using arithmetic operations in Prolog

I have the following code:

position(0,0).
move(f):-
    position(X,Y),
    number(X),
    number(Y),
    Y is Y+1,
    X is X+1.

but when i call move(f) it returns false. number(X) and number(Y) returns true but whem i add the other two lines the function doesn't work. what's the problem?

Upvotes: 1

Views: 635

Answers (1)

Shon
Shon

Reputation: 4098

Elaborating on some of the comments your question has received, variables in Prolog stand for a possible instantiation of a single value, just like variables in mathematics and mathematical logic, and once they are instantiated within a context they must remain consistent. If we're dealing with a formula 0 = (a + b) - (a + b), we know that it can only express its intended sense if any value assigned to the first a is also assigned to the second. That is, we can substitute any value for a, but it must be the same value throughout. Prolog works with variables in this same way. If x = x + 1, then 2 = 3; but then math would be broken.

Addressing mat's caution against using dynamic predicates, here is a possible way of handling moves, but accomplished by passing around a list of previous moves. With this method, the most recent move will always be the first element of List in the compound term moves(List).

Supposing the current history of moves is as follows:

moves([position(0,0), position(0,1), position(1,1)]).

move/3 takes a direction, a complex term representing the previous moves, and tells us what the updated list of moves is.

move(Direction, moves([From|Ms]), moves([To,From|Ms])) :-
    move_in_direction(Direction,From,To).

move_in_direction/3 takes a direction, and a position, and tells us what the next position in that direction is:

move_in_direction(left,  position(X1,Y1), position(X2,Y1)) :- X2 is X1 - 1.
move_in_direction(right, position(X1,Y1), position(X2,Y1)) :- X2 is X1 + 1.
move_in_direction(up,    position(X1,Y1), position(X1,Y2)) :- Y2 is Y1 + 1.
move_in_direction(down,  position(X1,Y1), position(X1,Y2)) :- Y2 is Y1 - 1.

Notice that, using this method, you get a back-trackable history of moves for free. I'd imagine you could use this in interesting ways -- e.g. having the player explore possible series of moves until a certain condition is met, at which point it commits or backtracks. I'd be interested to know what kind of solution you end up going with.

Upvotes: 1

Related Questions