0
votes

I am a Prolog newbie. I'm attending an AI course at my university, so we can't use advanced Prolog features: just simple facts and super-simple rules.

I'm having some trouble converting this two sentences to Prolog clauses:

  1. Everyone who loves all animals is loved by someone.
  2. Anyone who kills an animal is loved by no one.

I somehow managed to write the second one like this:

loves(X, Y) :- animal(A), \+killed(Y, A).

but even for this one, I'm quite sure it isn't quite right: this rule tells that everyone who didn't kill an animal is loved by everyone, which is the opposite of what I wanted to express.

Any help?

2
what are the facts (positive knowledge) you have ?CapelliC

2 Answers

1
votes

Have you studied predicate calculus, the logic of quantifiers?

There are problems with expressing truth of these two statements in Prolog. The first posits, for everyone Y who loves "all animals", the existence of someone X who loves Y, but without telling us how to "construct" X. The second one expresses knowledge of a negative statement, "Anyone who kills an animal is loved by no one."

Potentially you could have facts that express knowledge of all individuals, who loves who, who loves all animals, and who has killed an animal. Then you could write queries that check whether 1,2 hold. This is different from trying to assert the truth of 1,2 by rules and facts.

1
votes

You rewrote your problem with the contrapositive. Good.

  1. X loves Y implies B did not kill C, C is an animal.

But you expressed it as a disjunction of all other conditions. You should instead define

killed_no_animal(Y) :- forall(animal(A), \+killed(Y, A)).

And use killed_no_animal as a necessary condition to all other predicates:

loves(X, Y) :- killed_no_animal(Y), other predicate.
loves(X, Y) :- killed_no_animal(Y), other predicate.