Пролог, о том, как формировать лучшие статьи
У меня есть следующие пункты:
num_parent(adam, X) :- !, X = 0.
num_parent(eve, X) :- !, X = 0.
num_parent(X, 2).
Когда я набрал запрос:
num_parent(eve,X).
Это только возвращает:
X = 0.
что я и хочу
Но когда я набрал этот запрос:
num_parent(X,0).
это только возвращает:
X = adam.
Итак, как я могу изменить предложения, чтобы он вернулся:
X = adam;
X = eve.
Спасибо
2 ответа
Во-первых, попробуйте сформулировать, что вы хотите на простом английском языке. Вы, вероятно, хотите сказать:
У каждого есть два родителя, кроме Адама и Евы, у которых их нет.
Что насчет Лилит? Неважно, давайте придерживаться вашего чтения.
num_parent(Person, 2) :-
dif(Person, adam),
dif(Person, eve).
num_parent(adam, 0).
num_parent(eve, 0).
Как видите, определить это немного громоздко: нужно упомянуть каждого исключительного человека дважды. Легко сделать ошибку.
С if_/3
доступно в library(reif)
для SICStus и SWI вы можете написать более кратко:
num_parent(Person, Num) :-
if_( ( Person = adam ; Person = eve ), Num = 0, Num = 2 ).
А теперь некоторые использует:
?- num_parent(eve, Num).
Num = 0.
?- num_parent(X, 0).
X = adam
; X = eve
; false.
?- num_parent(X, 2).
dif(X, eve),
dif(X, adam).
?- num_parent(lilith, 2).
true.
Только программы возвращаются X = adam
потому что вы вставили разрез !
, Сокращение используется, когда вы нашли правильные правила, и вам не нужно проводить дальнейшие оценки, но оно сокращает все остальные решения.
В твоем случае
num_parent(adam, X) :- !, X = 0.
num_parent(eve, X) :- !, X = 0.
num_parent(_, 2). %replaced num_parent(X, 2) with num_parent(_, 2) to avoid singleton variable
num_parent(X, 0)
только возвращается X = adam
,
Если ты пишешь
num_parent(adam, X) :- X = 0.
num_parent(eve, X) :- !, X = 0.
num_parent(_, 2).
решение будет X = adam
а также X = eve
и в этом случае:
num_parent(adam, X) :- X = 0.
num_parent(eve, X) :- X = 0.
num_parent(_, 2).
решение будет X = adam
, X = eve
а также false
потому что запрос num_parent(X, 0)
не объединяется с num_parent(_, 2)
,
Вы можете лучше увидеть это поведение, используя трассировщик.