- •Введение
- •1. История Пролога
- •2. Синтаксис и семантика Пролог-программ
- •2.1. Объекты данных1
- •2.2. Декларативный смысл Пролог-программ
- •2.3. Основные определения
- •3. Практическое программирование на Прологе
- •3.1. Структура Пролог-программы
- •3.2. Некоторые предопределенные термы
- •3.3. Свободные и связанные переменные
- •3.4. Внутренняя бд Пролога
- •3.5. Обработка условий и организация циклов в Prolog’е
- •3.5.1. Обработка условия
- •3.5.2. Использование предиката типа repeat
- •3.6. Списки в Прологе
- •3.6.1. Примеры списков
- •3.6.2. Разделение списков на голову и хвост
- •3.6.3. Некоторые полезные программы для работы со списками
- •1. Слияние списков.
- •2. Сортировка списков
- •3.7. Ввод и вывод
- •3.7.1. Файловая система
- •Операции с именами файлов
- •Чтение и запись
- •3.8. Строки и функции работы со строками
- •4. Простенькая экспертная система
- •Игрушечная эс «Кто чем увлекается?»
- •5. Базовые понятия и термины Пролога
- •5.1. Объекты
- •5.2. Внутренние дела Пролога
- •5.3. Что такое шаблоны?
- •5.4. Управление поиском
- •Литература
3.5. Обработка условий и организация циклов в Prolog’е
Два встроенных предиката, очень полезных для обработки условий и организации циклов:
1) Предикат fail искусственно порождает неуспех.
2) Предикат cut (или !) предотвращает бэктрекинг:
p:-p1,p2,!,p3,.. – если достигнуты цели p1 и p2, бэктрениг не осуществляется.
3.5.1. Обработка условия
Пусть a- предикат, который может быть либо успешным либо нет. В случае успеха мы хотим выполнить предикат u, в обратном случае – предикат f.
p:-a,!,u;f.
Можно и так (в случае неуспеха выполняется второе правило для p):
p:-a,!,u.
p:-f.
Пример:
p(A,C,Dplus):-A>=C,!,Dplus=A-C;Dplus=C-A.
Или:
p(A,C,Dplus):-A>=C,!,Dplus=A-C.
p(A,C,Dplus):-Dplus=C-A.
Конечно, наиболее простое решение:
p(A,C,Dplus):-Z:= A-C, Dplus=abs(Z), где abs – встроенная функция.
Если в нашем примере со строками требуется получить все номера строк с длиной не более 45, тогда процедура, решающая эту задачу, будет такой:
get_all_DefStrings:-
input_string(NbS,TS,LS),
LS<=45,
write(NbS,’,’),
fail.
get_all_DefStrings. % или get_all_DefStrings:-!.
3.5.2. Использование предиката типа repeat
Пусть требуется в рамках одного правила предиката pravilo выполнить некоторое множество заведомо успешных предикатов, после чего выполнять некоторое другое множество предикатов, до тех пор, пока справедливо некоторое условие.
Первую и вторую группы предикатов можно,очевидно, обозначить одним предикатом, p1 и p2 соответственно. Пусть p_control – предикат, проверяющий условие, а предикат repeat (который может, очевидно, иметь любое другое имя) записывается в виде следующих двух правил:
repeat.
repeat:-repeat.
Тогда:
pravilo:-p1,repeat,p2,p_control.
Предикат p1 выполнится один раз, предикат же p2 будет выполняться до тех пор, пока p_control неуспешен.
Разберемся, как это происходит. p1 всегда успешен, затем выполняется всегда успешное первое правило предиката repeat и Пролог устанавливает указатель отката на второе правило. Выполняется p2. После неуспеха p_control выполняется второе правило repeat:-repeat, после чего – первое правило, указатель отката устанавливается на второе правило, далее p2, p_control и т.д.
Приведем простой пример использования repeat. Требуется загрузить факты БД со значениями, вводимыми с клавиатуры. Предикат check_cont запрашивает пользователя о разрешении ввода группы значений факта fact, предикат vvod принимает значения.
database
fact(string,string,string)
predicates
repeat
check_cont
vvod
goal
vvod,exit.
clauses
repeat.
repeat:-repeat.
vvod:-
retractall(fact(_,_,_)),
write(“Начинаем процесс ввода значенний”),nl,
repeat,
clearwindow,
write("A?"),readln(A),nl,
write("B?"),readln(B),nl,
write("C?"),readln(C),nl,
assert(fact(A,B,C)),
check_cont.
check_cont:-
write("ВВОДИТЬ ДАЛЕЕ? (Y|N)"),
readchar(Ans),Ans='N',!,
write("Процесс завершен"),readchar(_).
3.6. Списки в Прологе
3.6.1. Примеры списков
domains
list_integer=integer*
list_struct=el2*
el=e(list_integer)
el2=l(integer,symbol)
predicates
p1(list_integer)
p2(list_struct)
goal
L1=[1,2,3,4]
%Списки списков
L2=[e([10,40,50]),e([30,20])]
....................................
%Списки структур
L3=[l(1,"Fortran"),l(2,"Algol"),l(3,"PL/1")],
write("Языки программирования"),nl,
p2(L3),
search(3,L1),
....................................