I have the following Prolog
Program:
p(f(X), Y) :- p(g(X), g(Y)).
p(g(X), Y) :- p(f(Y), f(X)).
p(f(a), g(b)).
The prolog proof tree has to be drawn for the predicate p(X, Y)
.
Question:
Y
matched to Y1/Y
and not to Y/Y1
and why is Y
used further on?p(X, Y)
), I get a new predicate (e.g. p(g(X1), g(Y))
) - why contains p(g(X1), g(Y))
just one subtree? I mean, shouldn't it have 3 because the knowledgebase contains 3 statements - instead of just 1?g(X1)/fX5, g(Y1)/Y5
?Note: Maybe it seems that I have never done a tutorial or something. But I did.. I appreciate every help.
Very good questions!
Why is
Y
matched toY1/Y
and not toY/Y1
and why isY
used further on?
The naming here seems a little arbitrary in that they could have used Y/Y1
but then would need to use Y1
further on. In this case, they chose Y1/Y
and use Y
further on. Although the author of this expression tree was inconsistent in their convention, I wouldn't be too concerned about the naming as much as whether they follow the variable correctly down the tree.
if I match a predicate (e.g.
p(X, Y)
), I get a new predicate (e.g.p(g(X1), g(Y))
) - why containsp(g(X1), g(Y))
just one subtree? I mean, should'nt it have 3 because the knowledgebase contains 3 statements - instead of just 1?
First a word on term versus predicate. A term is only a predicate in the context of Head :- Body
in which case Head
is a term that forms the head of a predicate clause. If a term is an argument to a predicate (for example, p(g(X1), g(Y))
, the g(X1)
and g(Y)
are not predicates. They are just terms.
More specifically in this case, the term p(g(X1), g(Y))
only has one subtree because it only matches the head of one of the 3 predicate clauses which is the one with the head p(g(X), Y)
(it matches with X = X1
and Y = g(Y)
). The other two can't match since they're of the form p(f(...), ...)
and the f(...)
term cannot match the g(X1)
term.
And why is at each layer of the tree matched with something like
X2/X1
and so on ? and not with the predicate before ? Shouldn't it beg(X1)/fX5, g(Y1)/Y5
?
I'm not sure I'm following this question, but the principle to follow is that the tree is attempting to use the same variable name if it applies to the same variable in memory, whereas a different variable name (e.g., X1
versus X
) is used if it's a different X
. For example, if I have foo(X, Y) :- <some code>, bar(f(X), Y).
and I have bar(X, Y) :- blah(X), ...
then the X
referred to in the bar
predicate is different than the X
referred to in the foo
predicate. So we might say, in the call to foo(X, Y)
we're calling bar(f(X), Y)
, or alternatively, bar(X1, Y)
where X1 = f(X)
.