Нужно ли быть умным? Вы можете выписать действительные шаблоны, их не так уж много:
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.
, потому что они не могут быть доказаны.