Главная страница
Навигация по странице:

  • ТЕМА 2.8. ФАЙЛЫ В ЯЗЫКЕ PROLOG

  • 2.8.1 Предикаты Prolog для работы с файлами

  • 2.8.2 Описание файлового домена

  • 2.8.5 Модификация существующего файла

  • 2.8.6 Дозапись в конец уже существующего файла

  • ТЕМА 2.9 СОЗДАНИЕ ДИНАМИЧЕСКИХ БАЗ ДАННЫХ В ЯЗЫКЕ PROLOG

  • 2.9.2 Предикаты динамической базы данных в языке Prolog

  • Системы искусственного интеллекта. Тематический план


    Скачать 1.4 Mb.
    НазваниеТематический план
    Дата09.04.2023
    Размер1.4 Mb.
    Формат файлаpdf
    Имя файлаСистемы искусственного интеллекта.pdf
    ТипТематический план
    #1048753
    страница7 из 9
    1   2   3   4   5   6   7   8   9
    ТЕМА 2.7 СТРОКИ В ЯЗЫКЕ PROLOG
    План лекции:
    2.7.1 Операции над строками
    2.7.1 Операции над строками
    Строка в Prolog, как и в других языках, представляет собой набор символов. При программировании на Prolog символы могут быть «записаны» при помощи их кодов ASCII. Обратный слэш (\), непосредственно за которым следует десятичный код ASCII символа (N), интерпретируется как соответствующий символ. Для представления одиночного символа выражение \N должно быть заключено в апострофы: '\N'. Для представления же строки символов их коды ASCII помещаются друг за другом, а вся строка заключается в двойные кавычки: "\N\N\N". Например, запись «ABC» равносильна записи "\65\66\67".
    Длина строки измеряется полным количеством символов в строке.
    Prolog имеет встроенный предикат, который используется для нахождения длины строки: srt_len (String_value, String_length).
    Если в правиле srt_len("TODAY",L) переменная L не означена до начала обработки правила, то она получит значение длины строки "TODAY".
    Этим значением будет целое число. Если же до начала выполнения вызова предиката str_len обе его переменные уже означены, то предикат будет успешным только при условии, что значение String_length равно длине строки String_value. Например, если S имеет значение "ABC", а L имеет значение 3, то предикат str_len(S,L) успешен; в противном случае он неуспешен.
    Конкатенация двух строк означает их объединение, т. е. образование одной новой строки. Например, результат конкатенации двух строк "one day" и "at a time" может быть равен "one day at a time" или "at a time one day". Эти две результирующие строки различны, так как образующие их строки были
    объединены в различном порядке. Prolog имеет встроенный предикат, который выполняет соединение (конкатенацию) двух строк и имеет синтаксис: concat(Input_string1,Input_string2,Output_String).
    При этом в нем должно иметься не менее двух любых входных объектов. Этот же предикат, если задана выходная строка, позволяет определить одну из исходных строк, участвующих в конкатенации, либо, если заданы все объекты, проверяет истинность операции.
    Пример:
    concat("TODAY","TOMORROW",S)
    S="TODAYTOMORROW" concat(S,"TOMORROW","TODAYTOMORROW")
    S="TODAY" concat("TODAY",S,"TODAYTOMORROW")
    S="TOMORROW" concat("TODAY","TOMORROW","TODAYTOMORROW") истина concat("TODAY","TOMORROW","TODAYTOMOR") ложь
    Создание подстрок. Подстрока — это строка, являющаяся копией некоторой части исходной строки. Например, двумя возможными подстроками строки "Expert Systems" являются "Expert" и "Systems". Prolog имеет встроенный предикат, служащий для создания подстрок, синтаксис которого:
    fronsrt(Number,Source_string,Substring1,Substring2).
    Аргумент Number задает полное количество символов, которые должны быть скопированы в Substring1 из исходной строки Source_String.
    Остальные символы строки Source_string будут скопированы в Substring2.
    Пример. Утверждение: frontstr(6,"Expert systems", String1, String2)
    присваивает String1 значение "Expert", а String2 — значение "systems".
    Создание символьных префиксов. Создать «префиксный» символ — это значит присоединить этот символ к началу строки. Например, присоединение префикса 'A' к строке "BCDEF" дает строку "ABCDEF". Эта операция в Prolog реализуется с помощью встроенного предиката:
    frontchar(String,Char,Rest_of_string).

    Объекту String присваивается значение, состоящее из Char и
    Rest_of_string («остаток строки»).
    Указанный предикат также можно использовать для выделения одного символа (первого) из строки.
    Пример:
    frontchar(Str, 'F', "OX") Str="FOX" frontchar("SPRING", C, "PRING")
    C='S' frontchar("dBASE", 'd', X) X="BASE"
    Специальные строки. В Prolog определены специальные строки, используемые для определенных целей. Эти строки называются именами и используются для обозначения символических констант, доменов, предикатов и переменных. По определению, специальные строки в Prolog имеют следующие свойства:
    - строка строится из прописных и строчных букв, цифр и символов подчеркивания;
    - между символами не должно быть пробелов;
    - строка начинается с буквы;
    - строка не может начинаться с любого из специальных символов;
    - строка не может содержать управляющих символов.
    Prolog имеет встроенный предикат, позволяющий проверять, является ли строка специальной строкой Prolog. Синтаксис этого предиката следующий:
    isname(String).
    Если String — это специальная строка Prolog, то предикат будет успешным; в противном случае он будет неуспешным.
    Преобразование данных. Prolog для преобразования данных из одного типа в другой предоставляет следующие предикаты:
    upper_lower (U, L) str_char (S, C) str_int (S, I) str_real (S, R) char_int (C,I).

    Их применение целесообразно, когда тип объектов встроенного предиката отличается от типа объектов предиката, определенного пользователем.
    Все предикаты преобразования данных содержат два объекта, а имена этих предикатов указывают тип выполняемого преобразования. Например, str_char преобразует строку, состоящую из одного символа и имеющую тип string, в значение типа char. Имена предикатов также указывают порядок объектов, поскольку имеют два направления преобразования данных.
    Например, если в предикате upper_low (S1, S2) переменная S1 уже означена и имеет значение "STARS AND STRIPES", то данный предикат присваивает строку "stars and stripes" переменной S2. Но если S2 означена, а S1 — не означена, то значение "STARS AND STRIPES" получает переменная S1. В случае же, когда обе переменные означены, предикат успешен, если одна из переменных имеет значение строки, содержащееся в другой переменной, но записанной строчными буквами (т. е. фактически выполняется проверка их совпадения без учета регистра).
    Предикат str_char, как уже было сказано, используется для преобразования объектов типа string в объекты типа char. Предикат str_int используется для преобразования строчного представления целых чисел в переменные типа integer. Предикат str_real используется для преобразования действительных чисел в строки. Предикат же char_ int используется для присваивания числа (ASCII-кода символа) данному объекту.

    ТЕМА 2.8. ФАЙЛЫ В ЯЗЫКЕ PROLOG
    План лекции:
    2.8.1 Предикаты Prolog для работы с файлами
    2.8.2 Описание файлового домена
    2.8.3 Запись в файл
    2.8.4 Чтение из файла
    2.8.5 Модификация существующего файла
    2.8.6 Дозапись в конец уже существующего файла
    2.8.1 Предикаты Prolog для работы с файлами
    Работа с данными, содержащимися в файлах, называется файловой обработкой. К числу наиболее типичных операций над файлами относятся создание файла, запись в файл и чтение из файла, а также модификация уже существующего файла и добавление к нему новых данных.
    Перечислим некоторые предикаты Prolog для работы с файлами:
    - deletefile(Filename) — уничтожение файла;
    - save(Filename) — сохранение файла на диске;
    - renamefile(OldFilename, NewFilename)— переименование файла;
    - existfile(Filename) — проверка наличия файла с заданным именем;
    - disk(Path) — выбор накопителя и пути доступа к файлу;
    - dir(Path, Filespec, Filename) — выдача списка файлов в заданном каталоге. В последних двух случаях переменной Path должен быть присвоен корректный путь доступа, а переменная Filespec задает расширение представляющей интерес группы файлов (данный предикат выдает список имен файлов с заданным расширением). Имя выбранного файла будет присвоено переменной Filename:
    - openwrite(FDomain, Filename) — открытие файла для записи.
    Здесь FDomain — файловый домен, а Filename — имя файла на диске;

    - openread(FDomain,Filename) — открытие файла для чтения;
    - openmodify(FDomain, Filename) — открытие уже существующего файла для его модификации (при этом указатель помещается в начало этого файла);
    - openappend
    (FDomain,
    Filename)
    — открытие уже существующего файла для дозаписи новых данных в его конец;
    - writedevice (FDomain) — назначение устройства записи;
    - readdevice (FDomain) — назначение устройства чтения;
    - closefile (FDomain) — закрытие файла;
    - flepos (Logical_filename, File_position, Mode) — помещение указателя в файле в нужную позицию. При этом параметру Mode можно присвоить одно из трех возможных значений: 0 — смещение (File_position) указано относительно начала файла, 1 — смещение указано относительно текущей позиции или 2 — смещение указано относительно конца файла.
    2.8.2 Описание файлового домена
    Чтобы использовать в программе на языке Prolog файлы, необходимо снабдить ее описанием файлового домена. Описание файлового домена с именем datafile выглядит следующим образом [4]:
    domains
    file = datafile
    В описании file можно указать несколько символических имен, но само это описание должно быть единственным. Если в программе вводится несколько символических имен файлов, то они разделяются между собой точкой с запятой: file = datafile1; datafile2; datafile3

    2.8.3 Запись в файл
    Опишем последовательность действий, необходимых для записи информации в файл.
    1.
    Открытие файла. Предикат openwrite (datafile,"FILE1. DAT"), где datafile1 — это введенный пользователем файловый домен, а FILE1.DAT — имя файла на диске, устанавливает связь между объектами datafile и FILE1.
    DAT. После этого ссылки на datafile1 будут означать обращение к
    FILE1.DAT, и эта связь останется в силе вплоть до закрытия файла. Если файл с именем FILE1.DAT к моменту вызова предиката openwrite уже присутствовал в каталоге, то его содержимое будет утрачено. Чтобы застраховаться от этого, можно сначала проверить наличие файла при помощи предиката existfile("FILE1.DAT") и принять соответствующие меры, если предикат existfile будет успешным.
    2.
    Назначение файла для записи. Эту операцию выполняет предикат writedevice(datafile). Возможно также указание вместо файла одного из устройств для записи (вывода информации): экрана (screen) или принтера
    (printer).
    3.
    Собственно запись в файл. Можно использовать любые подходящие для этой цели предикаты, например, write: любой предикат write после выполнения writedevice будет выводить информацию не на экран, а в заданный файл.
    4.
    Использование любых других предикатов и правил, отвечающих назначению программы.
    5.
    Закрытие файла. Для этого служит предикат closefile (datafile).
    Когда файл закрыт, операции чтения или записи для него уже недопустимы.
    Закрытие файла также защищает его содержимое от каких-либо манипуляций. Еще одним следствием закрытия файла является перевод указателя файла в его начало, — это может понадобиться при повторном открытии файла.

    Пример фрагмента программы, поясняющий сказанное:
    openwrite(datafile,"FILE1.DAT"), writedevice(datafile),
    < любые правила или предикаты записи в файл > < любые другие
    правила или предикаты > сlosefile(datafile).
    2.8.4 Чтение из файла
    Для чтения данных из файла требуется выполнить следующие действия.
    1.
    Открытие файла — openread(datafile,"FILE1.DAT").
    2.
    Назначение файла для чтения — readdevice(datafile). Можно также назначить устройство чтения (ввода данных) — клавиатуру (keyboard).
    3.
    Собственно чтение из файла при помощи соответствующего предиката или правила.
    4.
    Использование произвольных предикатов и правил, отвечающих целям программы.
    5.
    Закрытие файла — closefile(datafile).
    Пример фрагмента, демонстрирующего сказанное:
    openread(datafile,"FILE1.DAT"), readdevice(datafile),
    < любые правила или предикаты чтения из файла > < любые другие
    правила или предикаты > сlosefile(datafile).
    2.8.5 Модификация существующего файла
    Последовательность действий, требуемых для модификации уже существующего файла, несколько отличается от той, которая необходима для записи в файл или чтения из него. Прежде всего файл должен быть открыт для модификации (т. е. и для чтения, и для записи одновременно). Для этого служит предикат openmodify(datafile,"FILE1.DAT"), который успешен, только если файл уже имеется на диске. Когда файл открывается для модификации, указатель помещается в его начало.

    Для модификации файла нужно выполнить следующие действия.
    1.
    Открытие файла — openmodify(datafile,"FILE1.DAT").
    2.
    Переадресация вывода в файл — writedevice(datafile).
    3.
    Запись в файл новых данных.
    4.
    Использование произвольных предикатов и правил, отвечающих целям программы.
    5.
    Закрытие файла — closefile(datafile).
    Пример:
    openmodify(datafile,"FILE1.DAT"), writedevice(datafile),
    < правила для выборочной записи в файл >, < любые другие правила или
    предикаты > сlosefile(datafile).
    2.8.6 Дозапись в конец уже существующего файла
    Возможность записывать новые данные в конец уже существующего файла обеспечивается в Prolog предикатом openappend. Когда файл открывается для дозаписи, указатель файла автоматически помещается в его конец.
    Для добавления новых данных в конец файла нужно выполнить следующие действия.
    1.
    Открытие файла — openappend(datafile,"FILE1.DAT").
    2.
    Переадресация вывода в файл — writedevice(datafile).
    3.
    Дозапись в файл новых данных при помощи соответствующих правил.
    4.
    Использование произвольных предикатов и правил, отвечающих целям программы.
    5.
    Закрытие файла — closefile(datafile).
    Пример:
    openappend(datafile,"FILE1.DAT"), writedevice(datafile),

    < любые правила для дозаписи в файл >, < любые другие правила или
    предикаты > сlosefile(datafile).
    Пример записи в файл
    /* Вывод информации из статической базы на экран дисплея и в файл на диске. */ domains
    str = string file = datafile predicates
    data(str) write_lines goal
    openwrite(datafile,"SHAKE1.DAT"), write_lines, closefile(datafile).
    clauses data("A drum, a drum!"). data("Macbeth does come").
    data("The weird sisters, hand in hand,"). data("Posters of the sea and land,"). data("Thus do go about, about:"). data("Thrice to thine and thrice to mine."). data("And thrice again, to make up nine.").
    write_lines :- data(Line), write(" ",Line),nl, writedevice(datafile), write(" ",Line),nl, writedevice(screen), fail. write_lines.
    Последний предикат write_lines позволяет удовлетворить цель, если первый вариант правила был неуспешен ввиду исчерпания утверждений из базы.
    Пример чтения данных
    /* Чтение данных из файла и их вывод на экран */
    domains
    str = string file = datafile predicates
    read_write_lines goal
    openread(datafile,"SHAKE1.DAT"), readdevice(datafile), read_write_lines, closefile(datafile). clauses
    read_write_lines :- not(eof(datafile)), readln(Line), writedevice(screen), write(" ",Line),nl, read_write_lines. read_write_lines.

    Правило read_write_lines использует встроенный предикат Prolog eof, который дает успех, если обнаружен признак конца файла. Если в процессе чтения данных достигается конец файла, то никакие считывания больше не будут производиться, — если, конечно, не переместить указатель файла на какую-либо позицию, предшествующую метке конца файла. Неуспешной будет любая подцель, пытающаяся произвести чтение из файла при указателе, стоящем на этой метке.
    Пример чтения с клавиатуры и записи в файл:
    /* Считывание данных с клавиатуры (до "end") и их запись в файл на диске */ domains
    file = datafile dstring = string
    predicates
    readin(dstring) create_a_file goal
    create_a_file
    clauses
    create_a_file
    :write("Введите имя файла:"), readln(Filename), openwrite(datafile,Filename), writedevice(datafile), readln(Dstring), readin(Dstring), closefile(datafile). readin("end") :- !.
    readin(Dstring) :write(Dstring), readln(Dstring1), readin(Dstring1).
    В Prolog существует предикат, позволяющий поместить указатель в файле в нужную позицию, — flepos (Logical_ filename,File_position,Mode).
    Параметру File_position здесь должно быть присвоено целое число, обозначающее номер позиции в файле, где позже будет считан или записан символ. Параметру Mode можно присвоить одно из трех значений: 0, 1 или 2, которое определяет, как будет интерпретировано значение File_position:
    0
    — смещение относительно начала файла;
    1
    — смещение относительно текущей позиции;
    2
    — смещение относительно конца файла.

    Например, в выражении filepos(players,100,0) параметр players — это имя логического файла, параметр File_ position имеет значение 100, что указывает на то, что будет прочитан символ, отстоящий на 100 позиций, а значение 0 для параметра Mode указывает, что отсчет будет производиться от начала файла. В другом примере — filepos (players,100,1) — отсчет будет вестись уже относительно текущей позиции указателя: если этот предикат будет успешен, то указатель сдвинется на 100 позиций вперед.

    ТЕМА 2.9 СОЗДАНИЕ ДИНАМИЧЕСКИХ БАЗ ДАННЫХ В
    ЯЗЫКЕ PROLOG
    План лекции:
    2.9.1 Базы данных на Prolog
    2.9.2 Предикаты динамической базы данных в языке Prolog
    2.9.1 Базы данных на Prolog
    В Prolog имеются специальные средства для организации баз данных
    (БД), которые рассчитаны на работу с реляционными базами данных.
    Внутренние унификационные процедуры языка Prolog осуществляют автоматическую выборку фактов с нужными значениями известных параметров и присваивают значения еще не определенным. Механизм отката же позволяет находить все имеющиеся ответы на сделанный запрос.
    Описание предикатов динамической базы данных выполняется следующим образом:
    database
    dplayer(name,team,position)
    Напомним, что раздел database в Prolog предназначен для описания предикатов базы данных. Все различные утверждения этого предиката составляют динамическую базу данных Prolog. Она называется динамической, поскольку во время работы программы из нее можно удалять любые содержащиеся в ней утверждения, а также добавлять новые. В этом состоит ее отличие от «статических» баз данных, где утверждения являются частью кода программы и не могут быть изменены во время ее работы.
    Другая важная особенность динамической базы данных состоит в том, что она может быть записана на диск, а позже считана с диска в оперативную память. Важным является и то, что в динамической базе данных могут содержаться только факты (но не правила).

    Иногда бывает предпочтительно хранить часть информации базы данных в виде утверждений статической БД; тогда эти данные заносятся в динамическую БД сразу после активизации программы. Для этой цели используются специальные предикаты. В целом предикаты статической БД имеют другое имя, но ту же самую форму представления данных, что и предикаты динамической.
    Например, предикат статической
    БД, соответствующий предикату dplayer для динамической базы данных, может быть описан так:
    predicates
    player(name,team,position)
    clauses player("Dan Marino","Miami Dolphins","QB"). player("Richard
    Dent","Chicago Bears","DE"). player("Bernie Kosar","Cleveland Browns","QB"). player("Doug
    Cosbie","Dallas
    Cowboys","TE"). player("Mark
    Malone","Pittsburgh Steelers","QB").
    2.9.2 Предикаты динамической базы данных в языке Prolog
    В Prolog имеются специальные встроенные предикаты для работы с динамической базой данных: asserta, assertz, retract, save, consult, readterm и findall.
    Предикаты asserta, assertz и retract позволяют занести факт в заданное место динамической БД или удалить из нее уже имеющийся факт. При этом предикат asserta заносит новый факт в базу данных, располагающуюся в оперативной памяти компьютера. Новый факт помещается перед всеми уже внесенными утверждениями данного предиката.
    Синтаксис:
    asserta(Clause).
    Например, чтобы поместить в БД утверждение player("Bernie
    Kosar","Cleveland Browns","QB").

    Перед уже имеющимися там утверждениями, необходимо применить следующее предикатное выражение:
    asserta(dplayer("Bernie Kosar",
    "Cleveland Browns","QB")).
    Предикат assertz (так же, как и asserta) заносит новые утверждения в базу данных, но помещает новое утверждение после всех уже имеющихся в базе утверждений того же предиката. (Запомнить просто: последняя буква предиката — «a» или «z». Буква «a» стоит перед всеми другими буквами английского алфавита, а «z» — после всех букв; точно так же эти предикаты размещают и добавляемое утверждение.) Синтаксис: assertz(Clause).
    Предикат retract удаляет утверждение из динамической БД. Его синтаксис:
    retract(Existing_clause).
    Например, для удаления из базы данных утверждения dplayer("Doug
    Cosbie","Dallas Cowboys","TE") необходимо написать выражение:
    retract(dplayer("DougCosbie","DallasCowboys","TE")).
    Так же, как asserta и assertz, предикат retract применим только в отношении фактов.
    Для модификации базы данных можно использовать комбинацию выражений с предикатами asserta, assertz и retract.
    Предикаты save и consult применяются для записи динамической БД в файл на диск и для загрузки содержимого файла в динамическую БД соответственно. При этом предикат save сохраняет находящуюся в оперативной памяти базу данных в текстовом файле. Синтаксис:
    save(File_name).
    Например, можно записать: save("football.dba").

    В результате все утверждения находящейся в оперативной памяти динамической БД будут записаны в файл football. dba. Если же файл с таким именем уже имелся на диске, то его прежнее содержимое будет стерто.
    Файл БД может быть считан в память (загружен) при помощи предиката consult. Синтаксис:
    consult(File_name).
    Предикат consult неуспешен, если файл с указанным именем отсутствует на диске, если этот файл содержит ошибки
    (например, при несоответствии синтаксиса предиката из файла описаниям из раздела программы database) или если содержимое файла невозможно разместить в памяти из-за отсутствия места.
    Предикат readterm используется для чтения из файла объектов, относящихся к определенному в программе домену. Синтаксис:
    readterm(Domain,Term).,
    где Domain задает имя домена, а Term — различные наборы значений объектов этого домена.
    Например, в предикатном выражении: readterm(auto_record,auto(Name,Year,Price)).
    Domain замещен на auto_record, а Term — на auto (Name,Year,Price), где терм auto определяет все наборы значений этого домена. При этом описание доменов должно выглядеть так:
    domains
    name = string year = integer price = real auto_record = auto(name,year,price) file = auto_file
    Для получения доступа к файлу сначала необходимо воспользоваться предикатами openread и readdevice, после чего можно применить readterm.
    Пример:
    /* Демонстрация примера работающей базы данных. База данных допускает следующие операции: добавление, удаление, выборку и просмотр данных.

    Эта программа создает базу данных и содержит ее в оперативной памяти */
    database
    dplayer (symbol,symbol,byte,byte)
    /* предикат включает в себя имя игрока, название команды, игровой номер и количество сыгранных сезонов*/
    predicates
    player (symbol,symbol,byte,byte) redirect /*пересылка данных в динамическую БД*/ rule menu (byte) /*организует обработку выбранного пункта меню*/
    clauses player("Dan Marino","Miami Dolphins",13,4). player("Richard
    Dent","Chicago Bears",95,4). player("Bernie Kosar","Cleveland Browns",19,2,). player("Doug
    Cosbie","Dallas
    Cowboys",84,
    8). player("Mark
    Malone","Pittsburgh Steelers",16,7,).
    rule:-write("1.Добавление данных в БД"),nl, write("2.Удаление данных об указанном игроке"),nl,
    write("3.Поиск сведений об игроках указанной команды"),nl,
    write("4.Просмотр всей БД"),nl,
    write("5.Выход"),nl, readint(N),
    N<>5, menu(N),
    rule.
    rule.
    menu(1):-write("Введите имя, название команды,
    игровой номер и количество сыгранных сезонов."),nl,
    write("Имя: "),readln(Fam), write("Название команды:"),readln(Team), write("Игровой номер:"),readint(Number), write("Количество сыгранных сезонов: "), readint(Plays),
    assertz(dplayer(Fam,Team,Number,Plays)).
    menu(2):-write("Укажите имя игрока для удаления сведений о нем:"),nl,
    readln (Fam), retract(dplayer(Fam,_,_,_)). menu(2):- write("Такого игрока нет!"),nl,menu(2).
    menu(3):- write("Укажите название команды для поиска информации об игроках:"),nl,
    readln (Team),
    write("Игроки этой команды:"),nl,
    dplayer(X,Team,_,_), write(X),nl, fail.
    menu(3).
    menu(4):- dplayer(F,T,N,K), write("Имя:
    ",F),nl, write("Название команды: ",T), nl, write("Игровой номер: ", N), nl, write("Количество сыгранных сезонов:",
    K),nl,nl, fail.
    menu(4).
    redirect:-player(X,Y,Z,P), assertz(dplayer(X,Y,Z,P)), fail.
    redirect:-write("Пересылка данных успешно завершена.
    Нажмите ENTER"),nl,readln(_).
    goal redirect, rule.

    1   2   3   4   5   6   7   8   9


    написать администратору сайта