2
votes

I hate to ask basic questions here, but, it seems, good manuals on Prolog are hard to find.

I have two terms:

woman(alice).
woman(janice).

Now, I want to make the following compound term:

sisters(woman(X), woman(Y)).

When I run the query sisters(X,Y), I get this mumbo jumbo: X = woman(_G2215), Y = woman(_G2217)

In fact, everything satisfies it.

sisters(woman(david), woman(xxxxxx))

is also true.

Why doesn't it work the intended way? It seems, prolog never looks at the first 2 terms.

I know I should make it

sisters(X, Y) :- woman(X), woman(Y), X \= Y

but I want to know why the first way doesn't work.

2

2 Answers

1
votes

In the case of the clause:

sisters(woman(X), woman(Y)).

the arguments are the terms women/1, not calls to the women/1 predicate. Note that Prolog is not a functional language.

1
votes

To elaborate on Paulo's answer...

You have established the following facts:

woman(alice).    % 'alice' is a woman
woman(janice).   % 'janice' is a woman
sisters(woman(X), woman(Y)).   % woman(X) is a sister of woman(Y) for ANY X and Y

So you can see, for reasons Paulo points out about compound terms and that Prolog doesn't recursively query them, you're already headed in a direction you did not intend. In this context, you have stated a fact, sisters(woman(X), woman(Y)) with two independent, uninstantiated variables. Since they are variables, and you don't have any sisters/2 clause to constrain their values, they can be anything.

So for the following query:

sisters(X, Y).

Prolog looks at your facts and predicates for a match and finds, sisters(woman(X), woman(Y)). The logical answer is, therefore:

X = woman(_G2215)
Y = woman(_G2217)

This just says it is true for these values of X and Y where _G2215 and _G2217 are arbitrary variables. Any value of these would be true based upon the rules and facts you have stated. In particular that means that this is true:

sisters(woman(david), woman(xxxxxx))

Because X could be david and Y could be xxxxxx and it would be true, since your fact says:

sisters(woman(X), woman(Y)).

You could introduce a rule:

sisters(woman(X), woman(Y)) :- woman(X), woman(Y), X \= Y.

And then you'd start getting sensible answers to the query, sisters(X, Y):

X = woman(alice)
Y = woman(janice)

Or more simply, as you have:

sisters(X, Y) :- woman(X), woman(Y), X \= Y.

With result:

X = alice
Y = janice