Swi-prolog двусторонняя статья / факт

Мне нужна помощь в описании следующих фактов в Swi-Prolog:

Кларк и Джонс живут в одном доме и вместе играют в шахматы.

а также

Менеджер и архитектор живут в одном доме, другие работники не живут в этом доме.

У меня есть такая структура:

[person(_, _), person(_, _), ...]

куда person описывает следующее:

person(Name, Occupation)

Головоломка, которую я решаю, содержит больше фактов, но у меня возникают проблемы с описанием этих двусторонних фактов.

Для простоты я сделал решение довольно функциональным, как программирование, где я разбил все на функции. У меня есть метод fact1(List), которая принимает структуру, описанную ранее (список person структуры).

Как бы я описал, что Кларк и Джонс живут в одном доме?

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?

↓ ОБНОВЛЕНИЕ ↓

Вся головоломка выглядит следующим образом (я знаю, что это не соответствует приведенному выше примеру).

Браун, Кларк, Джонс и Смит - это имена людей, которые занимают, хотя и не обязательно, соответственно должности бухгалтера, кассира, менеджера и президента в Первом национальном банке Бэртауна.

  1. Хотя кассир постоянно его бьет, президент будет играть в шахматы ни с кем другим.

  2. И менеджер, и кассир - лучшие шахматисты, чем бухгалтер.

  3. Джонс и Смит - ближайшие соседи и по вечерам часто играют в шахматы.

  4. Кларк играет в шахматы лучше, чем Джонс.

  5. Бухгалтер живет рядом с президентом, но не рядом ни с кем другим.

Мне удалось решить это с помощью друга, выполнив некоторые логические задачи заранее.

Я объединил факты один, три и пять, чтобы получить следующие факты:

Кассир играет только с президентом.

Джонс и Смит живут вместе и играют вместе.

Бухгалтер живет с президентом.

ЗАКЛЮЧЕНИЕ: Джонс и Смит не могут быть президентом или кассиром, потому что они живут и играют вместе, но президент живет с бухгалтером и играет только с кассиром.

Затем я добавил следующие ограничения и получил однозначный единственный ответ:

\+ member(person(jones, accountant), Persons)
\+ member(person(smith, accountant), Persons)
\+ member(person(jones, president), Persons)
\+ member(person(smith, president), Persons)

1 ответ

Не уверен, что понимаю, но... если вы хотите выбрать общий дом, я полагаю, вы должны добавить поле дома в своей структуре персонажа (ваш пример содержит только имя и род занятий).

Если ваша личность структура

 person(Name, Occupation, House)

и если вы хотите проверить, если люди с именем jones а также clarke делят один и тот же дом и предположим, что вы должны проверить список personПредлагаю создать статью getHouse/3 следующее

getHouse([person(Name, _, House) | _], Name, House).

getHouse([_ | T], Name, House) :-
  getHouse(T, Name, House).

извлечь из списка лиц дом, которому дано имя (или имя, данное дому).

С помощью getHouse/3Я полагаю, вы могли бы написать свой fact1/1 как

fact1(L) :-
  getHouse(L, clarke, CommonHouse),
  getHouse(L, jones, CommonHouse).
Другие вопросы по тегам