Если цель поиска задается в самой программе, в разделе goal, то она является внутренней. Само предложение, определяющее цель, может состоять из подцелей, разделенных связками. Предложение, описывающее цель, должно оканчиваться точкой.
При доказательстве внутренней цели система найдет ровно одно решение, удовлетворяющее данный запрос.
Если в качестве связок используется конъюнкция, то ответ будет найден в результате выполнения всей совокупности целевых утверждений.
Вернемся к примеру из главы 1, описывающему дерево родственных отношений (рис. 1.2).
Goal
sister(ann,X),write(”Ann — сестра ”,X), nl
Вначале будет согласован предикат sister и переменная X означена значением pat, затем встроенный предикат write напечатает Ann — сестра pat, затем предикат nl переведет строку, и на этом выполнение программы завершится.
Рассмотрим подробно применение дизъюнкции в качестве связки между подцелями.
Пусть дизъюнкция разделяет подцели в теле правила:
ancestor(X,Y):-
pearent(X,Y);
pearent(X,Z), ancestor(Z,Y).
Конъюнкция связывает сильнее, чем дизъюнкция, поэтому это равносильно
pearent(X,Y);
(pearent(X,Z), ancestor(Z,Y))
и, в свою очередь, равносильно двум правилам:
ancestor(X,Y):-
pearent(X,Y).
ancestor(X,Y):-
pearent(X,Z), ancestor(Z,Y).
Если дизъюнкция разделяет подцели внешней цели:
Goal: sister(ann,X); pearent(X,ann)
то это будет аналогично последовательному выполнению двух разных запросов: вначале система найдет всех, для кого ann сестра, затем родителей ann.
Если бы предыдущий запрос был переформулирован как внутренняя цель (с добавлением предикатов write), то система не стала бы согласовывать цель о родителях ann, так как остановка произошла поcле первого успешного согласования подцели sister.
Из предыдущего примера видно, что свойство внутренней цели находить ровно одно решение не всегда является удобным.