Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Prolog
Перезагрузить страницу permute для двух списков
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
Paltosik Paltosik вне форума
Новичок
 
Сообщений: 2
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 06.05.2007
По умолчанию 06.05.2007, 01:14

Никак не могу понять как работает перестановка двух списков. Вот моя задача:
Фамилии врача, инженера, милиционера и пекаря – Докшин, Корнеев, Мареев и Скобелев. О них известно следующее:
а) Корнеев и Докшин – соседи и на работу всегда ездят вместе;
б) Докшин старше Мареева;
в) Корнеев регулярно обыгрывает Скобелева в пинг-понг;
г) пекарь на работу всегда ходит пешком;
д) милиционер не живет рядом с врачом;
е) инженер и милиционер встречались только один раз, когда милиционер оштрафовал инженера за нарушение правил дорожного движения;
ж) милиционер старше и врача, и инженера.
Нужно определить, кто чем занимается.

логическое ее решение и нужные нам предикаты :
1. Пекарь – не Корнеев и не Докшин (а + г).
2. Пара Корнеев + Докшин не может быть ни парой милиционер + врач (а+д), ни парой милиционер + инженер (а + е).
3. Следовательно, пара Корнеев + Докшин может быть только парой врач + инженер (1 + 2).
(этот предикат не описал, но он необязательный вроде)
4. Милиционер старше Докшина и Корнеева (ж + 3)(врача и инженера), а Докшин старше Мареева (б). Следовательно, милиционер – Скобелев, а пекарь – Мареев
5. Пара Корнеев + Скобелев не может быть парой милиционер + инженер (в + е). Следовательно, Корнеев не инженер, а врач. Инженер – Докшин.
Код:
more(X,Y,[X|T]).
more(X,Y,[_|T]):-more(X,Y,T).
remove([X|T],X,T).
remove([H|T],X,[H|T1]):-remove(T,X,T1).
permute([],[]).
permute(X,[H|T]):-remove(X,H,P),permute(P,T).

list1(Y):-permute([DOSHKIN,KORNEEV,MAREEV,SKOBOLEV],Y).
solve(DOSHKIN,KORNEEV,MAREEV,SKOBOLEV):-prof=[PEKAR,VRACH,INZHENER,MILITSIONER],
AGE=[Y1,Y2,Y3,Y4],list1(prof),
not(permute([PEKAR],[KORNEEV])),
not(permute([PEKAR],[DOSHKIN])),
not(permute([KORNEEV,DOSHKIN],[VRACH,MILITSIONER])),
not(permute([KORNEEV,DOSHKIN],[INZHENER,MILITSIONER])),
more(MILITSIONER,VRACH,AGE),more(MILITSIONER,INZHENER,AGE),
more(DOSHKIN,MAREEV,AGE),
not(permute([KORNEEV,SKOBOLEV],[INZHENER,MILITSIONER])).
Моя програмка не работает, пролог выдает просто NO.
Где ошибка пока не пойму, но возникает вопрос будут ли исключаться нужные мне пары ? Например
Код:
not(permute([KORNEEV,DOSHKIN],[INZHENER,MILITSIONER])).
Ответить с цитированием
  (#2 (permalink)) Старый
Винитарх Винитарх вне форума
Специалист
 
Аватар для Винитарх
 
Сообщений: 7,958
Сказал(а) спасибо: 2
Поблагодарили 303 раз(а) в 303 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
По умолчанию 06.05.2007, 21:53

Цитата:
Никак не могу понять как работает перестановка двух списков.
А что Вы вкладываете в эту фразу, какой смысл?
Лучше покажите на простом примере.
Ответить с цитированием
  (#3 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 06.05.2007, 23:05

Перестановка списка, т.е. предикат permute реализован правильно. Его первый аргумент - это входной список, а второй - выходной список, который является списком переставленных элементов первого списка. Либо оба аргумента - входные списки, при этом один является перестановкой другого.

Но при его использовании в данной попытке решения есть проблемы:
Во-первых:
Код:
list1(Y):-permute([DOSHKIN,KORNEEV,MAREEV,SKOBOLEV],Y).
Если Вы имели в виду перестановку конкретных фамилий, то здесь этого не получится, т.к. слова с большой буквы Пролог воспринимает просто как переменные.
Во-вторых, ниже:
Код:
prof=[PEKAR,VRACH,INZHENER,MILITSIONER],
Слева от знака равенства стоит константа, а справа - список переменных, это равенство всегда ложно.
Далее - то, что Корнеев не пекарь можно записать либо с помощью предиката not, либо с помощью какого-либо специального оператора - знака не равно в Вашем Прологе. И т.д.

Вы пишете не в проложном синтаксисе, поэтому Пролог Ваш код не понимает.
Аналитическое решение у Вас хорошее, а вот ход реализации Ваших рассуждений мне, например, не ясен.
Ответить с цитированием
  (#4 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 07.05.2007, 21:13

Вот Ваш способ решения на VIP 5.2:
Код:
domains
sl = string*
predicates
nondeterm remove(sl,string,sl)
nondeterm permute(sl,sl)
nondeterm solve(string,string,string,string)
more(string,string)
clauses
remove([X|T],X,T).
remove([H|T],X,[H|T1]):- remove(T,X,T1).

permute([],[]).
permute(X,[H|T]):- remove(X,H,P),permute(P,T).

solve(DOSHKIN,KORNEEV,MAREEV,SKOBOLEV):-
    Prof=["PEKAR","VRACH","INZHENER","MILITSIONER"],
    permute(Prof, [DOSHKIN,KORNEEV,MAREEV,SKOBOLEV]),
    not(permute(["PEKAR"],[KORNEEV])),
    not(permute(["PEKAR"],[DOSHKIN])),
    not(permute([KORNEEV,DOSHKIN],["VRACH","MILITSIONER"])),
    not(permute([KORNEEV,DOSHKIN],["INZHENER","MILITSIONER"])),
    not(permute([KORNEEV,SKOBOLEV],["INZHENER","MILITSIONER"])),
    more(DOSHKIN,MAREEV).

more("MILITSIONER","VRACH").
more("MILITSIONER","INZHENER").
more("INZHENER",X):- X<>"MILITSIONER".
more("VRACH",X):- X<>"MILITSIONER".
more("PEKAR",_).
more("MILITSIONER","PEKAR").
goal
solve(DOSHKIN,KORNEEV,MAREEV,SKOBOLEV).
Ответ:
Код:
DOSHKIN=INZHENER, KORNEEV=VRACH, MAREEV=PEKAR, SKOBOLEV=MILITSIONER
1 Solution
У Вашего Пролога синтаксис отличается, но суть здесь будет такая же.
Ответить с цитированием
  (#5 (permalink)) Старый
Alison Alison вне форума
Member
 
Сообщений: 4,781
Сказал(а) спасибо: 0
Поблагодарили 119 раз(а) в 116 сообщениях
Регистрация: 17.11.2004
По умолчанию 07.05.2007, 21:44

А так, наверное, по стилю будет ближе к Вашему Прологу:
Код:
domains
refs = reference string
sl = refs*
predicates
nondeterm remove(sl,string,sl)
nondeterm permute(sl,sl)
nondeterm solve(string,string,string,string)
nondeterm more(sl,sl)
check_more(sl)
clauses
more(_,[]).
more([X|T],[X|S]):- more(T,S).
more([_|T],S):- more(T,S).

remove([X|T],X,T).
remove([H|T],X,[H|T1]):- remove(T,X,T1).

permute([],[]).
permute(X,[H|T]):- remove(X,H,P),permute(P,T).

solve(DOSHKIN,KORNEEV,MAREEV,SKOBOLEV):-
    Prof=["PEKAR","VRACH","INZHENER","MILITSIONER"],
    permute(Prof, [DOSHKIN,KORNEEV,MAREEV,SKOBOLEV]),
    not(permute(["PEKAR"],[KORNEEV])),
    not(permute(["PEKAR"],[DOSHKIN])),
    not(permute([KORNEEV,DOSHKIN],["VRACH","MILITSIONER"])),
    not(permute([KORNEEV,DOSHKIN],["INZHENER","MILITSIONER"])),
    not(permute([KORNEEV,SKOBOLEV],["INZHENER","MILITSIONER"])),
    check_more([DOSHKIN,MAREEV]).

check_more([DOSHKIN,MAREEV]):-
    AGE=[_,_,_,_],
    more(AGE,["MILITSIONER","VRACH"]),
    more(AGE,["MILITSIONER","INZHENER"]),
    more(AGE,["PEKAR"]),
    more(AGE,[DOSHKIN,MAREEV]),
    !.
goal
solve(DOSHKIN,KORNEEV,MAREEV,SKOBOLEV).
Ответить с цитированием
Ads.
  (#6 (permalink)) Старый
Paltosik Paltosik вне форума
Новичок
 
Сообщений: 2
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 06.05.2007
По умолчанию 07.05.2007, 22:31

Alison
спасибо за помощь, довел ваше ршение до своего пролога все работает! еще раз благодарю!
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск из двух списков staff Prolog 12 20.10.2011 01:37
Нужно написать программу для слияния двух списков символов Окс Lisp 0 22.05.2011 21:25
Определите функцию same, которая для двух списков находит первый Masha11 Lisp 4 13.01.2011 13:33
Программа на вычисление суммы двух списков S@SORY Вопросы начинающих программистов 0 14.12.2010 19:01
Реализация вычитания двух чисел, представленных в виде списков Regina Вопросы начинающих программистов 0 09.12.2010 20:43
Сравнение двух списков zener Prolog 4 28.10.2010 15:40
Проверка равенства двух списков Sendo Prolog 16 28.10.2010 00:12
Написать программу, которая из двух списков делает один DFK Lisp 7 03.04.2008 09:54
Объединение чётных элементов двух списков Дмитрий_Шишков Prolog 2 18.08.2006 13:23
Сравнение двух списков по элементно(с условием ...) degavi Prolog 15 19.12.2005 14:26
Как объеденить четные и нечетные элементы двух списков Anonymous Prolog 62 03.10.2003 12:29



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов