Предикат read для ввода термов




1. Предикат read/1.

В отличие от предиката write, который всегда успешно согласуется, встроенный предикат read(Term) определен так, что он не только дает возможность ввести с клавиатуры некоторый терм, но и проверяет, унифицируется ли заданный аргумент Term с введенным термом.

Попытка пользователя ввести выражение, не являющееся термом, приведет к ошибке.

 

Замечание

Ввод терма всегда должен заканчиваться точкой и нажатием клавиши Enter.

Если аргументом read является переменная, то унификация будет успешной и эта переменная будет конкретизирована введенным с клавиатуры значением.

1)?- read(X). abc. /*Введен атом */ X = abc Yes 2)?- read(X). t(1,2). /* Введен составной терм */ X = t(1,2) Yes
3)?- read(X). $asdf$. /*Введена строка */ X = $asdf$ Yes 4)?- read(t(X,Z)). t(Y,2). /* Унификация t(X,Z)=t(Y,2)*/ X = H1 /* H1 – внутреннее имя Y */ Z = 2 Yes
5)?- read(5). 5. Yes 6)?- read('Терм'). Тер. No

 

2. Предикат read_string/1

Для ввода символьных строк удобнее использовать предикат read_string(String), который при конкретизированном аргументе, как и read, выполняет сверку заданной и введенной строк. Отличий два: (1) ввод не нужно завершать точкой, только нажать Enter, (2) вводимую строку не нужно заключать в знаки доллара (см. выше пример 3).

Примеры.

7)?- read_string(X). Строка X = $Строка$ yes 8)?- read_string(X). t(1,2) X = $t(1,2)$ /*Преобразовано в строку */ Yes
9)?-read_string($Строка$). Строка /*Введена строка */ Yes 10)?- read_string('Строка'). /* атом! */ Строка /*Введена строка */ Yes

Различие между предикатами read и read_string принципиальное. С помощью read можно прочесть составной терм и тут же использовать его как цель, а read_string превращает всё в строки (см. пример 8), которые целью быть не могут.

Например, предположим, что в программе имеется факт t(2,3). Напишем вопрос, где предполагается ввод составного терма (как элемента данных) и использование этого терма как цели для согласования.

?- read(X),X.

t(Z,Y). /* Вводим составной терм */

X = t(2,3) /* Результат конкретизации X= t(Z,Y)при вводе и

унификации t(X,Y)= t(2,3) с фактом из программы */

yes

ЗАДАНИЕ 2

1. Проверить выполнение примеров, приведенных для предикатов read и read_string.

2. База данных состоит из двух таблиц. Первая хранит общую информацию о студенте, вторая — о его учебе. Таблицы связаны между собой по полю "Номер зачетной книжки".

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

а) В программе описать информацию из таблиц с помощью двух предикатов, например, person/4 и student/4. Элементы с текстовой информацией в предикатах представлять как строки ($Александрова$, $Мех.‑мат.$ и т.п.).

Таблица 1

Номер зачетной книжки Фамилия Инициалы Год рождения
  Александрова А.А.  
  Иванов И.И.  
  Петров П.П.  
  Сидоров С.С.  

Таблица 2

Номер зачетной книжки Факультет Специальность Курс
  Мех.-мат. Информационные технологии  
  ФВТ Информационные системы  
  ФВТ Системный анализ и управление  
  Физический Нанотехнологии  

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

Диалог пользователя с программой должен выглядеть так:

3. Убедиться, что программой выдаются правильные ответы.

4. Программа была составлена в расчете на конкретную задачу: вывод информации об одном студенте. Выясним, нельзя ли, используя ту же программу, получить информацию обо всех студентах сразу. Для этого нужно запустить запрос и вместо конкретной фамилии попытаться ввести какую-нибудь переменную, например, Z. Какой получен ответ?

Предикат string_term

Причина, по которой не удалось использовать переменную для запроса информации обо всех студентах, состоит в том, что введенная переменная была истолкована как строка (т.е. $Z$), потому что для ввода был использован предикат read_string. Чтобы не менять этот предикат, но решить эту проблему, нужно дополнительно выполнить преобразование строки $Z$ в переменную Z.

Взаимные преобразования строк и термов можно выполнять с помощью предиката string_term/2. В качестве первого аргумента предикат ожидают строку, а в качестве второго — терм. Предикат позволяет выполнять преобразование

а) строк в термы:

б) термов в строки:

в) а также выяснять, преобразуются ли друг в друга заданные терм и строка:

Замечание

Помимо этого предиката система имеет также несколько других встроенных предикатов для выполнения преобразований типов данных:

string_atom (String, Atom),

string_integer (String, Integer)

И некоторые другие.

ЗАДАНИЕ 2 (продолжение)

Добавить в программу новую цель: после ввода фамилии преобразовать введенную строку в терм. Это позволяет рассматривать имя переменной, введенное с помощью read_string, как переменную, а не строку.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: