Reputation: 1943
I need help describing the following facts in Swi-Prolog:
Clark and Jones live in the same house and play chess together.
and
The manager and the architect live in the same house, no other employees live in that house.
I have a structure like this:
[person(_, _), person(_, _), ...]
Where person
describes the following:
person(Name, Occupation)
The puzzle I am solving contains more facts than that, but I am having trouble with describing these two-way facts.
For the sake of simplicity, I have made the solution pretty functional-programming-like, where I split everything into functions. I have a method called fact1(List)
, which accepts the structure described earlier (list of person
structures).
How would I describe that Clark and Jones live in the same house?
name(clark).
name(jones).
name(person(Name, _), Name).
occupation(person(_, Occupation), Occupation).
fact1(List):-
name(Clark, clark),
name(Jones, jones),
???. % have references to Clark and Jones, but what now?
↓ UPDATE ↓
The whole puzzle is as follows (I know it doesn't match the above example).
Brown, Clark, Jones, and Smith are the names of the men who hold, though not necessarily respectively, the positions of accountant, cashier, manager, and president in the First National Bank of Beartown.
Although the cashier beats him consistently, the president will play chess with no one else.
Both the manager and the cashier are better chess players than the accountant.
Jones and Smith are next door neighbors and frequently play chess together in the evening.
Clark plays a better game of chess than Jones.
The accountant lives near the president but not near any others.
I managed to solve it, with the help of a friend, by doing some logic tasks up front.
I combined facts one, three and five, to get the following facts:
Cashier only plays with the president.
Jones and Smith live together and play together.
The accountant lives with the president.
CONCLUSION: Jones and Smith can not be the president nor the cashier, because they live and play together, but the president lives with the accountant and only plays with the cashier.
I then added the following restrictions, and I then got a deterministic single answer:
\+ member(person(jones, accountant), Persons)
\+ member(person(smith, accountant), Persons)
\+ member(person(jones, president), Persons)
\+ member(person(smith, president), Persons)
Upvotes: 1
Views: 297
Reputation: 66230
Not sure to understand but... if you want select a common house, I suppose you should add an house field in your person struct (your example hold only name and occupation).
If your person struct is
person(Name, Occupation, House)
and if you want check if the persons with name jones
and clarke
are sharing the same house and supposing that you have to check a list of person
, I propose the creation of a clause getHouse/3
as follows
getHouse([person(Name, _, House) | _], Name, House).
getHouse([_ | T], Name, House) :-
getHouse(T, Name, House).
to extract, from a list of persons, the house given a name (or a name given a house).
Using getHouse/3
, I suppose you could write your fact1/1
as
fact1(L) :-
getHouse(L, clarke, CommonHouse),
getHouse(L, jones, CommonHouse).
Upvotes: 1