Логическая задача про библиотекарей

В этой теме 5 ответов, 2 участника, последнее обновление Васильев Владимир Сергеевич 11 мес. назад.

  • Автор
    Сообщения
  • #4305
    anastasia.str
    Участник

    Библиотека в нашем микрорайоне открыта по вечерам все дни, кроме субботы и воскресенья. Расписание дежурств пяти библиотекарей составлено так, что каждый вечер дежурят двое,причем ни одна пара не дежурит дважды в неделю,а каждый библиотекарь занят два вечера в неделю.
    Анна и Борис недавно обвенчались и, конечно, очень рады тому, что в один из вечером могут побыть вместе на работе. А Семен и Елена недавно развелись и ни один вечер не дежурят вместе.
    Один из пятерых работает по понедельникам и вторникам. Никто не работает подряд в четверг и пятницу.Один из той пары, которая работает в среду, дежурит в один день из других дней с Дмитрием. Борис занят по четвергам, а Елена по четвергам не дежурит. В какой бы вечер вы бы не пришли, обязательно застанете в библиотеке по крайней мере одного из троицы: Бориса,Дмитрия, Елену.
    Попробуйте восстановить расписание дежурств в библиотеке, если мы подскажем, что Дмитрий дежурит в понедельник.

  • #4306
    Васильев Владимир Сергеевич
    Хранитель

    Здравствуйте. Ваша логическая задача заключается в установлении соответствия между именами и днями недели. Это классический тип задач, который подробно рассмотрен в теме «Решение логических задач на Prolog«. Кроме того, множество примеров с детальным разбором приведено на нашем форуме (примерно 40 задач). Вы читали статью? Смотрели примеры? Пробовали писать код? Что именно не получается?

  • #4312
    anastasia.str
    Участник

    Я попыталась реализовать вот так, но у меня появилась загвоздка с ИЛИ, то есть в один из дней вы сможете увидеть «одного из». Помогите реализовать это:

    main(Duty) :-
        Duty = [_,_,_,_,_],
    	member([ann,_,_], Duty),
        member([ann,borya,_], Duty),
    	member([_,borya,thuersday],Duty),
    	(member([R,_,_],Duty);
    	member([_,R,_],Duty)),
    	(R = lena; R = borya; R = dima),
    	member([_,dima,monday],Duty),
    
    	((member([X,_,monday], Duty),
    	member([X,_,tuesday], Duty));
    	(member([_,X,monday], Duty),
    	member([_,X,tuesday], Duty))),
    
    	member([sem,_,_], Duty),
    	member([_,lena,_], Duty),
    	not(member([sem,lena,_], Duty)),
    
    	member([Guy,Girl,Day],Duty),
    	not(member([Guy,Girl,Day1],Duty)),
    	not(Day1 == Day),
    	member([Guy,_,Day],Duty),
    	member([Guy,_,Day1],Duty),
    	member([_,Girl,Day],Duty),
    	member([_,Girl,Day1],Duty),
    
    	not((member([Y,_,thuersday],Duty),
    	member([Y,_,friday],Duty))),
    	not((member([_,Q,thuersday],Duty),
    	member([_,Q,friday],Duty))),
    
    	member([W,E,wednesday],Duty),
    	(member([W,dima,_],Duty);
    	member([E,dima,_],Duty)),
    
    	not(member([_,lena,thuersday],Duty)).

  • #4313
    Васильев Владимир Сергеевич
    Хранитель

    Не понятно какая часть задачи вызывает затруднения, но я не вижу как вы пытаетесь связать людей с днями. Делать это надо примерно так:

    name(semen).
    name(elena).
    % другие имена ...
    
    solution([
      visit(monday, MondayNames), 
      visit(tuesday, TuesdayNames)
    % другие элементы списка
      ]):-
      % генерация возможных решений.

    Таким образом, к каждому в списке решения вы к каждому дню привяжете набор имен.

    После генерации всех возможных вариантов, необходимо выполнить проверку. Эта часть:

    «В какой бы вечер вы бы не пришли, обязательно застанете в библиотеке по крайней мере одного из троицы: Бориса, Дмитрия, Елену.»

    сводится к тому, что в каждом элементе списка (соответствует дню недели) надо проверить что в списке имен есть одна из трех фамилий (или имен, что там в задаче?). Решение «в лоб» (не универсальное) могло бы выглядеть так:

    check([]):-!.
    check([visit(_Day, Names)|Tail]):-
      member(Names, Name),
      member([boris, dima, elena], Name), !,
      check(Tail).

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

  • #4314
    anastasia.str
    Участник

    а тут в чем ошибка?

    name(lena).
    name(sem).
    name(dima).
    name(borya).
    name(anna).
    
    solution([
      visit(monday, name,name1),
      visit(tuesday, TuesdayNames,TuesdayNames),
      visit(wednesday, WednesdayNames,WednesdayNames),
      visit(thuersday, ThuersdayNames,ThuersdayNames),
      visit(friday,FriayNames,FriayNames)]).
    
    main(visit):-
        member([_,anna,_], solution),
        member([_,borya,anna], solution),
    	member([thuersday,borya,_],solution),
    
    
            %member([[X|L],X,L],Three),
    	%(member([R,_,_],Duty);
    %	member([_,R,_],Duty),
            % R = lena; R = borya; R = dima),
    
    
    	member([monday,dima,_],solution),
    
    	((member([monday,X,_], solution),
    	member([tuesday,X,_], solution));
    	(member([monday,_,X], solution)),
    	member([tuesday,_,X], solution)),
    
    	member([_,sem,_], solution),
    	member([_,_,lena], solution),
    	not(member([_,lena,sem], solution)),
    
    	member([Day,Guy,Girl],solution),
    	not(member([Day1,Guy,Girl],solution)),
    	not(Day1 == Day),
    	member([Day,Guy,_],solution),
    	member([Day1,Guy,_],solution),
    	member([Day,Girl,_],solution),
    	member([Day1,Girl,_],solution),
    
    	not((member([thuersday,Y,_],solution),
    	member([friday,Y,_],solution))),
    	not((member([thuesday,_,Q],solution),
    	member([friday,_,Q],solution))),
    
    	member([wednesday,W,E],solution),
    	(member([_,W,dima],solution);
    	member([_,E,dima],solution)),
    
    	not(member([thuersday,_,lena],solution)).
    
    
    check([]):-!.
    check([visit(_Day, Names,Name)|Tail]):-
      member(Names, Name),
      member([boris, dima, elena], Name), !,
      check(Tail).

    • #4315
      Васильев Владимир Сергеевич
      Хранитель

      В том, что вы не понимаете логическое программирование. Начните знакомство с логической парадигмой с этой статьи: Введение в логическое программирование . Я старался, но не могу помочь вам.

      Сейчас у вас в коде просто бред написан.

Для ответа в этой теме необходимо авторизоваться.