Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1414-Лекции.doc
Скачиваний:
29
Добавлен:
25.12.2018
Размер:
419.84 Кб
Скачать

Vita - родитель sasha

. . .

Предикат fail можно использовать для сопоставления списков лиц по некоторым общим признакам. Например, предположим, что имеется база данных о студентах, где данные о каждом студенте включают фамилию, пол, номер группы и вид спорта, которым он занимается. Допустим эти данные описываются предикатом student следующим образом:

student(familia, pol, gruppa, vid_sporta)

Рассмотрим теперь программу позволяющую выделить студентов - мужчин занимающихся боксом:

/* Программа 6 */

domains

familia, pol, gruppa, vid_sporta = symbol

predicates

student(familia, pol, gruppa, vid_sporta)

student_boxers

goal

write("Студенты-боксёры"), nl, nl, student_boxers

clauses

student("Александров", "м", "А1", "бокс").

student("Борисова", "ж", "А1", "волейбол").

student("Комарова", "м", "А2", "бокс").

student("Морозова", "ж", "А2", "волейбол").

student("Соколова", "ж", "А1", "баскетбол").

/* Правило составления списков студентов-мужчин боксёров */

student_boxers :- student(Familia, "м", Gruppa, "бокс"),

write(Familia, Gruppa), nl, fail.

Правило для составления списков студентов-боксёров требует, чтобы отбирались те студенты, у которых вторым аргументом предиката student является "м" (т.е. мужской пол), а четвёртым аргументом - "бокс". Предикат fail в конце правила обеспечивает выборку всех студентов отвечающих этим требованиям. В результате выполнения программы будет выведен следующий список:

Студенты-боксёры

Александров, А1

Комаров, А2

То же правило можно записать иначе:

student_boxers :- student(Familia, Pol, Gruppa,

Vid_sporta),

Pol="м", Vid_sporta = "бокс",

write(Familia, Gruppa), nl, fail.

Результат программы в данном случае будет тем же. Аналогично можно построить правила для выборки из этой базы данных по другим признакам. Например правило для составления списка всех студентов-спортсменов группы А1 будет выглядеть следующим образом:

student_sportsmens :- student(Familia, Pol, "А1",

Vid_sporta),

write(Familia), nl, fail.

Это же правило можно записать следующим образом:

student_sportsmens :- student(Familia, Pol, Gruppa,

Vid_sporta),

Gruppa="А1", nl, fail.

Рассмотрим теперь программу, демонстрирующую использование отсечения:

/* Программа 7 */

domains

person = symbol

predicates

roditel(person, person)

viborka

otsechenie(person, person)

clauses

roditel(ola, sasha).

roditel(vita, sasha).

roditel(vita, kata).

roditel(sasha, ana).

roditel(sasha, vera).

roditel(vera, kola).

viborka :- roditel(X,Y), write(" ", X, " ", Y), nl,

otsechenie(X, _), !.

otsechenie (X, _) :- X=sasha.

В разделе goal программы в качестве цели стоит предикат viborka. Сама программа позволяет провести выборку из списка. В процессе достижения цели программа обращается к правилу для предиката viborka.

Как можно видеть, первою подцелью этого правила является запрос "Кто чей родитель?":

roditel(X, Y).

Турбо-Пролог унифицирует эту подцель с первым предложением раздела clauses, т.е. связывает значения переменных X и Y следующим образом:

X = ola, Y = sasha

Далее должен выполняться предикат otsechenie при X = ola. Однако правило для этого предиката требует, чтобы X=sasha. Поэтому достижение цели в данном случае невозможно и Турбо-Пролог осуществляет возврат к следующему факту roditel из раздела clauses.

Унификация связывает теперь переменную X со значением vita (X=vita). Поскольку и в этом случае выполнение предиката otsechenie терпит неудачу, вновь будет осуществлён возврат к новому факту раздела clauses и так до тех пор, пока унификация подцели roditel(X, Y) приведёт наконец к X=sasha. В этом случае будет согласовано и правило для предиката otsechenie. Однако в правиле viborka за предикатом otsechenie следует символ отсечения "!", указывающий, что дальнейший поиск решений не нужен, хотя они и могли быть найдены. Поэтому на выходе мы получим лишь часть списка родителей и детей, а именно:

ola, sasha

vita, sasha

vita, kata

sasha, ana

Таким образом, отсечение cut(!) устанавливает "барьер", запрещающий выполнение возврата за поиском других альтернативных решений текущей подцели. Барьером этим, в данном случае, является первый факт, в котором родителем является sasha.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]