Листинг 2.2.Использование предиката not

domains

country=symbol

predicates

euro_pair(country,country)

border(country,country)

find_non_border_pair

goal

find_non_border_pair.

clauses

euro_pair("France","Germany").

euro_pair("France","Spain").

euro_pair("France","Italy").

euro_pair("Germany","Spain").

euro_pair("Germany","Italy").

euro_pair("Spain","Italy").

euro_pair("Russia","Finland").

euro_pair("Russia","Poland").

border("France","Germany").

border("France","Spain").

border("France","Italy").

border("Russia","Finland").

border("Russia","Poland").

border("Spain","Germany").

find_non_border_pair:-

* euro_pair(X,Y),

not(border(X,Y)),

not(border(Y,X)),

write("X=",X," Y=",Y),nl,

fail.

1. Как видно из программы наша цель find_non_border_pair означает, что мы хотим найти пары стран, не имеющих общей границы. В программе же представлены только сами пары стран и пары стран, имеющие общие границы.

Вместо того, чтобы выдавать на экран все пары стран с общими границами, а потом визуально искать все пары, не попавшие в этот список, лучше воспользоваться более простым и эффективным средством- предикатом not (отрицанием, то есть недостижением цели). Его пишут в программе как not, чтобы отличить его от логического оператора “ ”.

Если мы хотим вызывать цель многократно, то лучше использовать цель в форме правила, не содержащего в себе данных (нулевой арности) А само правило определить в разделе clauses.

Это полезно, когда для достижения цели надо доказать много разных подцелей, включающих в себе достаточно сложные операции. Это поможет упростить процедуру запросов. При этом такие правила можно создавать “в запас”, а потом их использовать в работе программы.

2.В случае цели без аргументов вне зависимости оттого будете вы использовать внутреннюю или внешнюю цель ответ вы получите только один:

X=Germany Y=Italy

1 Solution

Это объясняется тем, что к предикату find_non_border_pair не могут быть поставлены точки возврата, так как такое утверждение в программе только одно, других просто нет.

Чтобы получить все возможные ответы, надо в теле правила

find_non_border_pair поставить предикат fail,который заставит поставить точки отката у подцели правила euro_pair(X,Y) (cимвол *):

find_non-border_pair:-

*euro_pair(X,Y),

not(border(X,Y)),

not(border(Y,X)),

write(“X=”,X,” Y=”,Y),nl,

fail.

Предикат fail вызывает откат, ибо он всегда неуспешен.

3.Для внешней цели можно обойтись без предиката fail, но тогда в правило надо добавить аргументы find_non_border_pair(X,Y)и не забыть произвести изменения в разделе предикатов –find_non_border_pair(country,country)

4.Предикат not не допускает свободной переменной в подцели, так как для связывания свободной переменной подцель должна быть унифицирована с каким-то предложением и выполнена, то есть переменная должна быть означена до своего использования. Как видите, предикат not позволяет ввести в программу элементы логики.

Например,

Goal: not(border(“France”,”Germany”))

Ответ: False (France и Germany –соседи)


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: