Опубликован: 12.02.2014 | Уровень: для всех | Доступ: платный
Лекция 12:

Язык запросов

12.3. Диалог с пользователем

В настоящем параграфе рассматривается реализация общения пользователя с компьютером.

Создается модуль mainDialog для реализации диалога с базой данных. Во время диалога пользователь может просмотреть базу данных, отредактировать базу данных (добавить или удалить факты) и просмотреть основные родственные отношения. Например, отношение "родитель – ребенок" имеет вид:

Мария Иванова - Анна Петрова
Иван Петров - Анна Петрова

Кроме этого, пользователь может посмотреть на дерево предков и на дерево потомков человека, а также задать запрос к базе данных на языке, приближенном к естественному языку. Запросы должны удовлетворять определенной грамматике. Для организации диалога используется repeat-цикл. Выход из цикла выполняется по желанию пользователя о выходе из программы. Перед выходом программа спрашивает, сохранить ли изменения в базе данных. Если пользователь не дает положительный ответ, то изменения не сохраняются.

В декларацию класса mainDialog (листинг 12.8) следует поместить объявление предиката, который вызывается в разделе goal (файл mainDialog.cl).

predicates
    run: ().
Пример 12.8. Декларация класса mainDialog

Раздел goal проекта должен быть изменен следующим образом (файл main.pro):

goal
    mainExe::run(main::run),
    mainDialog::run().

Имплементация класса mainDialog приведена ниже (файл mainDialog.pro). Указатели на объекты классов dbrel, relation, printData и readData (они описываются ниже) хранятся в фактах-переменных. При инициализации им присваивается "значение" erroneous, что по-существу, означает, что значение им присвоено не было. Это "значение" можно присваивать динамически, кроме этого, имеется предикат проверки isErroneous(имя_факта), что часто оказывается полезным в GUI-приложениях.

open core, console

class facts
    db : dbrel := erroneous.
    rel : relation := erroneous.
    pd : printData := erroneous.
    rd : readData := erroneous.

class predicates
    maindialog: ().
clauses
    maindialog():-
        std::repeat(),
            write("\nВыберите действие:\n"
                "\t1. Просмотр базы данных\n"
                "\t2. Редактирование базы данных\n"
                "\t3. Базовые отношения\n"
                "\t4. Дерево предков\n"
                "\t5. Дерево потомков\n"
                "\t6. Запрос на естественном языке\n"
                "\t7. Выход\n"),
            X = rd:readStr(),
        act(X),
        !.
    maindialog().

class predicates
    act: (string) determ.
clauses
    act("1"):- !,
        write("Все записи:\n"),
        pd:printDb(),
        fail.
    act("2"):- !,
        write("Редактирование базы данных:\n"
            "2.1 Добавление факта\n"
            "2.2 Удаление факта\n"),
        X = rd:readStr(),
        act(X).
    act("2.1"):- !,
        write("Добавление новых сведений\n"),
        Add = addData::new(rd),
        Add:addNewPerson(),
        fail.
    act("2.2"):- !,
        write("Удаление сведений:\n"),
        Del = delData::new(rd),
        Del:delPerson(),
        fail.
    act("3"):- !,
        write("\nВыберите отношение: \n"
            "\t3.1 Родитель\n"
            "\t3.2 Отец\n"
            "\t3.3 Мать\n"
            "\t3.4 Муж\n"
            "\t3.5 Сын\n"
            "\t3.6 Дочь\n"
            "\t3.7 Сестра\n"
            "\t3.8 Брат\n"
            "\t3.9 Предок\n"),
        X = rd:readStr(),
        act(X),
        !.
    act("3.1"):-  !,
        write("Отношение \"родитель - ребенок\":\n"),
        rel:parent(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.2"):- !,
        write("Отношение \"отец - ребенок\":\n"),
        rel:father(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.3"):- !,
        write("Отношение \"мать - ребенок\":\n"),
        rel:mother(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.4"):- !,
        write("Отношение \"муж - жена\":\n"),
        rel:husband(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.5"):- !,
        write("Отношение \"сын - родитель\":\n"),
            rel:son(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.6"):- !,
        write("Отношение \"дочь - родитель\":\n"),
        rel:daughter(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.7"):- !,
        write("Отношение \"сестра – брат или сестра\":\n"),
            rel:sister(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.8"):- !,
        write("Отношение \"брат – брат или сестра\":\n"),
        rel:brother(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("3.9"):- !,
        write("Отношение \"предок - потомок\":\n"),
        rel:ancestor(Id1, Id2),
            pd:printRel(Id1, Id2),
        fail.
    act("4"):- !,
        write("Дерево предков:\n"),
        T = trees::new(rd),
        T:findAncTree(),
        fail.
    act("5"):- !,
        write("Дерево потомков:\n"),
        T = trees::new(rd),
        T:findDescTree(),
        fail.
    act("6"):- !,
        Q = query::new(rd, rel),
        Q:query(),
        fail.
    act("7"):- !,
        write("Выход. "),
        saveDb().
    act(_):-
        write("\nТакого действия нет.\n"),
        fail.

% Сохранение базы данных
class predicates
    saveDb: ().
clauses
    saveDb():-
        write("Сохранить изменения в базе данных (да/нет)? "),
        X = string::toLowerCase(rd:readStr()),
        'д' = string::frontChar(X),
        !,
        db:save().
    saveDb().

    run():-
        db := dbrel::new("family.txt"),
        db:load(),
        pd := printData::new(db),
        rd := readData::new(pd),
        rel := relation::new(db),
        mainDialog(),
        _ = readLine().
Пример 12.9. Имплементация класса mainDialog

Предикат frontChar возвращает первый символ строки.

Факты-переменные db, rel, pd и rd хранят указатели на объекты классов dbrel, relation, printData и readData, соответственно.

Жаныл Айкын
Жаныл Айкын
Rustam Inatov
Rustam Inatov

Доброго времени суток, подскажите пожалуйста, visual prolog examples, pie, vip7.5 - это все, где я могу скачать? (в смысле) может быть на сайте есть какой-то архив? Увы я не нашел его.

Подскажите, пожалуйста.

С уважением, Рустам.

Айдана Ахметова
Айдана Ахметова
Россия
Дмитрий Куянов
Дмитрий Куянов
Россия, Омск, ОмГТУ