Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное_пособие_флп.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
675.84 Кб
Скачать

2.7.Особенности лп:

- Декларативный характер описания программы приводит к высокой степени независимости отдельных частей программы, каждая из которых реализует отдельную часть решения.

- Возможность работать в обоих направлениях, так как последовательность и способ выполнения программы не фиксируется. На основе исходных данных можно вычислить результат, но также без дополнительного программирования на основе результата можно получить исходные данные.

- Возможность рассмотрения альтернативных решений и поиск всех возможных решений.

2.8 Использование предиката not и

квантификация переменных в подцели с предикатом not

Информация о фактах, которые не являются истинными и об отношениях, которые не соблюдаются, называется отрицательной информацией. Такая информация в явной форме в программе не хранится. Просто считается, что вся информация, которая отсутствует в программе, ложна.

Встроенный предикат not имеет один аргумент. Этим аргументом является подцель, значение истинности которой (после выполнения подцели) заменяется на противоположное.

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

Свободные переменные в предикате not не разрешены, потому что для связывания свободных переменных в подцели подцель должна унифицироваться с каким-либо предложением и выполниться, то есть, если вы используете внутри not переменную, то она должна быть означена до своего использования.

Квантификация переменных в подцели с предикатом not

? not(sister(ann,X)) если Ann не является сестрой X, то предикат sister –неуспешен, а not(sister…)- истина.

В подцели sister(ann,X) переменная X квантифицирована экзистенциально (существует ли некоторый X, для которого Ann является сестрой?)

Переменная X в подцели с отрицанием not(sister(…)) квантифицирована универсально (является ли Ann не сестрой X?То есть для любого X является ли Ann не сестрой X? Для проверки этого положения требуется отыскать только одно значение X, при котором подцель с отрицанием потерпит неудачу.

Квантификация переменных всегда изменяется на противоположную, если фраза подвергается отрицанию.

Рассмотрим задачу, в которой заданы пары европейских государств, часть из которых имеет общие границы. Необходимо определить названия пар государств, не имеющих общих границ.

Предположим, программа для решения этой задачи имеет вид:

Листинг 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 –соседи)