Prolog — задача 155 лодочные гонки

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

      Задача:

      Четверо владельцев лодок решили провести гонки из четырех заездов, меняясь в каждом заезде лодками.
      1) В первом заезде Борис был на лодке Виктора, а во втором Виктор – на лодке Олега.
      2) Петр выиграл третий заезд на своей лодке «Мотылек», причем он выиграл и все остальные заезды.
      3) На «Колибри» во втором заезде плыл Олег, а в четвертом заезде плыл Борис.
      4) В четвертом заезде лодка «Колибри» пришла второй после «Стрижа».
      Кому принадлежала лодка «Шмель»?

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

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

      Решение 1

      DOMAINS
      	имя = борис; виктор; петр; олег
      	название = мотылек; колибри; стриж; шмель
      	призовое_место = integer
      	номер_заезда = integer
      	
      	имена = имя*
      	названия = название*
      	места = призовое_место*
      	номера = номер_заезда*
      	
      	структура_гипотезы = заезд(номер_заезда, имя, название, призовое_место); владелец(имя, название)
      	гипотеза = структура_гипотезы*
      	
      	гипотезы = гипотеза*
      PREDICATES
      	nondeterm возможное_название(название)
      	nondeterm возможное_имя(имя)
      	nondeterm возможное_место(призовое_место)
      
      	nondeterm генерация_заезда(номер_заезда, гипотеза, гипотеза)
      	nondeterm генерация_гипотезы(гипотеза)
      	
      	nondeterm не_ездил_на_такой_лодке(имя, название, гипотеза)
      	
      	nondeterm выбрать_из(имя, имена, имена)
      	nondeterm выбрать_из(название, названия, названия)
      	nondeterm выбрать_из(призовое_место, места, места)
      	nondeterm выбрать_из(номер_заезда, номера, номера)
      	
      	nondeterm входит_в(структура_гипотезы, гипотеза)
      	nondeterm входит_в(имя, имена)
      	
      	nondeterm проверка_гипотезы(гипотеза)
      	
      	nondeterm генерация_проверка(гипотеза)
      	nondeterm решение(имена)
      	
      	nondeterm имена_шмеля(имена, гипотезы)
      	
      	nondeterm имена_без_повторов(имена, имена)
      CLAUSES
      	выбрать_из(Элемент, [Элемент|ОстальныеЭлементы], ОстальныеЭлементы).
          	выбрать_из(Элемент, [ПервыйЭлемент|ОстальныеЭлементы], [ПервыйЭлемент|ОстатокРезультата]):-
              	выбрать_из(Элемент, ОстальныеЭлементы, ОстатокРезультата).
              	
              входит_в(ПервыйЭлемент, [ПервыйЭлемент|_ОстальныеЭлементы]). 
         	входит_в(ПервыйЭлемент, [_ПервыйЭлемент|ОстальныеЭлементы]):- 
             		входит_в(ПервыйЭлемент, ОстальныеЭлементы).
      /*	
             	объединение_списков([], Список2, Список2).
         	объединение_списков([ПервыйЭлемент|ОстальныеЭлементы], Список2, [ПервыйЭлемент|ОбъединениеОстальных]):-
             		объединение_списков(ОстальныеЭлементы, Список2, ОбъединениеОстальных).
      */
      	возможное_название(мотылек).
      	возможное_название(колибри).
      	возможное_название(стриж).
      	возможное_название(шмель).
      	
      	возможное_имя(борис).
      	возможное_имя(виктор).
      	возможное_имя(петр).
      	возможное_имя(олег).
      	
      	возможное_место(1).
      	возможное_место(2).
      	возможное_место(3).
      	возможное_место(4).
      	
      	не_ездил_на_такой_лодке(Имя, Название, Заезды):-
      		входит_в(заезд(_, Имя, Название, _), Заезды), !, fail.
      	не_ездил_на_такой_лодке(_, _, _).
      	
      	генерация_заезда(НомерЗаезда, [
      		заезд(НомерЗаезда, борис, ЛодкаБориса, МестоБориса),
      		заезд(НомерЗаезда, виктор, ЛодкаВиктора, МестоВиктора),
      		заезд(НомерЗаезда, петр, ЛодкаПетра, МестоПетра),
      		заезд(НомерЗаезда, олег, ЛодкаОлега, МестоОлега)
      		| ПредыдущиеЗаезды
      	], ПредыдущиеЗаезды):-
      		Лодки = [мотылек, колибри, стриж, шмель],
      		Места = [1,2,3,4],
      		
      		выбрать_из(ЛодкаБориса, Лодки, ЛодкиВиктораПетраОлега),
      		выбрать_из(ЛодкаВиктора, ЛодкиВиктораПетраОлега, ЛодкиПетраОлега),
      		выбрать_из(ЛодкаПетра, ЛодкиПетраОлега, [ЛодкаОлега]),
      		
      		выбрать_из(МестоБориса, Места, МестаВиктораПетраОлега),
      		выбрать_из(МестоВиктора, МестаВиктораПетраОлега, МестаПетраОлега),
      		выбрать_из(МестоПетра, МестаПетраОлега, [МестоОлега]),
      		
      		не_ездил_на_такой_лодке(борис, ЛодкаБориса, ПредыдущиеЗаезды),
      		не_ездил_на_такой_лодке(виктор, ЛодкаВиктора, ПредыдущиеЗаезды),
      		не_ездил_на_такой_лодке(петр, ЛодкаПетра, ПредыдущиеЗаезды),
      		не_ездил_на_такой_лодке(олег, ЛодкаОлега, ПредыдущиеЗаезды).
      		
      		
      	генерация_гипотезы(
      	[
      		владелец(борис, ЛодкаБориса),
      		владелец(виктор, ЛодкаВиктора),
      		владелец(петр, ЛодкаПетра), 
      		владелец(олег, ЛодкаОлега),
      		
      		заезд(1, борис, ЛодкаБориса_1, МестоБориса_1), 
      		заезд(1, виктор, ЛодкаВиктора_1, МестоВиктора_1),
      		заезд(1, петр, ЛодкаПетра_1, МестоПетра), % Петр выиграл  ... и все остальные заезды.
      		заезд(1, олег, ЛодкаОлега_1, МестоОлега_1),
      		
      		заезд(2, борис, ЛодкаБориса_2, МестоБориса_2),
      		заезд(2, виктор, ЛодкаВиктора_2, МестоВиктора_2), 
      		заезд(2, петр, ЛодкаПетра_2, МестоПетра), % Петр выиграл  ... и все остальные заезды.
      		заезд(2, олег, ЛодкаОлега_2, МестоОлега_2),
      		
      		заезд(3, борис, ЛодкаБориса_3, МестоБориса_3),
      		заезд(3, виктор, ЛодкаВиктора_3, МестоВиктора_3),
      		заезд(3, петр, ЛодкаПетра_3, МестоПетра), % , причем он выиграл и все остальные заезды.
      		заезд(3, олег, ЛодкаОлега_3, МестоОлега_3),
      		
      		заезд(4, борис, ЛодкаБориса_4, МестоБориса_4),
      		заезд(4, виктор, ЛодкаВиктора_4, МестоВиктора_4),
      		заезд(4, петр, ЛодкаПетра_4, МестоПетра), % Петр выиграл  ... и все остальные заезды.
      		заезд(4, олег, ЛодкаОлега_4, МестоОлега_4)
      	]):-
      		% генерация владельцев
      		% Петр выиграл третий заезд на своей лодке «Мотылек»
      		ЛодкаПетра = мотылек,
      		ЛодкиБорисаВиктораОлега = [колибри, стриж, шмель],
      		выбрать_из(ЛодкаБориса, ЛодкиБорисаВиктораОлега, ЛодкиВиктораОлега),
      		выбрать_из(ЛодкаВиктора, ЛодкиВиктораОлега, [ЛодкаОлега]),
      		
      		%генерация лодок для всех заплывов
      		Лодки = [колибри, стриж, шмель, мотылек],
      		% 1
      		ЛодкаБориса_1 = ЛодкаВиктора, % В первом заезде Борис был на лодке Виктора
      		выбрать_из(ЛодкаБориса_1, Лодки, ЛодкиВиктораПетраОлега_1),
      		
      		выбрать_из(ЛодкаВиктора_1, ЛодкиВиктораПетраОлега_1, ЛодкиПетраОлега_1),
      		выбрать_из(ЛодкаПетра_1, ЛодкиПетраОлега_1, [ЛодкаОлега_1]),
      		% 2
      		ЛодкаОлега_2 = колибри, % На «Колибри» во втором заезде плыл Олег,
      		ЛодкиВиктораБорисаПетра_2 = [стриж, шмель, мотылек],
      		
      		ЛодкаВиктора_2 = ЛодкаОлега, % а во втором Виктор – на лодке Олега.
      		выбрать_из(ЛодкаВиктора_2, ЛодкиВиктораБорисаПетра_2, ЛодкиБорисаПетра_2),
      		
      		выбрать_из(ЛодкаБориса_2, ЛодкиБорисаПетра_2, [ЛодкаПетра_2]),
      		% 3 
      		ЛодкаПетра_3 = ЛодкаПетра, % Петр выиграл третий заезд на своей лодке ...
      		выбрать_из(ЛодкаПетра_3, Лодки, ЛодкиБорисаВиктораОлега_3),
      		
      		выбрать_из(ЛодкаБориса_3, ЛодкиБорисаВиктораОлега_3, ЛодкиВиктораОлега_3),
      		выбрать_из(ЛодкаВиктора_3, ЛодкиВиктораОлега_3, [ЛодкаОлега_3]),
      		
      		% 4
      		ЛодкаБориса_4 = колибри, % На «Колибри» ... а в четвертом заезде плыл Борис.
      		ЛодкиВиктораПетраОлега_4 = [стриж, шмель, мотылек],
      		выбрать_из(ЛодкаВиктора_4, ЛодкиВиктораПетраОлега_4, ЛодкиПетраОлега_4),
      		выбрать_из(ЛодкаПетра_4, ЛодкиПетраОлега_4, [ЛодкаОлега_4]),
      		
      		% генерация мест для всех заплывов
      		МестоПетра = 1, % Петр выиграл  ... и все остальные заезды.
      		МестаБорисаВиктораОлега = [2,3,4],
      		выбрать_из(МестоБориса_1, МестаБорисаВиктораОлега, МестаВиктораОлега_1),
      		выбрать_из(МестоВиктора_1, МестаВиктораОлега_1, [МестоОлега_1]),
      		
      		выбрать_из(МестоБориса_2, МестаБорисаВиктораОлега, МестаВиктораОлега_2),
      		выбрать_из(МестоВиктора_2, МестаВиктораОлега_2, [МестоОлега_2]),
      		
      		выбрать_из(МестоБориса_3, МестаБорисаВиктораОлега, МестаВиктораОлега_3),
      		выбрать_из(МестоВиктора_3, МестаВиктораОлега_3, [МестоОлега_3]),
      		
      		выбрать_из(МестоБориса_4, МестаБорисаВиктораОлега, МестаВиктораОлега_4),
      		выбрать_из(МестоВиктора_4, МестаВиктораОлега_4, [МестоОлега_4]),
      		
      		% каждый раз они плавали на новых лодках
      		NOT(ЛодкаБориса_1 = ЛодкаБориса_2), NOT(ЛодкаБориса_1 = ЛодкаБориса_3), NOT(ЛодкаБориса_1 = ЛодкаБориса_4), 
      		NOT(ЛодкаБориса_2 = ЛодкаБориса_3), NOT(ЛодкаБориса_2 = ЛодкаБориса_4), 
      		NOT(ЛодкаБориса_3 = ЛодкаБориса_4), 
      		
      		NOT(ЛодкаВиктора_1 = ЛодкаВиктора_2), NOT(ЛодкаВиктора_1 = ЛодкаВиктора_3), NOT(ЛодкаВиктора_1 = ЛодкаВиктора_4),
      		NOT(ЛодкаВиктора_2 = ЛодкаВиктора_3), NOT(ЛодкаВиктора_2 = ЛодкаВиктора_4),
      		NOT(ЛодкаВиктора_3 = ЛодкаВиктора_4), 
      		
      		NOT(ЛодкаПетра_1 = ЛодкаПетра_2), NOT(ЛодкаПетра_1 = ЛодкаПетра_3), NOT(ЛодкаПетра_1 = ЛодкаПетра_4),
      		NOT(ЛодкаПетра_2 = ЛодкаПетра_3), NOT(ЛодкаПетра_2 = ЛодкаПетра_4),
      		NOT(ЛодкаПетра_3 = ЛодкаПетра_4),
      		
      		NOT(ЛодкаОлега_1 = ЛодкаОлега_2), NOT(ЛодкаОлега_1 = ЛодкаОлега_3), NOT(ЛодкаОлега_1 = ЛодкаОлега_4), 
      		NOT(ЛодкаОлега_2 = ЛодкаОлега_3), NOT(ЛодкаОлега_2 = ЛодкаОлега_4), 
      		NOT(ЛодкаОлега_3 = ЛодкаОлега_4).
      		
      	проверка_гипотезы(Гипотеза):-
      		входит_в(заезд(4, _, колибри, 2), Гипотеза),
      		входит_в(заезд(4, _, стриж, 1), Гипотеза).
      		
      	генерация_проверка(Гипотеза):-
      		генерация_гипотезы(Гипотеза),
      		проверка_гипотезы(Гипотеза).
      		
      	имена_шмеля([], []):-!.
      	имена_шмеля([ПервоеИмя|ОстальныеИмена], [ПерваяГипотеза|ОстальныеГипотезы]):-
      		входит_в(владелец(ПервоеИмя, шмель), ПерваяГипотеза),
      		имена_шмеля(ОстальныеИмена, ОстальныеГипотезы).
      		
      	решение(ИменаБезПовторов):- %Кому принадлежала лодка «Шмель»?
      		findall(Гипотеза, генерация_проверка(Гипотеза), Гипотезы),
      		имена_шмеля(Имена, Гипотезы),
      		имена_без_повторов(Имена, ИменаБезПовторов).
      		
      	имена_без_повторов([], []):-!.
      	имена_без_повторов([ПервоеИмя|ОстальныеИмена], ОстальныеИменаБезПовторов):-
      		входит_в(ПервоеИмя, ОстальныеИмена), !,
      		имена_без_повторов(ОстальныеИмена, ОстальныеИменаБезПовторов).
      	имена_без_повторов([ПервоеИмя|ОстальныеИмена], [ПервоеИмя|ОстальныеИменаБезПовторов]):-
      		имена_без_повторов(ОстальныеИмена, ОстальныеИменаБезПовторов).		
      GOAL
      	
      	
      	/*Лодки = [мотылек, колибри, стриж, шмель],
      	выбрать_из(ЛодкаБориса, Лодки, ЛодкиВиктораПетраОлега).*/
      	
      	% генерация_заезда(1, Заезд1, [])
      	решение(ВозможныеВладельцыШмеля).
      

      Решение 2

      DOMAINS
      	имя = борис; виктор; петр; олег
      	название = мотылек; колибри; стриж; шмель
      	призовое_место = integer
      	номер_заезда = integer
      	
      	имена = имя*
      	названия = название*
      	места = призовое_место*
      	номера = номер_заезда*
      	
      	структура_гипотезы = заезд(номер_заезда, имя, название, призовое_место); владелец(имя, название)
      	гипотеза = структура_гипотезы*
      	
      	гипотезы = гипотеза*
      PREDICATES
      	nondeterm генерация_гипотезы(гипотеза)
      	
      	nondeterm выбрать_из(название, названия, названия)
      	nondeterm выбрать_из(призовое_место, места, места)
      	nondeterm выбрать_из(номер_заезда, номера, номера)
      	
      	nondeterm входит_в(структура_гипотезы, гипотеза)
      	nondeterm входит_в(имя, имена)
      	
      	nondeterm проверка_гипотезы(гипотеза)
      	
      	nondeterm генерация_проверка(гипотеза)
      	nondeterm решение(имена)
      	
      	nondeterm имена_шмеля(имена, гипотезы)
      	
      	nondeterm имена_без_повторов(имена, имена)
      CLAUSES
      	выбрать_из(Элемент, [Элемент|ОстальныеЭлементы], ОстальныеЭлементы).
          	выбрать_из(Элемент, [ПервыйЭлемент|ОстальныеЭлементы], [ПервыйЭлемент|ОстатокРезультата]):-
              	выбрать_из(Элемент, ОстальныеЭлементы, ОстатокРезультата).
              	
              входит_в(ПервыйЭлемент, [ПервыйЭлемент|_ОстальныеЭлементы]). 
         	входит_в(ПервыйЭлемент, [_ПервыйЭлемент|ОстальныеЭлементы]):- 
             		входит_в(ПервыйЭлемент, ОстальныеЭлементы).
      
      	генерация_гипотезы(
      	[
      		владелец(борис, ЛодкаБориса),
      		владелец(виктор, ЛодкаВиктора),
      		владелец(петр, ЛодкаПетра), 
      		владелец(олег, ЛодкаОлега),
      		
      		заезд(1, борис, ЛодкаБориса_1, МестоБориса_1), 
      		заезд(1, виктор, ЛодкаВиктора_1, МестоВиктора_1),
      		заезд(1, петр, ЛодкаПетра_1, МестоПетра), % Петр выиграл  ... и все остальные заезды.
      		заезд(1, олег, ЛодкаОлега_1, МестоОлега_1),
      		
      		заезд(2, борис, ЛодкаБориса_2, МестоБориса_2),
      		заезд(2, виктор, ЛодкаВиктора_2, МестоВиктора_2), 
      		заезд(2, петр, ЛодкаПетра_2, МестоПетра), % Петр выиграл  ... и все остальные заезды.
      		заезд(2, олег, ЛодкаОлега_2, МестоОлега_2),
      		
      		заезд(3, борис, ЛодкаБориса_3, МестоБориса_3),
      		заезд(3, виктор, ЛодкаВиктора_3, МестоВиктора_3),
      		заезд(3, петр, ЛодкаПетра_3, МестоПетра), % , причем он выиграл и все остальные заезды.
      		заезд(3, олег, ЛодкаОлега_3, МестоОлега_3),
      		
      		заезд(4, борис, ЛодкаБориса_4, МестоБориса_4),
      		заезд(4, виктор, ЛодкаВиктора_4, МестоВиктора_4),
      		заезд(4, петр, ЛодкаПетра_4, МестоПетра), % Петр выиграл  ... и все остальные заезды.
      		заезд(4, олег, ЛодкаОлега_4, МестоОлега_4)
      	]):-
      		% генерация владельцев
      		% Петр выиграл третий заезд на своей лодке «Мотылек»
      		ЛодкаПетра = мотылек,
      		ЛодкиБорисаВиктораОлега = [колибри, стриж, шмель],
      		выбрать_из(ЛодкаБориса, ЛодкиБорисаВиктораОлега, ЛодкиВиктораОлега),
      		выбрать_из(ЛодкаВиктора, ЛодкиВиктораОлега, [ЛодкаОлега]),
      		
      		%генерация лодок для всех заплывов
      		Лодки = [колибри, стриж, шмель, мотылек],
      		% 1
      		ЛодкаБориса_1 = ЛодкаВиктора, % В первом заезде Борис был на лодке Виктора
      		выбрать_из(ЛодкаБориса_1, Лодки, ЛодкиВиктораПетраОлега_1),
      		
      		выбрать_из(ЛодкаВиктора_1, ЛодкиВиктораПетраОлега_1, ЛодкиПетраОлега_1),
      		выбрать_из(ЛодкаПетра_1, ЛодкиПетраОлега_1, [ЛодкаОлега_1]),
      		% 2
      		ЛодкаОлега_2 = колибри, % На «Колибри» во втором заезде плыл Олег,
      		ЛодкиВиктораБорисаПетра_2 = [стриж, шмель, мотылек],
      		
      		ЛодкаВиктора_2 = ЛодкаОлега, % а во втором Виктор – на лодке Олега.
      		выбрать_из(ЛодкаВиктора_2, ЛодкиВиктораБорисаПетра_2, ЛодкиБорисаПетра_2),
      		
      		выбрать_из(ЛодкаБориса_2, ЛодкиБорисаПетра_2, [ЛодкаПетра_2]),
      		% 3 
      		ЛодкаПетра_3 = ЛодкаПетра, % Петр выиграл третий заезд на своей лодке ...
      		выбрать_из(ЛодкаПетра_3, Лодки, ЛодкиБорисаВиктораОлега_3),
      		
      		выбрать_из(ЛодкаБориса_3, ЛодкиБорисаВиктораОлега_3, ЛодкиВиктораОлега_3),
      		выбрать_из(ЛодкаВиктора_3, ЛодкиВиктораОлега_3, [ЛодкаОлега_3]),
      		
      		% 4
      		ЛодкаБориса_4 = колибри, % На «Колибри» ... а в четвертом заезде плыл Борис.
      		ЛодкиВиктораПетраОлега_4 = [стриж, шмель, мотылек],
      		выбрать_из(ЛодкаВиктора_4, ЛодкиВиктораПетраОлега_4, ЛодкиПетраОлега_4),
      		выбрать_из(ЛодкаПетра_4, ЛодкиПетраОлега_4, [ЛодкаОлега_4]),
      		
      		% генерация мест для всех заплывов
      		МестоПетра = 1, % Петр выиграл  ... и все остальные заезды.
      		МестаБорисаВиктораОлега = [2,3,4],
      		выбрать_из(МестоБориса_1, МестаБорисаВиктораОлега, МестаВиктораОлега_1),
      		выбрать_из(МестоВиктора_1, МестаВиктораОлега_1, [МестоОлега_1]),
      		
      		выбрать_из(МестоБориса_2, МестаБорисаВиктораОлега, МестаВиктораОлега_2),
      		выбрать_из(МестоВиктора_2, МестаВиктораОлега_2, [МестоОлега_2]),
      		
      		выбрать_из(МестоБориса_3, МестаБорисаВиктораОлега, МестаВиктораОлега_3),
      		выбрать_из(МестоВиктора_3, МестаВиктораОлега_3, [МестоОлега_3]),
      		
      		выбрать_из(МестоБориса_4, МестаБорисаВиктораОлега, МестаВиктораОлега_4),
      		выбрать_из(МестоВиктора_4, МестаВиктораОлега_4, [МестоОлега_4]),
      		
      		% каждый раз они плавали на новых лодках
      		NOT(ЛодкаБориса_1 = ЛодкаБориса_2), NOT(ЛодкаБориса_1 = ЛодкаБориса_3), NOT(ЛодкаБориса_1 = ЛодкаБориса_4), 
      		NOT(ЛодкаБориса_2 = ЛодкаБориса_3), NOT(ЛодкаБориса_2 = ЛодкаБориса_4), 
      		NOT(ЛодкаБориса_3 = ЛодкаБориса_4), 
      		
      		NOT(ЛодкаВиктора_1 = ЛодкаВиктора_2), NOT(ЛодкаВиктора_1 = ЛодкаВиктора_3), NOT(ЛодкаВиктора_1 = ЛодкаВиктора_4),
      		NOT(ЛодкаВиктора_2 = ЛодкаВиктора_3), NOT(ЛодкаВиктора_2 = ЛодкаВиктора_4),
      		NOT(ЛодкаВиктора_3 = ЛодкаВиктора_4), 
      		
      		NOT(ЛодкаПетра_1 = ЛодкаПетра_2), NOT(ЛодкаПетра_1 = ЛодкаПетра_3), NOT(ЛодкаПетра_1 = ЛодкаПетра_4),
      		NOT(ЛодкаПетра_2 = ЛодкаПетра_3), NOT(ЛодкаПетра_2 = ЛодкаПетра_4),
      		NOT(ЛодкаПетра_3 = ЛодкаПетра_4),
      		
      		NOT(ЛодкаОлега_1 = ЛодкаОлега_2), NOT(ЛодкаОлега_1 = ЛодкаОлега_3), NOT(ЛодкаОлега_1 = ЛодкаОлега_4), 
      		NOT(ЛодкаОлега_2 = ЛодкаОлега_3), NOT(ЛодкаОлега_2 = ЛодкаОлега_4), 
      		NOT(ЛодкаОлега_3 = ЛодкаОлега_4).
      		
      	проверка_гипотезы(Гипотеза):-
      		входит_в(заезд(4, _, колибри, 2), Гипотеза),
      		входит_в(заезд(4, _, стриж, 1), Гипотеза).
      		
      	генерация_проверка(Гипотеза):-
      		генерация_гипотезы(Гипотеза),
      		проверка_гипотезы(Гипотеза).
      		
      	имена_шмеля([], []):-!.
      	имена_шмеля([ПервоеИмя|ОстальныеИмена], [ПерваяГипотеза|ОстальныеГипотезы]):-
      		входит_в(владелец(ПервоеИмя, шмель), ПерваяГипотеза),
      		имена_шмеля(ОстальныеИмена, ОстальныеГипотезы).
      		
      	решение(ИменаБезПовторов):- %Кому принадлежала лодка «Шмель»?
      		findall(Гипотеза, генерация_проверка(Гипотеза), Гипотезы),
      		имена_шмеля(Имена, Гипотезы),
      		имена_без_повторов(Имена, ИменаБезПовторов).
      		
      	имена_без_повторов([], []):-!.
      	имена_без_повторов([ПервоеИмя|ОстальныеИмена], ОстальныеИменаБезПовторов):-
      		входит_в(ПервоеИмя, ОстальныеИмена), !,
      		имена_без_повторов(ОстальныеИмена, ОстальныеИменаБезПовторов).
      	имена_без_повторов([ПервоеИмя|ОстальныеИмена], [ПервоеИмя|ОстальныеИменаБезПовторов]):-
      		имена_без_повторов(ОстальныеИмена, ОстальныеИменаБезПовторов).		
      GOAL
      	
      	
      	/*Лодки = [мотылек, колибри, стриж, шмель],
      	выбрать_из(ЛодкаБориса, Лодки, ЛодкиВиктораПетраОлега).*/
      	
      	% генерация_заезда(1, Заезд1, [])
      	решение(ВозможныеВладельцыШмеля).
      

      Решение 3

      DOMAINS
      	лодка = мотылек; колибри; стриж; шмель
      	имя = борис; виктор; петр; олег
      	номер_заезда = первый; второй; третий; четвертый
      	
      	имена = имя*
      	лодки = лодка*
      	номера = номер_заезда*
      	
      	структура_гипотезы = заезд(номер_заезда, имя, лодка); владелец(имя, лодка)
      	гипотеза = структура_гипотезы*
      constants
      	все_лодки = [мотылек, колибри, стриж, шмель]
      	все_имена = [борис, виктор, петр, олег]
      	все_номера = [первый, второй, третий, четвертый]
      PREDICATES
      	nondeterm входит_в(структура_гипотезы, гипотеза)
      	nondeterm входит_в(имя, имена)
      	nondeterm входит_в(лодка, лодки)
      	nondeterm без_повторов(имена)
      	nondeterm без_повторов(лодки)
      	
      	nondeterm генерация_гипотезы(гипотеза)
      	nondeterm поиск_решения(имя)
      	
      	nondeterm убрать_повторы(имена, имена, имена)
      	nondeterm уникальные_решения(имя)
      CLAUSES
              входит_в(ПервыйЭлемент, [ПервыйЭлемент|_ОстальныеЭлементы]). 
         	входит_в(ПервыйЭлемент, [_ПервыйЭлемент|ОстальныеЭлементы]):- 
             		входит_в(ПервыйЭлемент, ОстальныеЭлементы).
             		
             	без_повторов([]).
          	без_повторов([Первый|Остальные]):-
            		NOT(входит_в(Первый, Остальные)),
            		без_повторов(Остальные).
      
      	генерация_гипотезы(Гипотеза):-
      		входит_в(ЛодкаБориса, все_лодки),
      		входит_в(ЛодкаВиктора, все_лодки),
      		входит_в(ЛодкаОлега, все_лодки),
      	
      	% инициализация по условиям
      		% В первом заезде Борис был на лодке Виктора,  а во втором Виктор – на лодке Олега.
      		ЛодкаБориса_1 = ЛодкаВиктора,
      		ЛодкаВиктора_2 = ЛодкаОлега,
      		
      		% Петр ... третий заезд на своей лодке «Мотылек», 
      		ЛодкаПетра = мотылек,
      		
      		% На «Колибри» во втором заезде плыл Олег, а в четвертом заезде плыл Борис.
      		ЛодкаОлега_2 = колибри,
      		ЛодкаБориса_4 = колибри,
      		
      		% В четвертом заезде лодка «Колибри» пришла второй после «Стрижа».
      		% Петр выиграл третий заезд на своей лодке «Мотылек», причем он выиграл и все остальные заезды.
      		ЛодкаПетра_4 = стриж,
      	
      	% генерация остального
      		без_повторов([ЛодкаПетра, ЛодкаБориса, ЛодкаВиктора, ЛодкаОлега]),
      		
      		входит_в(ЛодкаПетра_1, все_лодки),
      		входит_в(ЛодкаВиктора_1, все_лодки),
      		входит_в(ЛодкаОлега_1, все_лодки),
      		без_повторов([ЛодкаПетра_1, ЛодкаБориса_1, ЛодкаВиктора_1, ЛодкаОлега_1]),
      		
      		входит_в(ЛодкаПетра_2, все_лодки),
      		входит_в(ЛодкаБориса_2, все_лодки),
      		без_повторов([ЛодкаПетра_2, ЛодкаБориса_2, ЛодкаВиктора_2, ЛодкаОлега_2]),
      		
      		входит_в(ЛодкаПетра_3, все_лодки),
      		входит_в(ЛодкаБориса_3, все_лодки),
      		входит_в(ЛодкаВиктора_3, все_лодки),
      		входит_в(ЛодкаОлега_3, все_лодки),
      		без_повторов([ЛодкаПетра_3, ЛодкаБориса_3, ЛодкаВиктора_3, ЛодкаОлега_3]),
      		
      		входит_в(ЛодкаВиктора_4, все_лодки),
      		входит_в(ЛодкаОлега_4, все_лодки),
      		без_повторов([ЛодкаПетра_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)
      		].
      	
      	поиск_решения(ВладелецШмеля):-
      		генерация_гипотезы(Гипотеза),
      		входит_в(владелец(ВладелецШмеля, шмель), Гипотеза).
      		
      	убрать_повторы([], Буфер, БезПовторов):-
            		БезПовторов = Буфер.
          	убрать_повторы([ПервыйЭлемент|ОстальныеЭлементы], Буфер, БезПовторов):-
            		входит_в(ПервыйЭлемент, Буфер), 
            		убрать_повторы(ОстальныеЭлементы, Буфер, БезПовторов).
          	убрать_повторы([ПервыйЭлемент|ОстальныеЭлементы], Буфер, БезПовторов):-
            		NOT(входит_в(ПервыйЭлемент, Буфер)),
            		убрать_повторы(ОстальныеЭлементы, [ПервыйЭлемент|Буфер], БезПовторов).
      	
      	уникальные_решения(ВладелецШмеля):-
      		findall(Решение, поиск_решения(Решение), ВсеРешения),
      		убрать_повторы(ВсеРешения, [], РешенияБезПовторов),
      		входит_в(ВладелецШмеля, РешенияБезПовторов).
      GOAL
      	уникальные_решения(ВладелецШмеля).
      

      StudLance.ru

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