Методичні вказівки
Динамічні предикати
Всі факти бази даних за умовчання статичні і Prolog система не дозволяє змінити їй стан [2]. Для додавання або вилучення предикатів з бази даних необхідно відповідні предикати об’явити як динамічні за допомогою вбудованого предикату dynamic(P/A), де P – імя предикату, що може бути змінений, A – його арність.
Особливості роботи з файлами
Використання будь-якого предикату читання з файлу припускає, що файл існує. Щоб запобігти виникненню помилки у разі, якщо файл не існує, слід застосувати предикат exist_file(F), де F – ім’я файлу. Предикат є вдалим, якщо файл F існує.
При читанні даних з файлу іноді необхідна перевірка кінця файлу. У мові Prolog існує атом end_of_file, що дає можливість виконати перевірку кінця файлу після кожного читання. Фрагмент програми, представлений нижче, демонструє подібну перевірку:
p :- read(X), checkread(X).
checkread(end_of_file) :- write(‘Find end of file.’), !.
checkread(X) :- <Обробка терму X>.
Перевірка конкретизації змінної
У програмі іноді важливо визначити стан конкретизації змінної виконання подальших дій [2, 4]. Предикат var(X) є вдалим, якщо X – неконкретизована змінна. Предикат nonvar(X) є вдалим, якщо X – конкретизована змінна. Приклад застосування цих предикатів представлений нижче.
Приклад виконання завдання
Задача: Скласти програму-довідник розкладу руху автобусів. Програма повинна додавати до бази нові маршрути, якщо запит неможливо задовольнити.
% Факти представлені предикатом ruh(S,L),
% де S – назва міста, L – список часу відправлення автобуса
:-dynamic ruh/2, ruhtmp/2.
% У разі виклику з невизначеною назвою міста - pruh(_) - виведення стану розкладу.
pruh(X):-var(X),listing(ruh/2),!.
% У разі виклику з визначеною назвою міста, який присутній у розкладі -
% виведення списку часу відправлення за допомогою процедури writeruh
pruh(X):-ruh(X,L),writeruh(X,L),!.
% Якщо місто не визначено у розкладі:
% - введення часу відправлення ( gettime )
% - отримання часу відправлення у вигляду списку, який є отсортованим ( setof )
% - додавання нового факту до бази assert(ruh(X,L))
% - видалення з бази тимчасових предикатів ruhtmp, які були створені у процедурі gettime
pruh(X):- gettime(X),setof(T,ru(X,T),L),
assert(ruh(X,L)),abolish(ruhtmp/2),pruh(X).
% використовується виключно для організації циклу введення часу відправлення.
% створює в бази тимчасові факти ruhtmp(Місто,Час_видправлення).
gettime(S):-write(S),nl,gettime1(S).
% реалізація циклу введення часу відправлення спільно з процедурою obr
gettime1(S):-write('Time (hh:mm) :'),nl,read(X),obr(X,S).
% введення атому end - завершує цикл введення.
obr(end,_):-true.
obr(X,S):-assert(ruhtmp(S,X)),gettime1(S).
% друкування списку часу відправлення за допомогою рекурсії
writeruh(X,L):-nl,write(X),nl,writelist(L).
writelist([]):-!.
writelist([X|L]):-write(X),nl,writelist(L).
Контрольні запитання
-
Предикати запису у вихідний потік.
-
Предикати зчитування з вхідного потоку.
-
Вбудовані предикати роботи з файлом
-
Предикати додавання термів до бази даних програми
-
Предикати видалення термів з бази даних програми.
-
Вбудовані предикати перевірки конкретизації змінних.