Ответ в теме: Логическая задача: предвыборная дискуссия

      Комментарии к записи Ответ в теме: Логическая задача: предвыборная дискуссия отключены
#2787

Утверждения братьев типа «если Жан проголосует на Дюбуа, то Пьер — за Дюпона» могут быть записаны следующим образом:

statement(per, 1, Votes):-
member(vote(zan, dubua), Votes), !,
member(vote(per, dupon), Votes).
statement(per, 1, Votes).

В данном случае единица — номер высказывания Пьера. Тут используется функция member для поиска элемента списка. Мы сначала ищем в списке утверждение о том, что Жан проголосовал за Дюбуа — если находим, то выполняем отсечение и требуем наличие в списке записи, что Пьер голосовал за Дюпона. Отсечение в данном случае является красным, т.к. изменяет ход вычислений — мы поставили его для того, чтобы исключить варианты когда в списке будет найдена запись vote(zan, dubua), но будет отсутствовать vote(per, dupon). Если же первая запись не будет найдена в списке, то данное утверждение не должно накладывать ограничений, поэтому второе правило предиката завершается истиной при любом наборе голосов.

Аналогичным образом могут быть записаны все остальные записи о голосовании:

	statement(per, 1, Votes):-
member(vote(zan, dubua), Votes), !,
member(vote(per, dupon), Votes).
statement(per, 1, Votes).
statement(per, 2, Votes):-
member(vote(zan, duran), Votes), !,
member(vote(per, dubua), Votes).
statement(per, 2, Votes).
statement(per, 3, Votes):-
member(vote(zak, dupon), Votes), !,
member(vote(per, duran), Votes).
statement(per, 3, Votes).
statement(zan, 1, Votes):-
member(vote(per, duran), Votes), !,
NOT(member(vote(zan, dupon), Votes)).
statement(zan, 1, Votes).
statement(zan, 2, Votes):-
member(vote(zak, dubua), Votes), !,
member(vote(zan, dupon), Votes).
statement(zan, 2, Votes).
statement(zak, Votes):-
member(vote(per, dupon), Votes), !,
NOT(member(vote(zak, duran), Votes)).
statement(zak, _Votes).

У Жака всего одно высказывание, поэтому можно обойтись без нумерации. Для остальных избирателей необходимо написать вспомогательное правило, которое применит к сгенерированному решению все ограничения:

	statement(per, Votes):-
statement(per, 1, Votes),
statement(per, 2, Votes),
statement(per, 3, Votes).		
statement(zan, Votes):-
statement(zan, 1, Votes),
statement(zan, 2, Votes).

Остается поместить результаты голосования в список и передать на вход функциям, описывающим ограничения:

	Votes = [
vote(per, PerCandidate),
vote(zan, ZanCandidate),
vote(zak, ZakCandidate)
],
statement(per, Votes),
statement(zan, Votes),
statement(zak, Votes).

Теперь программа вернет лишь одно решение.