Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Решение логической задачи, как можно сделать на прологе? 
:(
    Опции темы
MacTep
Дата 22.12.2006, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Условие задачи:
В пяти домах, окрашенных в разные цвета, обитают мужчины разных национальностей. Они держат разных животных, предпочитают разные напитки и курят сигареты разных марок. Известно, что:
1. Англичанин живет в красном доме.
2. У испанца есть собака.
3. Кофе пьют в зеленом доме.
4. Украинец пьет чай.
5. Зеленый дом – первый по правую руку от  бежевого дома.
6. Курильщик «Уинстона» держит улиток.
7. Сигареты «Кул» курят в желтом доме.
8. Молоко пьют в среднем доме.
9. Норвежец живет в крайнем слева доме.
10. Мужчина, курящий «Честерфилд», живет в доме, соседнем с домом мужчины, у которого есть лиса.
11. Сигареты «Кул» курят в доме, соседнем с домом, где имеется лошадь.
12. Курящий «Лаки страйк» пьет апельсиновый сок.
13. Японец курит «Парламент».
14. Норвежец живет в доме рядом с голубым домом.
Вопросы : У кого есть зебра? Кто пьет воду?
Как такое возможно на Прологе написать?


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
MacTep
Дата 22.12.2006, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Вот я тут набросал решение, но прога у меня не работает. Может кто посоветует. Очень и очень надо. Помогите, кто чем может...
Код

predicates
        rewenie(string,string,string,string,string,
                string,string,string,string,string,
                string,string,string,string,string,
                string,String,string,string,string,
                string,string,string,string,string)
        posit(string)
        nation(string)
        color(string)
        cigar(string)
        animal(string)
        napitok(string)
        sootv(string,string,string,string,string)
        
clauses
    posit(pervij).
    posit(vtoroj).
    posit(tretij).
    posit(chetvertij).
    posit(pyatij).
    nation(anglichanin).
    nation(wved).
    nation(datchanin).
    nation(norvezhec).
    nation(nemec).
    color(red).
    color(white).
    color(blue).
    color(yellow).
    color(green).
    animal(kowka).
    animal(lowad).
    animal(ptica).
    animal(riba).
    animal(sobaka).
    cigar(dunhill).
    cigar(marlboro).
    cigar(pallmall).
    cigar(rothmans).
    cigar(winfield).
    napitok(voda).
    napitok(chaj).
    napitok(moloko).
    napitok(kofe).
    napitok(pivo).

    sootv(X,Y,Z,M,N) :- nation(X), X=anglichanin,  
      color(Y), Y=red.
        sootv(X,Y,Z,M,N) :- nation(X), X=wved,
          animal(M), M=sobaka.
        sootv(X,Y,Z,M,N) :- nation(X), X=datchanin, 
          napitok(N), N=chaj.
        sootv(X,Y,Z,M,N) :- color(Y), Y=green,
          napitok(N), N=kofe.
        sootv(X,Y,Z,M,N) :- cigar(Z), Z=pallmall,
          animal(M), M=ptica.
        sootv(X,Y,Z,M,N) :- color(Y), Y=yellow,
          cigar(Z), Z=dunhill.
        sootv(X,Y,Z,M,N) :- nation(X), X=norvezhec,
          posit(K), K=pervij.
        sootv(X,Y,Z,M,N) :- cigar(Z), Z=winfield,
          napitok(N), N=pivo.
        sootv(X,Y,Z,M,N) :- nation(X), X=nemec,
          cigar(Z), Z=rothmans.
       
    rewenie(X1,Y1,Z1,M1,N1,
            X2,Y2,Z2,M2,N2,
            X3,Y3,Z3,M3,N3,
            X4,Y4,Z4,M4,N4,
            X5,Y5,Z5,M5,N5) :- 
             X1=anglichanin, sootv(X1,Y1,Z1,M1,N1), 
             X2=wved,        sootv(X2,Y2,Z2,M2,N2),
             X3=norvezhec,   sootv(X3,Y3,Z3,M3,N3),
             X4=nemec,       sootv(X4,Y4,Z4,M4,N4),
             X5=datchanin,   sootv(X5,Y5,Z5,M5,N5),
             Y1<>Y2,Y1<>Y3,Y1<>Y4,Y1<>Y5,Y2<>Y3,Y2<>Y4,Y2<>Y5,Y3<>Y4,Y3<>Y5,Y4<>Y5,
             Z1<>Z2,Z1<>Z3,Z1<>Z4,Z1<>Z5,Z2<>Z3,Z2<>Z4,Z2<>Z5,Z3<>Z4,Z3<>Z5,Z4<>Z5,
             M1<>M2,M1<>M3,M1<>M4,M1<>M5,M2<>M3,M2<>M4,M2<>M5,M3<>M4,M3<>M5,M4<>M5,           N1<>N2,N1<>N3,N1<>N4,N1<>N5,N2<>N3,N2<>N4,N2<>N5,N3<>M4,N3<>N5,N4<>N5.


Это сообщение отредактировал(а) MacTep - 22.12.2006, 23:31


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Artemios
Дата 23.12.2006, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 14.8.2006
Где: Саратов, Россия

Репутация: 2
Всего: 50



Прикинул, но у меня тоже на заработало. Точнее, работает, но вместо нужных соответствий всегда No.
Код

решение(СписокДомов,[[],[],[],[],[]],[[],[],[],[],[]],СписокДомов).
решение(СписокДомов,СписокАттр,СписокАттр2,СписокДомов2):-
    выборка(Дом,СписокАттр,СписокАттр1), 
    непротиворечит(Дом,СписокДомов),
    решение([Дом|СписокДомов],СписокАттр1,СписокАттр2,СписокДомов2).

выборка([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],[СНом,СЦв,СНац,СЖив,СПойл,ССиг],[СНом2,СЦв2,СНац2,СЖив2,СПойл2,ССиг2]):-
    select(Номер,СНом,СНом2),
    select(Цвет,СЦв,СЦв2),
    select(Национальность,СНац,СНац2),
    select(Животное,СЖив,СЖив2),
    select(Пойло,СПойл,СПойл2),
    select(Сигареты,ССиг,ССиг2).

эквивалентно(А,Б):-
    А,Б;
    not(А),not(Б).

соседи(Номер1,Номер2):-
    Номер1 is Номер2-1;
    Номер1 is Номер2+1.

непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],[]):-
    эквивалентно(Цвет=красный, Национальность=англичанин), %правило 1
    эквивалентно(Национальность=испанец, Животное=собака), %правило 2
    эквивалентно(Цвет=зеленый, Пойло=кофе), %правило 3
    эквивалентно(Национальность=украинец, Пойло=чай), %правило 4
    эквивалентно(Животное=улитки, Сигареты='Уинстон'), %правило 6
    эквивалентно(Цвет=желтый, Сигареты='Кул'), %правило 7
    эквивалентно(Номер=3, Пойло=молоко), %правило 8
    эквивалентно(Номер=1, Национальность=норвежец), %правило 9
    эквивалентно(Пойло='апельсиновый сок', Сигареты='Лаки Страйк'), %правило 12
    эквивалентно(Национальность=японец, Сигареты='Парламент'), %правило 13
    эквивалентно(Сигареты='Честерфилд',Животное\=лиса), %часть правила 10
    эквивалентно(Сигареты='Кул',Животное\=лошадь), %часть правила 11
    эквивалентно(Национальность=норвежец,Цвет\=голубой). %часть правила 14

непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],[[Номер2,Цвет2,Национальность2,Животное2,Пойло2,Сигареты2]|Остальные]):-
    (Цвет=зеленый,Цвет2=бежевый,!,Номер2 is Номер-1;true), %правило 5
    (Сигареты='Честерфилд',Животное2=лиса,!,соседи(Номер,Номер2);true), %правило 10
    (Сигареты='Кул',Животное2=лошадь,!,соседи(Номер,Номер2);true), %правило 11
    (Национальность=норвежец,Цвет2=голубой,!,соседи(Номер,Номер2);true), %правило 14
    непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],Остальные).

решение(СписокДомов):-
    решение([],[[1,2,3,4,5],[красный,зеленый,бежевый,желтый,голубой],[англичанин,испанец,украинец,норвежец,японец],[собака,улитки,лиса,лошадь,зебра],[кофе,чай,молоко,'апельсиновый сок',вода],['Уинстон','Кул','Честерфилд','Лаки Страйк','Парламент']],_,СписокДомов).

либо я где-то ошибаюсь, либо я чего-то не понял smile smile


--------------------
fib = 1: 1: [ x+y | (x,y) <- zip fib (tail fib) ]
PM MAIL   Вверх
Artemios
Дата 23.12.2006, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 14.8.2006
Где: Саратов, Россия

Репутация: 2
Всего: 50



При замене в 14 правиле норвежца на англичанина программа:
Код

решение([Дом1,Дом2,Дом3,Дом4,Дом5],СписокАттр):-
    выборка(Дом1,СписокАттр,СписокАттр1),
    выборка(Дом2,СписокАттр1,СписокАттр2),
    непротиворечит(Дом2,[Дом1]),
    выборка(Дом3,СписокАттр2,СписокАттр3),
    непротиворечит(Дом3,[Дом1,Дом2]),
    выборка(Дом4,СписокАттр3,СписокАттр4),
    непротиворечит(Дом4,[Дом1,Дом2,Дом3]),
    выборка(Дом5,СписокАттр4,_),
    непротиворечит(Дом5,[Дом1,Дом2,Дом3,Дом4]).

выборка([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],[СНом,СЦв,СНац,СЖив,СПойл,ССиг],[СНом2,СЦв2,СНац2,СЖив2,СПойл2,ССиг2]):-
    select(Номер,СНом,СНом2),
    select(Цвет,СЦв,СЦв2),
    select(Национальность,СНац,СНац2),
    select(Животное,СЖив,СЖив2),
    select(Пойло,СПойл,СПойл2),
    select(Сигареты,ССиг,ССиг2),
    непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты]).

эквивалентно(А,Б):- % эквивалентность логических утверждений А и Б
    А,Б;
    not(А),not(Б).

следовательно(А,Б):- % из утверждения А следует утверждение Б
    А,Б;
    not(А),Б;
    not(А),not(Б).

соседи(Номер1,Номер2):-
    Номер1 is Номер2-1;
    Номер1 is Номер2+1.

% проверка по внутренним соответствиям
непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты]):-
    эквивалентно(Цвет=красный, Национальность=англичанин), %правило 1
    эквивалентно(Национальность=испанец, Животное=собака), %правило 2
    эквивалентно(Цвет=зеленый, Пойло=кофе), %правило 3
    эквивалентно(Национальность=украинец, Пойло=чай), %правило 4
    эквивалентно(Животное=улитки, Сигареты='Уинстон'), %правило 6
    эквивалентно(Цвет=желтый, Сигареты='Кул'), %правило 7
    эквивалентно(Номер=3, Пойло=молоко), %правило 8
    эквивалентно(Номер=1, Национальность=норвежец), %правило 9
    эквивалентно(Пойло='апельсиновый сок', Сигареты='Лаки Страйк'), %правило 12
    эквивалентно(Национальность=японец, Сигареты='Парламент'). %правило 13

% проверка по соседям
непротиворечит(_,[]).
непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],[[Номер2,Цвет2,Национальность2,Животное2,Пойло2,Сигареты2]|Остальные]):-
    следовательно((Цвет=зеленый,Цвет2=бежевый),Номер2 is Номер-1), %правило 5
    следовательно((Цвет2=зеленый,Цвет=бежевый),Номер is Номер2-1), %правило 5
    следовательно((Сигареты='Честерфилд',Животное2=лиса),соседи(Номер,Номер2)), %правило 10
    следовательно((Сигареты2='Честерфилд',Животное=лиса),соседи(Номер,Номер2)), %правило 10
    следовательно((Сигареты='Кул',Животное2=лошадь),соседи(Номер,Номер2)), %правило 11
    следовательно((Сигареты2='Кул',Животное=лошадь),соседи(Номер,Номер2)), %правило 11
%    следовательно((Национальность=норвежец,Цвет2=голубой),соседи(Номер,Номер2)), %правило 14
%    следовательно((Национальность2=норвежец,Цвет=голубой),соседи(Номер,Номер2)), %правило 14
    следовательно((Национальность=англичанин,Цвет2=голубой),соседи(Номер,Номер2)), %правило 14
    следовательно((Национальность2=англичанин,Цвет=голубой),соседи(Номер,Номер2)), %правило 14
    непротиворечит([Номер,Цвет,Национальность,Животное,Пойло,Сигареты],Остальные).

вывод_списка([]).
вывод_списка([Г|Х]):-
    write(Г),nl,
    вывод_списка(Х).

решение:-
    решение(СписокДомов,[[1,2,3,4,5],[красный,зеленый,бежевый,желтый,голубой],[англичанин,испанец,украинец,норвежец,японец],[собака,улитки,лиса,лошадь,зебра],[кофе,чай,молоко,'апельсиновый сок',вода],['Уинстон','Кул','Честерфилд','Лаки Страйк','Парламент']]),
    вывод_списка(СписокДомов).

работает:
Цитата

?- решение.
[1, бежевый, норвежец, улитки, вода, Уинстон]
[2, зеленый, испанец, собака, кофе, Честерфилд]
[3, голубой, японец, лиса, молоко, Парламент]
[4, красный, англичанин, лошадь, апельсиновый сок, Лаки Страйк]
[5, желтый, украинец, зебра, чай, Кул]

Yes
?-  

а при норвежце сопоставлений не находит.

Это сообщение отредактировал(а) Artemios - 23.12.2006, 23:35


--------------------
fib = 1: 1: [ x+y | (x,y) <- zip fib (tail fib) ]
PM MAIL   Вверх
MacTep
Дата 24.12.2006, 02:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Слушай, а объясни, плиз, как им пользоваться, этим языком? smile Я установил сам SWI-Prolog. Установил SWI-Prolog-Editor. И не понимаю. Захожу, загружаю файл программы. Набираю "решение" и ни фига не работает. Говорит, что нет такой функции... smile


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Artemios
Дата 24.12.2006, 03:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 14.8.2006
Где: Саратов, Россия

Репутация: 2
Всего: 50



Берешь мой пример (тот, что код без подсветки), сохраняешь в файл с расширением pl, например logic.pl .

Если SWI-Prolog используешь под Linux-ом:
в консоли: 
$     cd <путь к директории с нужным файлом>
$     pl 
?-    [logic].
?-    решение.

Если под Windows-ом:
запускаешь swi-prolog, в меню file->consult и ищешь/выбираешь свой файл logic.pl .
после этого можешь набирать в пролог-консоли
?-   решение.

либо после открытия пролога сразу в пролог-консоли:
?- consult('полный путь к файлу logic.pl').
?- решение.

Да, в винде по умолчанию расширение *.pl ассоциируется с swi-prolog -ом, поэтому можно даже не открывая заранее пролог, двойной щелчок по файлу logic.pl -- пролог сам уже откроется с загруженной в БД нашей программой, и в консоли сразу пишешь:
?-  решение.

P.S. Только знаки ?- писать не надо -- это я показываю приглашение интерпретатора.


--------------------
fib = 1: 1: [ x+y | (x,y) <- zip fib (tail fib) ]
PM MAIL   Вверх
MacTep
Дата 24.12.2006, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

Репутация: нет
Всего: 4



Спасибо большое. smile Поднимаю репутацию. За терпение, за решение двух задач. За непомерную помочь. Ты единственный, кто согласился помочь  помочь делом, а не словом. smile


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Artemios
Дата 24.12.2006, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 14.8.2006
Где: Саратов, Россия

Репутация: 2
Всего: 50



Спасибо smile


--------------------
fib = 1: 1: [ x+y | (x,y) <- zip fib (tail fib) ]
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.1068 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.