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?
↓ ОБНОВЛЕНИЕ ↓
Вся головоломка выглядит следующим образом (я знаю, что это не соответствует приведенному выше примеру).
Браун, Кларк, Джонс и Смит - это имена людей, которые занимают, хотя и не обязательно, соответственно должности бухгалтера, кассира, менеджера и президента в Первом национальном банке Бэртауна.
Хотя кассир постоянно его бьет, президент будет играть в шахматы ни с кем другим.
И менеджер, и кассир - лучшие шахматисты, чем бухгалтер.
Джонс и Смит - ближайшие соседи и по вечерам часто играют в шахматы.
Кларк играет в шахматы лучше, чем Джонс.
Бухгалтер живет рядом с президентом, но не рядом ни с кем другим.
Мне удалось решить это с помощью друга, выполнив некоторые логические задачи заранее.
Я объединил факты один, три и пять, чтобы получить следующие факты:
Кассир играет только с президентом.
Джонс и Смит живут вместе и играют вместе.
Бухгалтер живет с президентом.
ЗАКЛЮЧЕНИЕ: Джонс и Смит не могут быть президентом или кассиром, потому что они живут и играют вместе, но президент живет с бухгалтером и играет только с кассиром.
Затем я добавил следующие ограничения и получил однозначный единственный ответ:
\+ 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).