0
votes

I decided to learn basic Prolog because the idea of it seemed interesting. The language itself is difficult to put my head around though.

As an excercise I decided to try and make a simple program to solve knight/knave/villager puzzles. As a base I took a program solving knight/knave puzzles and tried to modify it to suit my needs. The puzzle rules are well known

  • knight - always tells the truth
  • knave - never tells the truth
  • villager - sometimes tells the truth, sometimes doesn't

So in the program that I based mine off of, there were these two most important rules in code:

said(knight, X) :- true(X)
said(knave, X) :- false(X)

And that's easy enough. If something is true, it was a knight who said it. If it's false, it was a knave who said it. But what about an alternative conclusion, namely that it was a villager who said X?

I tried this:

said(villager, X) :- true(X); false(X)

But I think it means "If X is either true or false, a villager said it", which is not what I want.

How do I say "If something is true, either a villager or a knight said it" (and same with false/knave) in Prolog? I imagine I'd have to modify the first two lines, but how?

1
To me, the best, and most intuitive examples for Prolog beginners are the family relations, maps and fun with natural numbers. - false

1 Answers

1
votes

You just add said(villager,X) :- true(X) as a new fact; you don't need to modify the original facts (as they are still true). Then you can add said(villager,X) :- false(X). Which all amounts to what you originally had.

This seems to match "villager sometimes tells the truth, sometimes doesn't"? It seems like you have no basis, based on the truth of a statement, to tell if the villager said it; all you can do is tell if they could have said it.