Скачиваний:
26
Добавлен:
22.05.2015
Размер:
92.67 Кб
Скачать

Лабораторная работа 6 Внутренняя база данных

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

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

Операции над фактами бд

assert(fact) - вставляет указанный факт в конец внутренней базы данных.

assertz(fact) - вставляет указанный факт в конец внутренней базы данных.

asserta(fact) - вставляет указанный факт в начало внутренней базы данных.

fact должен быть термом, принадлежащим домену внутренней базы данных. Указанные предикаты, применённые к факту с режимом детерминизма single, заменяют существующий факт указанным.

retract(fact) nondeterm anyflow - успешно удаляет первый сопоставимый факт из базы данных. Неуспешен, когда ни один факт не связан. fact может содержать анонимные переменные. Предикат retract/1 не может быть использован для удаления фактов single или фактов-переменных. Будьте осторожны вызывая retract/1 со свободным аргументом fact, когда база данных содержит факты, объявленные как single. Если Вы удаляете факт single, то генерируется ошибка во время выполнения.

retractall(fact) - удаляет все сопоставленные факты из базы данных. Он всегда успешен, даже если нет ни одного факта для удаления. Попытка удаления факта single приводит ко ошибке во время компиляции. Невозможно получить какие-либо выходные значения из предиката retractall/1. По этой причине, переменные при вызове должны быть или связаны, или анонимны.

retractFactDb(Имя_DB) - удаляет все факты из внутренней базы данных с именем Имя_DB. Заметим, что факты single и факты-переменные удалить невозможно, они невидимы для этого предиката.

file::consult(FileName, Имя_DB) – загружает БД из файла в память.

file::consult(FileName, Имя_DB, IsUnicodeFile [out]) – загружает БД из файла в память и третьим аргументов возвращает кодировку (true – Unicode, false - ansi).

file::reconsult(FileName, Имя_DB) – перезагружает БД из файла в память.

file::reconsult(FileName, Имя_DB, IsUnicodeFile [out]) – перезагружает БД из файла в память и третьим аргументов возвращает кодировку (true – Unicode, false - ansi).

file::save(FileName, Имя_DB) – сохраняет БД с указанным именем в файл.

file::save(FileName, Имя_DB, IsUnicodeFile) – сохраняет БД с указанным именем в файл. Третий аргумент указывает кодировку для сохранения (true – Unicode, false - ansi).

Лексика русского языка

Пример 1. Создадим файл БД со словами русского языка. Источником для этого может послужить любой файл с перечнем русской лексики, взятый из Интернета. Например, файл “Словарь.txt”, который при запуске примера должен находиться в папке EXE Вашего консольного проекта. Для преобразования текстового файла в БД существует несколько путей. Самый простой – прочитать весь текст файла и разделять его на лексемы в памяти. Однако лучший способ - читать текст не целиком, а по словам или по строкам. Тем самым мы можем обрабатывать файлы достаточно большого размера, не захватывая много памяти при этом. Следующий пример именно так и делает.

implement main

open core, console, string

constants className = "com/visual-prolog/main".

classVersion = "$JustDate: $$Revision: $".

class facts - слова

w:(string).

i: unsigned :=0.

class predicates

r: (inputStream).

clauses

classInfo(className, classVersion).

r(In):-In:endOfStream(),!.

r(In):-S=In:readLine(),assert(w(S)),i:=i+1,r(In).

run():-init(),

    StandartInput=stdio::getInputStream(),

    In=inputStream_file::openFile8("Словарь.txt"),

    r(In),

    stdio::setInputStream(StandartInput),

    file::save("Словарь.w",слова,false()),

    write("Всего слов = ",i), 

    _ = readLine().

end implement main

goal

   mainExe::run(main::run).

Пояснения к цели программы:

StandartInput=stdio::getInputStream(),%читаем поток ввода

In=inputStream_file::openFile8("Словарь.txt"),%новый поток

r(In), % преобразование входного текста в БД

stdio::setInputStream(StandartInput),%устан. поток ввода

file::save("Словарь.w",слова,false()),%сохраняем БД в файл

Пояснения к предикату преобразование входного текста в БД:

r(In):-In:endOfStream(),!.%останов цикла если конец файла

r(In):-S=In:readLine(),assert(w(S)),i:=i+1,r(In). %чтение строки из файла и сохранение её в виде факта БД в памяти

Убедитесь, что после выполнения программы в папке EXE появился файл "Словарь.w", содержащий слова русского языка в алфавитном порядке. В конце файла должен быть факт, указывающий количество слов в словаре.

Задание 1. На основе полученной БД слов составить линейный кроссворд. Линейный кроссворд это список слов, у которых каждое следующее слово начинается на последнюю букву предыдущего. Например: Яблоко-окурок-кот-телефизор-ребро-оглобля. Количество слов равно шести. Подсказка: для получения первой буквы слова можно воспользоваться предикатом string::frontchar(), для получения последней буквы – предикатом string::lastChar().

Задание 2. На основе полученной БД слов составить линейный кроссворд, длина которого вводится с клавиатуры.

Задание 3. На основе полученной БД слов составить линейный замкнутый кроссворд, в котором первая буква первого слова должна совпадать с последней буквой последнего слова. Длина кроссворда вводится с клавиатуры.

Задание 4. На основе полученной БД слов составить линейный замкнутый кроссворд, в котором первая буква первого слова должна совпадать с последней буквой последнего слова. Длина кроссворда вводится с клавиатуры. Длина всех слов должна быть одинаковой и также вводится с клавиатуры.

Задание повышенной сложности 1. На основе полученной БД создать новую БД слов “Словарь-англ.w”, в которой должны быть только те слова русского языка, которые можно написать английскими буквами.

Задание повышенной сложности 2. На основе файла “Частотный словарь.txt”, в котором указано число употреблений каждого слова в русских текстах, создать БД фактов f(unsigned Номер, real Частота, string Слово) и сохранить её в файле “ Частотный словарь.w ”. Подсказка: при чтении очередной строки из файла её надо распарсить тремя предикатами string::fronttoken(). Также можно (на Ваш выбор) распарсить предикатом string::split_delimiter().После чего следует найти сумму всех вторых аргументов и общее количество слов. Зная эти величины нужно заново прочитать исходный файл, преобразовывая две первые лексемы в соответствующий тип данных с помощью предикатов math::tryToUnsigned() и math::tryToReal(), для того, чтобы путём деления определить частоту встречаемости каждого слова. Полученную БД сохранить в файле “Частотный словарь.w”.

Задание повышенной сложности 3. Для БД “Частотный словарь.w” разработать предикат, возвращающий слова в указанном частотном диапазоне.

Соседние файлы в папке Лабораторные работы