Hi I'm desperately try to understand this snippet from my understanding it sets the variables X:1
, Z:[2,3]
. Now I can't get any further...
prefix([],X).
prefix([X|Y],[X|Z]):-prefix(Y,Z).
?-prefix(W,[1,2,3]).
Prolog doesn't really "set" variables to values. It attempts to unify arguments when you make a query or if you use the unification operator, =/2
.
Let's see what happens in Prolog when you make a query.
?- prefix(W, [1,2,3]).
When you make this query, Prolog will start searching your asserted facts and predicates (including those pre-defined in your Prolog environment) for something that matches prefix(W, [1,2,3]).
The first candidate it encounters is:
prefix([], X).
Prolog attempts to unify W
with []
, and succeeds with W = []
. It then attempts to unify [1,2,3]
with X
. This also succeeds with X = [1,2,3]
. So the complete clause succeeds and you get the first solution on this query:
W = [] ?
If at this point you press ;
, Prolog will backtrack if there were choice points, which there were since you have additional prefix/2
clauses. So Prolog goes back to that point and attempts to match prefix(W, [1,2,3])
with prefix([X|Y],[X|Z])
. It attempts to unify W
with [X|Y]
and succeeds with W = [X|Y]
(yes, at this point, these are all variable), and successfully unifies [1,2,3]
with [X|Z]
with X = 1
and Z = [2,3]
. This now means W = [1|Y]
(Y
is still unbound). Since this is the head of the clause of a predicate, Prolog will execute the body...
So now with W = [1|Y]
, X = 1
, and Z = [2,3]
, Prolog will call:
prefix(Y, Z).
In other words, it will call, prefix(Y, [2,3])
. Since this is now a "fresh" query to prefix/2
, Prolog starts searching from the top of your database of asserted facts and rules again and attempts to match prefix(Y, [2,3])
with prefix([], X).
This succeeds with Y = []
and X = [2,3]
. Remember: this was a recursive call from prefix([X|Y], [X|Z])
so let's make note of all the unifications when the prefix(Y, [2,3])
call returns. We had X = 1
, Z = [2,3]
and now Y = []
. So prefix([X|Y], [X|Z])
in this case succeeds with X = 1
, Y = []
and Z = [2,3]
. Thus, the original call prefix(W, [1,2,3])
succeeds with:
W = [X|Y] = [1|[]] = [1].
The last call prefix(Y, [2,3])
left a choice point just as prefix(W, [1,2,3])
originally did! So you can chase that one back using the same logic as above until you exhaust all of the successful possibilities. You'll eventually get all of the solutions for W
.
I'm not going to go through all of them. That would be too long, and this is your assignment, not mine. :) Try to understand the principle I gave above for how Prolog searches your facts and rules and try yourself.
In understanding how to trace the predicate, it's also helpful to understand how to semantically read it.
prefix([], X).
This says that []
is the prefix for any list. Technically, since this is list-specific, this might be more precisely written:
prefix([], L) :- is_list(L).
Or...
prefix([], []).
prefix([], [_|_]).
Otherwise, with simply prefix([], _).
or prefix([], X).
, silly things like prefix(P, 3)
succeed with P = []
.
Then the recursive predicate:
prefix([X|Y], [X|Z]) :- prefix(Y, Z).
This says that, [X|Y]
is a prefix of [X|Z]
if Y
is a prefix of Z
.
The flow of the recursion follows this description.