Трёхэлементный список упражнений в Прологе - PullRequest
0 голосов
/ 20 апреля 2019

Итак, я очень новичок в Прологе, и мне трудно перейти от традиционного языка программирования к нему, поэтому самые простые упражнения могут сбить меня с толку. Я хочу знать, как я могу создать предикат наподобие тройного (N, N1), в котором N представляет собой список из 3 элементов, который имеет только 1 и / или 0 и / или нулевую переменную (_), и он работает так:

Если N имеет два нуля, переменная будет заменена одним. Если у него есть два, переменная будет заменена на 0. Если N имеет 3 нуля или 3, оно должно вернуть false.

Так, например:

?- triple([1,_,1],R).
R = [1,0,1].

?- triple([1,1,0],R).
R = [1,1,0].

?- triple([_,0,0],R).
R = [1, 0, 0].

?- triple([1,_,0],R).
R = [1, _G396, 0].

?- triple([0,0,0],R).
false.

Спасибо!

1 Ответ

0 голосов
/ 21 апреля 2019

Нужно ли быть умным? Вы можете выписать действительные шаблоны, их не так уж много:

triple([0,0,0], _) :- false.
triple([0,0,1], [0,0,1]).
triple([0,1,0], [0,1,0]).
triple([0,1,1], [0,1,1]).
triple([1,0,0], [1,0,0]).
triple([1,0,1], [1,0,1]).
triple([1,1,0], [1,1,0]).
triple([1,1,1], _) :- false.

Кодирование паттерна мне кажется сложнее.

  • Список из трех элементов, я называю их L1, L2, L3, является приемлемой тройкой, если элементы списка могут быть сопоставлены с допустимым логическим шаблоном, и ..
  • Допустимые шаблоны: A,A,B, A,B,A, B,A,A и ..
  • Шаблоны верны только в том случае, если A и B равны 0 или 1 и отличаются друг от друга.

Работая в обратном направлении, я написал это, но могут быть и лучшие / более простые версии:

valid_a_b(A,B) :-
    (A=0; A=1),
    (B=0; B=1),
    A \= B.

pattern(A,A,B) :- valid_a_b(A,B).
pattern(A,B,A) :- valid_a_b(A,B).
pattern(B,A,A) :- valid_a_b(A,B).

triple([L1,L2,L3],[L1,L2,L3]) :- 
    pattern(L1,L2,L3).

Пролог возьмет triple([0,1,_],R). и попытается найти маршрут, чтобы доказать, что это правда.

Он найдет pattern(A,A,B) и поймет, что A не может принимать 0 и 1, поэтому он не подходит.

Затем он продолжит поиск и найдет pattern(A,B,A), поставит A=0, B=1 и попробует pattern(0,1,0). Убедитесь, что A, B оба равны 0,1 и отличаются друг от друга - да, они есть. Тогда он вернется и скажет R = [0, 1, 0].

(и что он выбрал точку выбора - это верный ответ, но он не исчерпал пространство поиска, хотели бы вы продолжить поиск?).

Нет способа удовлетворить эти шаблоны для списка 0,0,0 или 1,1,1, поэтому те говорят, что false., потому что они не могут быть доказаны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...