Average_guy
Average_guy

Reputation: 571

Why does my predicate not work, when a similar predicate does?

I have the following facts:

loves(andy, julia).
loves(andrew, maria).
loves(bob, sofia).
loved(juila).
loved(maria).
loved(sofia).

and I want to have two predicates:

do_love(X, Y) :- ...
is_loved(X, Y) :- ...

which returns Y as the name of the person, and X as the fact itself. For the loved fact, I wrote:

is_loved(X, Y) :- X = loved(Y), X.

which as expected, returns:

is_loved(X,Y).
X = loved(juila),
Y = juila ;
X = loved(maria),
Y = maria ;
X = loved(sofia),
Y = sofia.

However, when I write the predicate for the loves fact in a similar way:

do_love(X, Y) :- X = loves(X, Y), X.

it returns false for the query:

do_love(X,Y).
false.

I'm new to prolog, and can't really see why this is the case. Why does the query for is_loved work, while the one for do_love doesn't?

Upvotes: 2

Views: 300

Answers (1)

soundly_typed
soundly_typed

Reputation: 40356

The problem is you're trying to unify X with two different values:

  • X = loves(...) and
  • loves(X, ...)

(I truncate using ... because those parts are irrelevant to what I'm saying).

In other words, your do_love predicate is saying "X must unify with a loves predicate" and also "X must unify with the first argument in a loves predicate". With the data set you've set up, no single value fulfills both requirements.

Depending on what you're trying to do, this might be what you want:

do_love(X, Y) :- loves(X, Y).

Sidenote 1: Predicates don't "return" values like they do in other languages with functions. You don't need the , X in your predicates for them to work.

Sidenote 2: The = is a "unify" operator, rather than an "assignment" like other languages. See this page for more info.

Upvotes: 5

Related Questions