Tarps
Tarps

Reputation: 1943

Swi-prolog two-way clause/fact

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.

  1. Although the cashier beats him consistently, the president will play chess with no one else.

  2. Both the manager and the cashier are better chess players than the accountant.

  3. Jones and Smith are next door neighbors and frequently play chess together in the evening.

  4. Clark plays a better game of chess than Jones.

  5. 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

Answers (1)

max66
max66

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

Related Questions