Fjodor
Fjodor

Reputation: 539

Prolog - functions? constants?

I am working in prolog and bumped into something I haven't really managed to grasp. To work without variables and with constant symbols and functions, for example:

test(a,T) :- /* change constant a, put result in T */
test(b,T) :- /* change constant b, put result in T */
test(f(X,Y),T) :- /* change function f and possibly the terms X and Y */

Is this doable? I don't really understand these non-variables way of putitng it and would be glad if someone could provide an insight, thanks in advance!

Upvotes: 1

Views: 901

Answers (2)

user1812457
user1812457

Reputation:

To add to the answer by @mat:

You don't really have constants vs. variables, as in traditional imperative languages. You have terms, and terms can be, as far as their binding is concerned:

  • terms which don't yet have a set value, also called unbound variables
  • terms that are fully bound, meaning they don't contain any elements that are still unbound, also called ground terms
  • or even partially bound terms

Few examples from the top-level:

?- X = Y.
X = Y.

Both X and Y are now the same unbound variable term.

?- 3 = X.
X = 3.

X is bound to the value of 3.

?- X = foo(a, b).
X = foo(a, b).

X is bound to the compound term foo(a, b). X is now "ground":

?- X = foo(a, b), ground(X).
X = foo(a, b).

?- X = foo(Y, b).
X = foo(Y, b).

X is bound to the partial term foo(Y, b). Y here is an unbound variable. If you ask whether X is ground, the query fails:

?- X = foo(Y, b), ground(X).
false.

A predicate can describe a relationship between terms. For example, the built-in predicate plus/3 describes the following relationship:

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

?- plus(1, 2, X).
X = 3.

?- plus(X, 2, 4).
X = 2.

Now to the last example that you have given: in test(f(X,Y), T), f(X,Y) is not a function: it is a compound term with arity 2, so, f/2. You can evaluate it, as if it were a predicate, or change it in some way to get a different term in the second argument. For example, to switch the argument order:

switch(f(X, Y), f(Y, X)).

With this, you could pose queries like:

?- switch(f(1,2), T).
T = f(2, 1).

?- switch(T, f(a,b)).
T = f(b, a).

?- switch(f(1,X), T), X = foo(bar, baz).
X = foo(bar, baz),
T = f(foo(bar, baz), 1).

So if you wanted a very artificial predicate foo(X, Y) that is defined as follows:

  • true if X is a and Y is aa, or
  • if X is b and Y is bbb, or
  • if X is the compound term f/2, and Y is the compound term g/2 in which the order of the arguments of f/2 is switched.

Implementation:

foo(a, aa).
foo(b, bbb).
foo(f(A, B), g(B, A)).

Terms that are partially bound, also called partial data structures, with "holes" in them, are useful in many different ways. One naive way of implementing a first in, first out queue could be:

% empty_queue(Q) creates an emtpy queue
empty_queue(q(Q,Q)).

% enqueue(Q0, X, Q) enqueues X to the queue Q0, resulting in Q
enqueue(q(Front, [X|Back]), X, q(Front, Back)).

% dequeue(Q0, X, Q) dequeues X from the queue Q0, resulting in Q
dequeue(q([X|Front], Back), X, q(Front, Back)).

You can see for yourself how works and how you can break it (try dequeuing elements you have not enqueued yet!). There are better ways to make a queue, but this is just to show how you can use a partial data structure. If you only use the queue term through these three predicates (empty_queue/1, enqueue/3, dequeue/3), the "back" will always be a free variable.

You need to ask a more specific question for a more specific answer than this.

Upvotes: 3

mat
mat

Reputation: 40768

You must think in terms of relations between different variables.

So, if you want to define a transition between an old value and a new value, you need an additional argument:

state0_state(OldState, NewState) :- NewState = <define yourself> .

The advantage of such relations is that they can often be used in all directions: You can use them to ask, for example: Which old states yield a specific new state? Or more generally: Which transitions are possible at all?

Upvotes: 2

Related Questions