Prolog — задача 158 Инженеры отдыхают

  • В этой теме 0 ответов, 1 участник, последнее обновление 2 недели назад сделано Васильев Владимир Сергеевич.
Просмотр 0 веток ответов
  • Автор
    Сообщения
    • #6734
      @admin

      Задача:

      Инженеры отдыхают
      В течение последних четырех лет инженеры
      Еремин, Фомин, Дементьев и Барклая получают
      очередные отпуска в мае, июне, июле и августе.

      Причем если один из них отдыхает в мае, то другой в июне, третий – в июле,
      а четвертый – в августе.

      Каждый из них получал отпуск в разное время.

      Так, в первый год Дементьев отдыхал в июле,
      во второй год Дементьев отдыхал в августе, а Еремин – в мае.
      На третий год Барклая отдыхал в июне, а Фомин на четвертый год – в июле.

      Требуется узнать время отдыха каждого инженера в каждом году.

      Приведенные тут варианты решения очень легко читаются — я думаю, к ним не нужны дополнительные пояснения. Если что-то не понятно — спрашивайте. Наиболее сложные предикаты — входит_в, без_повторов и убрать_повторы подробно разобраны тут. Там же, объясняется как понять findall. Также, понять решение может помочь статья «Решение логических задач на Prolog«.

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

      Решение 1

      domains
        имя = еремин;фомин;дементьев;барклая
        месяц = май;июнь;июль;август
        год = первый; второй; третий; четвертый
       
        структура_гипотезы = отпуск(имя, месяц, год)
        гипотеза = структура_гипотезы*
        
        имена = имя*
        месяцы = месяц*
        годы = год*
      constants
        все_имена = [еремин,фомин,дементьев,барклая]
        все_месяцы = [май,июнь,июль,август]
        все_годы = [первый,второй,третий,четвертый]
      predicates
        nondeterm входит_в(структура_гипотезы, гипотеза)
        nondeterm входит_в(имя, имена)
        nondeterm входит_в(месяц, месяцы)
        nondeterm входит_в(год, годы)
        
        nondeterm без_повторов(месяцы)
        nondeterm без_повторов(годы)
        
        nondeterm генерация_гипотезы(гипотеза)
      clauses
          входит_в(ПервыйЭлемент, [ПервыйЭлемент|_ОстальныеЭлементы]). 
          входит_в(ПервыйЭлемент, [_ПервыйЭлемент|ОстальныеЭлементы]):- 
             входит_в(ПервыйЭлемент, ОстальныеЭлементы).
            
          без_повторов([]).
          без_повторов([Первый|Остальные]):-
            NOT(входит_в(Первый, Остальные)),
            без_повторов(Остальные).
          
          генерация_гипотезы(Гипотеза):-
              входит_в(МесяцЕремина1, все_месяцы), входит_в(МесяцФомина1, все_месяцы),
              входит_в(МесяцБарклая1, все_месяцы),
              
              входит_в(МесяцФомина2, все_месяцы),
              входит_в(МесяцБарклая2, все_месяцы),
              
              входит_в(МесяцЕремина3, все_месяцы), входит_в(МесяцФомина3, все_месяцы),
              входит_в(МесяцДеменьтева3, все_месяцы), 
              
              входит_в(МесяцЕремина4, все_месяцы), 
              входит_в(МесяцДеменьтева4, все_месяцы), входит_в(МесяцБарклая4, все_месяцы),
              
              % Так, в первый год Дементьев отдыхал в июле, 
              МесяцДеменьтева1 = июль,
              % во второй год Дементьев отдыхал в августе, а Еремин – в мае. 
              МесяцДеменьтева2 = август,
              МесяцЕремина2 = май,
              % На третий год Барклая отдыхал в июне, а Фомин на четвертый год – в июле. 
              МесяцБарклая3 = июнь,
              МесяцФомина4 = июль,
              
              % Причем если один из них отдыхает в мае, то другой в июне, третий – в июле, 
              % а четвертый – в августе. 
              без_повторов([МесяцЕремина1, МесяцФомина1, МесяцДеменьтева1, МесяцБарклая1]),
              без_повторов([МесяцЕремина2, МесяцФомина2, МесяцДеменьтева2, МесяцБарклая2]),
              без_повторов([МесяцЕремина3, МесяцФомина3, МесяцДеменьтева3, МесяцБарклая3]),
              без_повторов([МесяцЕремина4, МесяцФомина4, МесяцДеменьтева4, МесяцБарклая4]),
              
              % Каждый из них получал отпуск в разное время.
              без_повторов([МесяцЕремина1, МесяцЕремина2, МесяцЕремина3, МесяцЕремина4]),
              без_повторов([МесяцФомина1, МесяцФомина2, МесяцФомина3, МесяцФомина4]),
              без_повторов([МесяцДеменьтева1, МесяцДеменьтева2, МесяцДеменьтева3, МесяцДеменьтева4]),
              без_повторов([МесяцБарклая1, МесяцБарклая2, МесяцБарклая3, МесяцБарклая4]),
              
          	Гипотеза = [
          	  отпуск(еремин, МесяцЕремина1, первый),
          	  отпуск(фомин, МесяцФомина1, первый),
          	  отпуск(дементьев, МесяцДеменьтева1, первый),
          	  отпуск(барклая, МесяцБарклая1, первый),
          	  
          	  отпуск(еремин, МесяцЕремина2, второй),
          	  отпуск(фомин, МесяцФомина2, второй),
          	  отпуск(дементьев, МесяцДеменьтева2, второй),
          	  отпуск(барклая, МесяцБарклая2, второй),
          	  
          	  отпуск(еремин, МесяцЕремина3, третий),
          	  отпуск(фомин, МесяцФомина3, третий),
          	  отпуск(дементьев, МесяцДеменьтева3, третий),
          	  отпуск(барклая, МесяцБарклая3, третий),
          	  
          	  отпуск(еремин, МесяцЕремина4, четвертый),
          	  отпуск(фомин, МесяцФомина4, четвертый),
          	  отпуск(дементьев, МесяцДеменьтева4, четвертый),
          	  отпуск(барклая, МесяцБарклая4, четвертый)
             ].
      goal 
      	генерация_гипотезы(Гипотеза).
      

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