1
votes

I want to define the following rule in prolog:

when X is thirsty, X should go to the bar.

after, I would ask prolog thirsty(X) and prolog should give back go(bar)

I have tried it on the following way:

go(Y).
thirsty(X) :- go(bar).

But when I test it with

thirsty(bob).

The result will only be true. Can someone help me what I have to change to get go(bar) as the result?

2

2 Answers

3
votes

go(Y). as a rule doesn't really mean anything, other than go anywhere perhaps. When you assert rules in Prolog, you should be able to assign some semantic meaning to them. Your rule says, If X is thirsty, then the bar is a place to go which of course always succeeds since bar is always a place to go, as is any place else you might want to go according to your rule, go(Y). Since you didn't use X anywhere in your thirsty(X) predicate clause body, it's never used (so you probably saw a singleton variable warning about that).

Defining a good rule in Prolog is first about stating your rule in a sensible way first. Perhaps a reasonable rule involving a person might be:

Person goes to the bar if Person is thirsty.

This might be stated as:

go_bar(Person) :- thirsty(Person).

Or more generally,

goes(Person, bar) :- thirsty(Person).
goes(Person, restaurant) :- hungry(Person).

Then you'd need to assert some facts about the person (or query the user for these facts):

thirsty(bob).

With that fact asserted, the following query can result:

?- goes(bob, X).
X = bar
1
votes

when X is thirsty, X should go to the bar.

Looking at the first part of this sentence, "when X is thirsty”, there’s clearly a property thirsty that X can have, so thirsty sounds like a good predicate (thirsty(X) means X is thirsty).

Then there’s a few ways to look at the second part of the sentence, "X should go to the bar”, I’ll write some below in order of increasing complexity with the last being what I think you want:

  1. One is that “should go to the bar” is a property of X, in which case you can define the predicate should_go_to_the_bar as a predicate so that should_go_to_the_bar(X) means X should go to the bar.

Then your program can be:

thirsty(bob).
should_go_to_the_bar(X) :- thirsty(X).

?- should_go_to_the_bar(bob).
True
  1. Another is that “should go to” may be a relation between X and the_bar, so that should_go_to(X, the_bar) means that X should go to the_bar.

Then your program can be:

thirsty(bob).
should_go_to_the_bar(X, the_bar) :- thirsty(X).

?- should_go_to(bob, X).
X = the_bar
  1. Another is that "should" may be a property of actions like go_to(X, the_bar), so that should(go_to(the_bar)) means that it should be that go_to(X, the_bar).

Then your program can be:

thirsty(bob).
should(go_to(X, the_bar)) :- thirsty(X).

?- should(X).
X = should(go_to(bob, the_bar))
  1. Last I’ll go into is that "should" may be a relation between a person X and an action they can do like go_to(X, the_bar), so that should(X, go_to(X, the_bar) means that X should go_to(X, the_bar) i.e. X should make it true that “X goes to the bar".

Then your program can be:

thirsty(bob).
should(X, go_to(X, the_bar)) :- thirsty(X).

?- should(bob, Action).
Action = go_to(bob, the_bar)

I think this last interpretation is closest to what you want.