Joffrey Baratheon
Joffrey Baratheon

Reputation: 474

Success and failure when querying the database

So I'm stuck on an exercise that I've been working on. I have the following facts:

sd(appleseed0, appleseed1).

sd(appleseed0, apple1).
sd(appleseed1, apple1).
sd(appleseed2, apple1).

sd(appleseed0, apple2).
sd(appleseed1, apple2).
sd(appleseed2, apple2).

What this means is that appleseed1 came from appleseed0, apple1 came from appleseed0, etc. The problem I'm having is that I need it to print out false if the values are switched around. Meaning, I want the query to result in "true" when the query is seed(appleseed0, apple1) and then "false" when the query is in opposite order like seed(apple1, appleseed0).

Right now, my predicate looks like this:

seed(A,B) :- sd(A,B) ; sd(B,A).

I understand that this is why my queries are returning true, no matter the order, but my only other idea is:

seed(A,B) :- sd(A,B). 

but I cannot write it like that because that would make it an infinite loop with no false. How can I make it so that the query will result in "true" when shown with something like seed(appleseed2, apple2) and "false" when shown with something like seed(apple2, appleseed2)?

Upvotes: 2

Views: 113

Answers (1)

user1812457
user1812457

Reputation:

Hoping that I am reading your question correctly:

You don't need an extra predicate. Indeed, what you are looking for is the query:

?- sd(A, B).

This will succeed or fail just like you describe. The predicate

seed(A, B) :-
    (   sd(A, B)
    ;   sd(B, A)
    ).

(just like yours, just formatted to be easier to follow) reads: "seed(A, B) is true when sd(A, B) is true. It is also true when sd(B, A) is true" (like you have noticed). An interesting side effect is that if you had these two facts in your database:

sd(foo, bar).
sd(bar, foo).

Then the query:

?- seed(foo, bar).

will succeed twice (!), just like the query

?- seed(bar, foo).

or the equivalent top level query

?- sd(bar, foo) ; sd(foo, bar).

That last query makes it most obvious why the query will succeed twice.

What confuses me: Why do you think that

seed(A, B) :-
    sd(A, B).

will lead to an infinite loop? Is there some part of the program that you are not showing? As it stands, defining a predicate like this is equivalent to just giving sd/2 an alias, seed/2. This definition reads: "seed(A, B) is true when sd(A, B) is true."

Upvotes: 1

Related Questions