LINUX.ORG.RU

[swi-prolog][howto] Логическая программа

 


0

0

Репост из толксов.
На дискретной математики (1 курс) занимались тем, что делали «логическую программу» на ПРОЛОГе. Например, есть задача

Область определения --– люди колледжа.

  • Все выпускники Итона в колледже играют в крикет.
  • Никто, кроме преподавателей, не обедает за верхним столом.
  • Ни один из тех, кто играет в крикет, не умеет грести.
  • Все мои друзья в этом колледже выпускники Итона.
  • Все преподаватели прекрасные гребцы.

Вывод: все мои друзья не преподаватели.

. После формализации задача имеет такой вид: картинко. «Логическая программа» имеет вид такой:

Predicates: 
V(x) 
K(x) 
P(x) 
O(x) 
G(x) 
D(x) 
Clauses: 
D(a) 
K(x):-V(x) 
P(x):-O(x) 
:-K(x),G(x) 
V(x):-D(x) 
G(x):-P(x) 
Goal ?- not(O(a)) 
. Хотелось бы сделать так, чтобы эти «логические программы» можно было бы запускать в swi-prolog'е.

Насколько я понял, первые 8 строк не нужны, но что делать дальше я так и не понял. Помогите, пожалуйста.
Спасибо.

★★

#!/usr/bin/pl -q -t run -f

d(a).
k(X):- v(X).
p(X):- o(X).
not(g(X)):- k(X).
v(X):- d(X).
g(X):- p(X).

run :- not(p(a)), write('Yes'), nl.

run :- write('No'), nl.

В результате получается «No», среди преподавателей есть друзья.

Rudcozt
()
Ответ на: комментарий от Rudcozt

Спасибо, хоть что-то уже ясно. Но ответ странный. По идее, там должно было получиться, что нет друзей среди преподов.оО

do0dlez ★★
() автор топика
Ответ на: комментарий от do0dlez

Хм, еслибы среди друзей были преподы, то

Все мои друзья в этом колледже выпускники Итона.

Преподы - выпускники Иртона

Все выпускники Итона в колледже играют в крикет.

Преподы играют в крикет

Ни один из тех, кто играет в крикет, не умеет грести.

Преподы не умеют грести.

Все преподаватели прекрасные гребцы.

FAIL.

Viglim
()
Ответ на: комментарий от do0dlez

Видимо, в программу закралась «досадная ошибка».

Viglim
()

%Вот тебе твоя программа, ну оччень сложная :)

друг(сэм).
преподаватель(мистер_Джонсон).
выпускник_иттона(X) :- друг(X).
гребец(X) :- преподаватель(X).
обедает_за_верхним_столом(X) :- преподаватель(X).
играет_в_крикет(X) :- выпускник_иттона(X).
играет_в_крикет(X) :- \+ гребец(X).

% ... а вот варианты запросов

% ?- друг(X),обедает_за_верхним_столом(X).
% ?- друг(X), \+обедает_за_верхним_столом(X).
?- друг(X), \+преподаватель(X).

Attila ★★
()
Ответ на: комментарий от do0dlez

>Да. Заметил ошибку: в выводе не О, а Р.

С точки зрения логики задачи это до фени, всё равно гребут и едят только преподы :)

Attila ★★
()

Какой ужас.

В результате получается «No», среди преподавателей есть друзья.

Чушь. В твоей программе происходит следующее: вызывается первая подцель not(p(a)), и тут же происходит фейл, потому что в заголовке правила стоит not(g(X)). man унификация. До всей остальной писанины дело даже не доходит.

Вот тебе твоя программа, ну оччень сложная :)

А ты сам понимаешь как она работает? Похоже, что нет. У тебя в запросе Х сначала унифицируется с сэмом, а потом уже фейлится подцель преподаватель(сэм), потому что единственный имеющийся вариант это преподаватель(мистер_ктототам). Как и у предыдущего советчика до остальной программы (в которой тоже полно ошибок) дело даже не доходит.

Держите:

man(p1).
man(p2).
man(p3).
man(p4).

activity(p1, graduate).
activity(p1, croquet).
activity(p2, graduate).
activity(p3, dining).
%activity(p4, graduate).
%activity(p4, dining).

graduate(X) :- man(X), activity(X, graduate).
dining(X) :- man(X), activity(X, dining).

player(X) :- graduate(X).
boater(X) :- \+player(X).
boater(X) :- teacher(X).
teacher(X) :- dining(X).
my_friend(X) :- graduate(X).

goal :- forall(my_friend(X), \+teacher(X)).

anonymous
()
Ответ на: комментарий от Attila

Ох лол. А еще с таким понтом в толксах отметился, «пролог вы проходили ... мимо :( », да «я бы рекомендовал почитать И. Братко». Да еще и звезду нацепил.

anonymous
()
Ответ на: комментарий от anonymous

Твоё решение притянуто за уши не меньше моего. Раз уж пошла такая жара, то по-уму надо было программу начинать с объявления списков для Студентов, Преподавателей, Выпускников_Итона, Игроков, Гребцов, Обедающих(хотя они лишняя сущность) и, наконец, Друзей. И только после этого писать правила. Есть только два НО: 1-е - с прологом я закончил баловаться 20 лет назад, а с программированием вообще лет 10, боюсь буду долго вспоминать нюансы; 2-е - ТСу такая программа порвёт моск окончательно, он в элементарном «плавает». Так что всё в твоих руках - блесни интеллектом, порви всем моск :)

Attila ★★
()
Ответ на: комментарий от Attila

Раз уж пошла такая жара, то по-уму надо было программу начинать с объявления списков для Студентов, Преподавателей, Выпускников_Итона, Игроков, Гребцов, Обедающих(хотя они лишняя сущность) и, наконец, Друзей

Нет. Этого нет в условии и если всех задать явно никакого логического вывода и правил не потребуется, будет просто набор фактов.

1-е - с прологом я закончил баловаться 20 лет назад, а с программированием вообще лет 10

А зачем тогда в советчики лезешь? Напиал фигню да еще и упираешься.

боюсь буду долго вспоминать нюансы

Это не нюансы, это основы пролога. Твоя программа сводится к

факт1(а).
факт2(б).
?- факт1(Х), \+факт2(Х).
И это явно не то, что они обсуждали на семинаре по матлогике. Остальное у тебя, во-первых, не участвует, а, во-вторых, записано с ошибками.

ТСу такая программа порвёт моск окончательно, он в элементарном «плавает»

Не порвет, это и есть элементарная программа.

anonymous
()
Ответ на: комментарий от anonymous

И если уж кого-то так смущает и рвет им моск отдельное описание человеков и их деятельности, то можно сделать так. [code]:- dynamic graduate/1. :- dynamic dining/1.

graduate(p1). graduate(p2). [/code]

anonymous
()
Ответ на: комментарий от anonymous

Спасибо! Вчера узнал, что то, чем мы занимались препод лишь в шутку называла ПРОЛОГом. Вот.

do0dlez ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.