Использование структур.
Программирование на языке Пролог
В приведенной программе вводятся функторы для обозначения различных горизонтальных и вертикальных перемещений курсора по экрану. В примере используется встроенный предикат управления курсором cursor (Row, Column), который перемещает курсор в позицию (Row — строка, Column — столбец) экрана. Если Row и Column свободные переменные, то они получают значения текущей позиции курсора. Для представления… Читать ещё >
Использование структур. Программирование на языке Пролог (реферат, курсовая, диплом, контрольная)
Цель работы
Изучение представления структур и организации ввода, вывода данных в Турбо-Прологе. Разработка пролог-программ обработки структур данных.
Структуры Пролога
Для представления структурированных (составных) данных в Прологе используются списки и структуры. Близким аналогом прологовских структур в алгоритмических языках (например Си и Паскале) являются записи. Важной особенностью структур, обуславливающее их широкое применение, является компактное представление сложно организованных данных.
Структуры — это объекты, которые состоят из нескольких компонент, возможно разных типов. Этими компонентами могут быть константы, переменные и, в свою очередь, структуры.
Структура состоит из функтора (имени) и последовательности компонент заключенных в круглые скобки и разделенных запятыми.
Число компонент структуры называется размерностью структуры или арностью структуры. Две структуры имеют идентичную организацию, если у них одинаковые функторы и размерность. Пролог допускает структуры с разным числом компонент и одинаковыми функторами. Это будут структуры с разной организацией.
Описание структур, а Турбо-Прологе
Турбо-Пролог требует описания используемых структур. Это осуществляется в разделе domains введением имени домена (имени типа) для структур с идентичной организацией. При этом, после функтора в скобках указываются имена домен (типы компонент).
Например:
domains.
data=date (day, month, year).
month=string.
day, year= integer.
person=person (name, address, telno).
address, telno=string.
name=(string, string, string).
Введенные имена домен структур используются далее в программе при описании предикатов, имеющих в качестве аргументов эти структуры. Имя домена и функтор могут совпадать (person). Турбо-Пролог их различает из контекста.
Альтернативные домены
В общем случае описание типов структур в Турбо-Прологе выглядит следующим образом:
= (D11, D12,…); (D21, D22,…); …,.
где — имя типа /имя домена/ ;
, …- равноправные, но различные функторы;
(D1, D12,…),(D21, D22,…),…- список типов компонент структур (типы стандартные или определяемые пользователем).
Каждая альтернатива включает функтор и, возможно, список областей для соответствующих компонент. Альтернативные домены позволяют вводить общее имя типа данных для структур с разными именами (функторами). Это дает возможность определить единый предикат, обрабатывающий эти разнородные структуры. В случае отсутствия такой возможности пришлось бы определять свои предикаты обработки структур для каждой альтернативы.
Формирование списка структур
В программе в виде фактов info хранится информация о результатах тестирования ряда лиц. Тест содержал 11 вопросов. Порядок задания вопросов мог варьироваться. Тестируемый мог ответить на вопрос (верно или неверно) или не отвечать. Ответы на тест представлены в виде списка, содержащего 1, если ответ верен, и 0, если ответ неверен. У разных лиц списки могут быть различной длины: от пустого (не смог ответить ни на один вопрос) до списка, содержащего одиннадцать элементов. Информация: лицо и его ответы представлены в виде структуры. Требуется найти тех, кто ответил более чем на половину вопросов и сформировать из них список структур .
domains.
test=t (name, result).
name=string.
result=integer*.
number=integer*.
list=test*.
predicates.
info (number, test).
len (result).
p (test).
do (list).
clauses.
info (1, t («tom»,[1, 0, 1, 1, 0]).
info (2, t («bob», [ ]).
info (3, t («ann»,[0, 0, 1, 1, 1, 1, 0]).
p (t (_, X)):-info (_, t (_, X)), len (X, N), N>3.
len ([ ], 0).
len ([H|T], N):-len (T, N1), N=N1+1.
do (L):-findall (X, p (X), L).
С помощью предиката р выявляются лица, ответившие более чем на половину вопросов. Предикат len используется для определения длины списка ответов. Цель программы предикат do формирует список структур, удовлетворяющих требованиям задачи.
Предикат управления курсором
В приведенной программе вводятся функторы для обозначения различных горизонтальных и вертикальных перемещений курсора по экрану. В примере используется встроенный предикат управления курсором cursor (Row, Column), который перемещает курсор в позицию (Row — строка, Column — столбец) экрана. Если Row и Column свободные переменные, то они получают значения текущей позиции курсора.
domains.
step =integer.
movement =up (step); down (step); left (step); right (step); no.
predicates.
move_cursor (movement).
clauses.
move_cursor (up (step)):-cursor (R, C), R1=R-Step, cursor (R1, C).
move_cursor (down (step)):-cursor (R, C), R1=R+Step, cursor (R1, C).
move_cursor (left (step)):-cursor (R, C), C1=C-Step, cursor (R, C1).
move_cursor (up (step)):-cursor (R, C), C1=C+Step, cursor (R1, C1).
move_cursor (no):-cursor (R, C).
Функторы структур определяют направление перемещения курсора по экрану от его текущего положения up-вверх, down-вниз, left-влево, right-вправо, no-на месте. Величину перемещения определяет компонента структуры Step-шаг.
С помощью домена movement (движение), описывающего различные виды перемещения курсора по экрану, вводится предикат move_cursorпереместить курсор, осуществляющий перемещение курсора на указанное число позиций Step в указанном направлении (за счет выбора функтора).
Перемещение курсора выполняется следующим образом: определяется текущее положение курсора (cursor (R, C)), вычисляется новое положение курсора ((R1,C) или (R, C1)); производится перемещение курсора в новое положение (cursor (R1,C) или cursor (R, C1)).
Пример ввода и вывода элементов списка
Требуется ввести ряд целых чисел, сформировать из них список, вывести его на экран как единое целое и поэлементно .
domains.
list=integer*.
predicates.
input (list, list).
read (list, list).
loop (list, list).
print (list).
work.
clauses.
work:-input ([ ], L), nl, nl, write («Список L=», L), nl, nl,.
write («Состоит из элементов:»), nl, print (L).
input (L, L2):-write («Введите элемент:»), read (L, L1),.
write («Будите еще вводить? (y/n):»), loop (L1,L2).
read (L,[X|L]):-readint (X), ! .
read (L, L).
loop (L, L):-readchar (Ch), Ch=`n', ! .
loop (L1,L2): — nl, input (L1, L2).
print ([X|L]):-write (X), nl, print (L).
print ([ ]).
Предикат work осуществляет всю необходимую по условию задачи работу.
Предикат input (L1,L2) вводит данные и, включая их в исходный список L1, формирует выходной список L2. Ввод элемента и включение его в список осуществляется оператором read. Если при вводе элемента произошла ошибка, то исходный список сохраняется. Предикат input после ввода каждого элемента спрашивает о продолжении ввода. Если ввод окончен, то необходимо нажать клавишу ` n '. Анализ введенного символа и выбор последующих действий осуществляет оператор loop. Предикат print осуществляет поэлементный вывод списка.
Пример ввода структурных данных и их обработка
Требуется ввести для ряда лиц данные в виде структуры, содержащей имя и возраст, и подсчитать средний возраст.
domains.
person=p (name, age).
name=string.
age, sum=integer.
mean=real.
predicates.
readperson (person).
run (sum, sum, sum, sum).
do (mean).
clauses.
readperson (p (Name, Age)):;
write («Имя:»), readln (Name)<
write («Возраст:»), readint (Age) .
run (S, N1, S2, N2):;
write («Будите вводить? (y/n):»), readchar (Ch), nl,.
Ch=` y ', !, readperson (p (_, A)) ,.
S1=S+A, N1=N1+1, run (S1, N1, S2, N2).
run (S, S, N, N) .
do (V):-run (0, S, 0, N), N0, !, nl, V=S/N .
do (0).
Всю работу, определяемую условием задачи, выполняет предикат do, аргументом которого и является искомый средний возраст, вычисляемый по введенным исходным данным .
Предикат readperson осуществляет ввод данных, касающихся одного лица, формирует из них структуру p (Name, Age).
Предикат run спрашивает о наличии сходных данных. Для подтверждения необходимо нажать клавишу ` y '. В противном случае следует нажать любую другую клавишу, что приведет к прекращению ввода. При наличии исходных данных, происходит их ввод с помощью предиката readperson. Введенный возраст (А) прибавляется к накапливаемой сумме возрастов: S — значение суммы до ввода текущего данного, S1- сумма после ввода и прибавления, А к S, счетчик числа введенных данных увеличивается на единицу (N — количество данных до ввода, N1 — после ввода).
В рассмотренном примере для ввода структуры вместо предиката readperson можно было бы воспользоваться встроенным предикатом readterm. Тогда изменение программы состояло бы в следующем: убрать из программы описание и определение предиката readperson; в предикате run заменить вызов readperson (p (_, A)) на readterm (person, p (_, A)); исходные данные набирать с указанием функтора (имени структуры), например p («Сергей», 18).
Задание на лабораторною работу
- 1. Изучить представление структур и организацию ввода / вывода данных в Турбо-Прологе.
- 2. В соответствии с вариантом задания, определенным преподавателем, составить пролог-программу.
- 3. Оформить отчет с указанием варианта задания, текста программы и протокола выполнения программы.