Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пролог =).doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
1.69 Mб
Скачать

4.4.2 Поэлементный ввод-вывод списка.

Данный способ может быть организован с помощью рекурсивно определенных процедур.

read_list([X|T]):-write('Введите элемент: '),

read(X), X\==end,!, read_list(T).

end - терм , означающий конец списка.

read_list([]). write_list([]):-nl. write_list([H|T]):-write(H),

tab(2), write_list(T).

Тогда после вызова цели:

?-read_list(L),nl,write('Список='),nl, write_list(L).

Возникает следующий диалог:

Введите элемент: a. Введите элемент: b. Введите элемент: c. Введите элемент: d. Введите элемент: end.

Список= a b c d

5.1 Отсечение.

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

Однако для повышения эффективности выполнения программы, часто требуется вмешаться в перебор, ограничить его, исключить некоторые цели.

Для этой цели в пролог введена специальная конструкция cut - "отсечение", обозначаемая как "!" ( Читается "cut", "кат").

5.1.1 Графическая иллюстрация действия cut.

Графически действие cut можно показать с помощью box-представления логического вывода.

В обычном случае бэктрекинг для правила

G:-A,B,C.

выглядит следующим образом:

Т.е. поиск альтернатив производится для всех целей: G,A,B,C. Заменим B на cut :

Действие cut заключается в отмене поиска альтернатив для целей A,G, стоящих после "!".

Cut подсказывает прологу "закрепить" все решения предшествующие появлению его в предложении. Это означает, что если требуется бэктрекинг, то он приведет к неудаче (fail) без попытки поиска альтернатив.

5.1.2 Пример действия cut.

Пусть база данных выглядит следующим

data(one). data(two). data(three).

Процедура для проверки:

cut_test_a(X):- data(X). cut_test_a('last clouse').

Цель:

?- cut_test_a(X),nl,write(X). one; two; three; last_clouse; no

Теперь поставим cut в правило:

cut_test_b(X):- data(X),!. cut_test_b('last clouse').

Цель:

?-cut_test_b(X),nl,write(X). one; no

Происходит остановка бэктрекинга для левого data и родительского

cut_test_b(X).

Теперь поместим cut между двумя целями.

cut_test_с(X,Y):- data(X), / !,data(Y). cut_test_с('last clouse').

Теперь бэктрекинг не будет для для левого data и родительского cut_test_b(X),но будет для правого data,стоящего после !.

?-cut_test_с(X,Y),nl,write(X-Y). one-one; one-two; one-tree; no