Госкомитет России по связи и информатизации ПОВОЛЖСКАЯ ГОСУДАРСТВЕННАЯ АКАДЕМИЯ ТЕЛЕКОММУНИКАЦИЙ И ИНФОРМАТИКИ
Одобрено...
20 downloads
158 Views
377KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Госкомитет России по связи и информатизации ПОВОЛЖСКАЯ ГОСУДАРСТВЕННАЯ АКАДЕМИЯ ТЕЛЕКОММУНИКАЦИЙ И ИНФОРМАТИКИ
Одобрено Методическим советом ПГАТИ 3.04.1998
МЕТОДИЧЕСКИЕ УКАЗАНИЯ к выполнению лабораторных работ " ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ АВТОЛИСП"
Автор-составитель:
КУЛЯС О.Л., к.т.н., доцент
Редактор:
АКЧУРИН Э.А., к.т.н., доцент
Рецензент:
ТЯЖЕВ А.И., д.т.н., профессор
Самара 1998
2 ВВЕДЕНИЕ Лабораторный цикл входит в дисциплину "Функциональное программирование" специальности 220400 и включает в себя четыре четырехчасовые работы по изучению языка программирования АВТОЛИСП. Каждая лабораторная работа включает разделы подготовки к ее выполнению с перечнем контрольных вопросов, задание на выполнение работы и краткие теоретические сведения по изучаемым разделам. Приведен список рекомендуемой для подготовки к выполнению работ литературы.
РЕКОМЕНДУЕМАЯ ЛИТЕРАТУРА 1. Лавров С.С., Силагадзе Г.Е. Автоматическая обработка данных. Язык ЛИСП и его реализация. М., Наука, 1978. 2. Хендерсон П. Функциональное программирование. Применение и реализация. М., Мир, 1983. 3. Филд А., Харрисон П. Функциональное программирование. М., Мир, 1993. 4. Хювенен Э., Сеппянен И. Мир ЛИСПа. ,т.1 и 2 . М., Мир, 1990. 5. Уинстон П. Искусственный интеллект. М., Мир, 1990 6. Иванов О.Н., Чайкин А.А., Шевченко В.Н. Язык программирования AutoLISP Release 10, 11. М., TRINIKA Ltd, 1992. 7. Гладков С.А. Программирование на языке АВТОЛИСП в системе САПР АВТОКАД. М., Диалог-МИФИ, 1991. 8. Кречко Ю.А., Полищук В.В. АВТОКАД: курс практической работы. М., Диалог МИФИ, 1994. 9. Геснер Р., Бойс Дж. АВТОКАД для начинающих. Казань, Гармония, 1993. 10.Кречко Ю.А., Полищук В.В. АВТОКАД 13: новые возможности. М., Диалог МИФИ, 1996. 11.Конспект лекций по дисциплине "Функциональное программирование".
3
ЛАБОРАТОРНАЯ РАБОТА N1
ОСНОВЫ ПРОГРАММИРОВАНИЯ НА ЯЗЫКЕ АВТОЛИСП
1. Подготовка к работе Изучить по лекциям и методической разработке вопросы, связанные с лексикой, особенностями представления данных и выражений на АВТОЛИСПе. Изучить функции присвоения значений переменным, функции создания списков и основные функции работы с ними. Изучить основные математические функции АВТОЛИСПа. 2. Контрольные вопросы 1. Активизация АВТОЛИСПа и основные приемы работы ним. 2. Основные лексические соглашения АВТОЛИСПа. 3. Типы данных в АВТОЛИСПе. 4. Присвоение значений переменным. Функции SET и SETQ. 5. Понятие списка. Создание списков в АВТОЛИСПе. 6. Элементарные селекторы в АВТОЛИСПе. Функции CAR и CDR. 7. Правила записи S-выражений в АВТОЛИСПе. 8. Базовые арифметические функции АВТОЛИСПа. 9. Базовые функции отношения. 10. Базовые тригонометрические функции. 3. Задание на выполнение работы 1. Загрузить АВТОКАД и выйти в его графический редактор, обеспечив при этом работу АВТОЛИСПу. 2. Определить версию АВТОЛИСПа, используя функцию (VER). Обратить внимание на действия клавиш "пробел" и "ENTER". Вывести на экран и просмотреть содержимое имен функций АВТОЛИСПа, хранящихся в переменной ATOMLIST: !atomlist . 3. Присвоить переменным значения в соответствии с таблицей, используя функции SET и SETQ. После присвоения проверить значения переменных функцией !.
4 имя переменной
значение
a b c d e f g h l m n e1 f4 gh
12 5 -8 6,5 - 4,25 " C3" nil " -15 * 10^2 " 11,25 * 10^5 " ups " nil (car) a*b-c e/25,3
4. Определить тип созданных переменных с помощью функций АВТОЛИСПа ATOM, BOUNDP, LISTP, TYPE . 5. Проверить выполнение математических функций АВТОЛИСПа для выражения состоящего из аргументов a, b, c, d. 6. Создать списки S, G1 и QL из следующих элементов: S
G1
QL
+ 2,9 * 10е3
(y1)
(25 -8 *5)
(- 54)
12,5
"IBM"
0, 255
(- 9*5)
6.28
"key"
"a - b"
"pi"
()
(- 4 0.28 0.6)
()
(ab k (d m))
"12/ 3"
55
(12 ("dog" "cat") NN)
-45
(e F (xy) mn)
"mouse" 7. Последовательно извлечь из созданных списков S, G1 и QL - первые элементы - вторые элементы - третьи элементы
5
- четвертые элементы. Просмотреть как изменились после этого списки S, G1, QL. 8. Выйти из АВТОКАДа командой END. 9. Составить отчет, который должен содержать все вводимые функции АВТОЛИСПа и возвращаемые результаты по всем пунктам задания. 4.Общие сведения Язык программирования LISP (LISt Processing - обработка списков) впервые предложен Дж. Маккарти в 1960 г.. Название языка хорошо подчеркивает основную область его применения - решение задач нечисленного характера. В виде списков удобно представлять алгебраические выражения, графы, элементы конечных групп, множества, правила и другие сложные объекты. Списки являются наиболее гибкой формой представления информации в памяти современных ЭВМ. LISP является функциональным языком - в основу которого положено понятие функции. Все вычисления, преобразования и управления программы в этих языках осуществляются с помощью элементарных (встроенных) функций или функций, определяемых программистом при написании программы. Программа на LISP является суперпозицией некоторых функций и, в свою очередь, может быть использована как функция другими программами. LISP отличается от обычных языков программирования оригинальным решением одной из проблем исскуственного интеллекта - теории рекурсии. Поскольку эта проблема возникает во многих отраслях знаний, LISP может использоваться в таких разных областях, как экспертные системы, символическая алгебра (символьные методы), разработка СБИС, машинное зрение, разработка архитектуры вычислительных систем и другие. AutoLISP - это специально созданный для AutoCAD диалект LISPа, полученный в результате изменения языка XLISP. Он идеально подошел для АВТОКАДа, поскольку позволяет программно работать с объектами, справочными таблицами, считывать и записывать файлы. Т.е. он является прямым и единственным окном внутрь АВТОКАДа. СОГЛАШЕНИЯ ПО ЛЕКСИКЕ В AutoLISP для ввода программ или данных приняты следующие лексические соглашения: - имена символов могут состоять из любой последовательности литер (печатных знаков), исключая следующие: (, ), ., ', ", ;.
6 - следующие литеры вызывают прерывание имени переменной или константы: (, ), ', ", ;, пробел, конец файла. - выражения могут занимать несколько строк. - несколько пробелов между именами эквивалентны одному пробелу. - имена функций и символов безразличны к регистру на котором они набираются. Имена символов не могут начинаться с цифры. Нельзя использовать в качестве имен имена функций АВТОЛИСПа. (Все имена функций АВТОЛИСПа, а также имена, созданные пользователем, храняться в переменной ATOMLIST. Вывести ее на экран можно из командной строки, набрав: !atomlist . - целые константы могут начинаться с необязательных литер "+" или "-". Значения целых чисел должны находиться в пределах от -32768 до +32767. - Действительные константы состоят из одной или более цифр, за которыми следует десятичная точка, за которой в свою очередь следует одна или более цифр. Далее в необязательном порядке могут следовать латинские литеры "e" или "E" и показатель степени числа 10. Таким образом: .34 56. -2.е2 - неверные записи 0.34 56.0 -2.0е2 - верные записи. - Строковые константы (литералы) - это последовательность литер взятая в кавычки. - Знак апострофа может быть использован как короткая запись функции QUOTE. 'foo эквивалентно (quote foo). - В программу могут быть введены комментарии. Они начинаются с литеры ";" и продолжаются до конца строки. - Точечная пара - это два элемента, каждый из которых является именем символа, числовой константой или литералом, заключенных в круглые скобки и разделенные разделителями. В качестве разделителей используются круглые скобки или пробелы. - pi, t, nil - обозначают соответственно число ПИ, символ логической истины и символ "пусто". Типы данных в AutoLISP Поскольку LISP предназначен в первую очередь для обработки символьной информации числа в нем играют не главную роль. Основные типы данных в нем называются "атом" и "точечная пара". Атом - это переменные любого из простых типов. AutoLISP в отличии от других
7
диалектов LISP имеет два специфических типа данных, это "имена примитивов" и "наборы" системы проектирования AutoCAD. В AutoLISP имеются следующие типы атомов: - списки - набор разделенных пробелами атомов и/или списков, заключенных в круглые скобки. - числа: целые числа - это положительные и отрицательные целые числа (без дробей и десятичных точек) и действительные числа - это проложительные и отрицательные числа с десятичной точкой. - литералы (строковые переменные) - последовательность литер взятая в кавычки. - символы - переменные, в которых хранятся не значения, а ссылки на другие переменные. - файловые дискрипторы - описатели файлов. - имена примитивов системы AutoCAD - переменные в которых хранится индекс однозначно соответствующий примитивам чертежа AutoCAD. - наборы системы AutoCAD - встроенные функции - переменные , посредством которых осуществляется обращение к стандартной библиотеке функций. В AutoLISP существует возможность проверить является ли переменная атомом. Для этого используется функция (atom). Если да - возвращается T (истина), если нет - nil. Далее можно определить является ли атом пустым списком с помощью функциии (boundp ). в противном Возвращается nil если атом имеет значение nil, и T случае (т.е. если атом имеет какое то значение или ссылку). Для определения того, является ли переменная списком, существует функция (listp ). Возвращает Т, если переменная список, иначе - nil. Наконец в AutoLISP можно определить тип данных объекта с помощью функции (type< объект>). При этом возвращается как символ тип данных объекта: INT - целые величины REAL - числа с плавающей точкой STR - строковые константы FILE - дескрипторы файлов SYM - символы LIST - списки и функции пользователя SUBR - встроенные функции AutoLISP ENAME - имена примитивов AutoCAD
8 PICKSET PAGETB -
наборы примитивов AutoCAD таблицы диспетчера страниц.
Выражения AutoLISP Любая управляющая конструкция AutoLISP содержит функции встроенные или созданные пользователем. Причем в списке функция должна стоять на первом месте. Выражения (S-выражения) AutoLISP это список, первым элементом которого является функция. Любая программа на LISP состоит из выражений и сама является выражением. Основные свойства выражений заключаются в следующем: - Каждая открывающая скобка должна иметь закрывающую. - Сразу после открывающей скобки должно стоять имя функции, выполняемой при вычислении. - Следующие за именем функции аргументы отделяются пробелом от функции и друг от друга. Дополнительные пробелы игнорируются , поэтому выражение может занимать несколько строк. - Каждое выражение вычисляется и результат возвращается. - С логической точки зрения любое возвращаемое значение может быть истинно или ложно. Итак, выражения AutoLISP имеют вид: (функция аргумент1 аргумент2 ... аргументN) Основы программирования на языке АВТОЛИСП Присвоение значений переменным Присвоение значений переменным осуществляется двумя функциями SET и SEYQ. В зависимости от значения, присваемого переменной, определяется ее тип. Значения переменных сохраняются до конца сеанса работы или до задания новых значений. Функция SET (установить) имеет формат (set ' ). Данная функция присваивает символу (где символ - имя переменной) значение выражения и возвращает это значение. Использование имени переменной с апострофом впереди равнозначно использованию специальной функции (quote ), которая возвращает выражение не выполняя его. Поэтому запись вида (quote cat) эквивалентна записи 'cat . Например: (set 'a 10.0) ;устанавливает в переменную А значение 10.0 и возвращает 10.0
9
(set (quote a) '(* b c d));устанавливает в переменную А выражение (* B C D) и возвращает (* B C D) Имя функции SETQ образовано как сокращение сочетания SET by Quote (присвоить по ссылке). Она позволяет в отличии от функции SET, обращаться не к самой переменной, а к ее значению. Эта функция является основной функцией присвоения в АВТОЛИСПЕ и имеет формат (setq ...). Данная функция устанавливает в символ1 значение выражения1, в символ2 значение выражения2 и т.д. и возвращает последнее выражение. Рассмотрим действие этой функции на примерах: (setq a 100 b 200) ;устанавливает в А значение 100, в В значение 200 и возвращает 200. (setq a '(c + d)) ;устанавливает в А выражение (C + D) и возвращает (C + D). (setq b 3 c 4 a (* b c) ; устанавливает в B значение 3, в C значение 4, в А значение произведения 12 и возвращает 12. Если функцией SETQ какой либо переменной было присвоено некоторое значение, то его можно использовать из командной строки АВТОКАДА. Для этого нужно в ответ на запрос напечатать ! и имя переменной: !a . Создание списков и работа с ними Функция LIST позволяет создать список. Она имеет формат: (list ...) Данная функция берет любое число элементов , создает из них список и возвращает его. Например: (list 14.75 12.4 0.0) ;создает список (14.75 12.4 0.0) и возвращает (14.75 12.4 0.0). В качестве элементов списка можно задавать не только конкретное значение, но и переменную любого типа, например: (list 12 'y 32.5 '(10.5 30) "cat"); создает список (12 y 32.5 (10.5 30) "cat") и возвращает (12 Y 32.5 (10.5 30) "CAT"). Для того чтобы к созданному списку можно было обратиться, следует присвоить его значение переменной используя функцию SETQ. Например, создадим список и присвоим его значение переменной SC: (setq sc (list 12 'y 32.5 '(10.5 30) "cat")). При программировании на LISP часто возникает необходимость извлечь один или несколько элементов списка. Для этого в АВТОЛИСПе существуют специальные встроенные функции, называемые элементарными селекторами.
10 Функция CAR позволяет извлечь первый элемент списка и возвращает его. Если список пуст, то возвращается NIL. Она имеет формат: (car ). Например: (car '(a b c)) возвращает A (car '(a b) c) возвращает (A B) (car '()) возвращает NIL. Функция CDR позволяет извлечь список без первого элемента и возвратить его. Если список пуст, возвращается NIL. Она имеет формат: (cdr ). Примеры: возвращает (B C) (cdr '(a b c)) (cdr '((a b) c)) возвращает (C) (cdr '()) возвращает NIL. Если в качестве аргументов этой функции задается точечная пара, то возвращается второй элемент точечной пары, список при этом не формируется. Например: (cdr '(a.b)) возвращает B (cdr '(1 . "Text")) возвращает "Text". Язык АВТОЛИСП допускает сцепление функций CAR и CDR до четырех уровней вложенности. Если дано: (setq x '((a b) c d), то вызов: (caar x) эквивалентен (car(car x)) и возвращает А (cdar x) эквивалентен (cdr(car x)) и возвращает (B) (cadar x) эквивалентен (car (cdr(car x))) и возвращает B (cadr x) эквивалентен (car (cdr x)) и возвращает C (cddr x) эквивалентен (cdr (cdr x)) и возвращает (D) (caddr x) эквивалентен (car (cdr (cdr x))) и возвращает D. Базовые функции языка АВТОЛИСП Автолисп располагает множеством предопределенных функций. Для вызова любой из них нужно задать ее имя (прописными или строчными буквами) в качестве первого элемента списка, последующими элементами которого являются аргументы функции (если они есть). Математические функции (+ ...) Эта функция возвращает сумму всех своих аргументов. Она может работать как с целыми, так и с вещественными числами. Если все аргументы представляют собой целые числа, то и результат будет
11
целочисленным; если хотя бы один из аргументов является вещественным числом, все целые числа будут преобразованы в вещественные, и результат также будет вещественным. Например: (+ 1 2) возвращает 3 (+ 1 2 3 4.5) возвращает 10.500000 (+ 1 2 3 4.0) возвращает 10.000000 (- ...) Эта функция вычитает второй аргумент из первого и возвращает полученнную разность. Если задается более двух аргументов, то из первого аргумента вычитается сумма всех остальных, от второго до последнего, и полученная разность возвращается в качестве результата. Если задан только один аргумент, функция возвращает результат вычитания этого аргумента из нуля. Функция может работать с целыми и с вещественными числами, используя обычные правила преобразования. Например: (- 50 40) (- 50 40.0 2) (- 50 40.0 2.5) (- 8)
возвращает возвращает возвращает возвращает
10 8.000000 7.500000 -8
( * ...) Эта функция возвращает произведение всех своих аргументов, в качестве которых могут задаваться как целые, так и вещественные числа, преобразуемые по обычным правилам. Например: (* 2 3) (* 2 3 4.0) (* 3 -4.5)
возвращает 6 возвращает 24.000000 возвращает -13.500000
(/ ...) Эта функция возвращает частное от деления первого числа на второе. Если задано более двух чисел, то первое число делится на произведение всех остальных, от второго до последнего, и частное от этого деления возвращается в качестве результата. Эта функция может использоваться с целыми и вещественными числами в соответствии со стандартными правилами. Например: (/ 100 2) (/ 100 2.0) (/ 100 20 2.0) (/ 100 20.0 2) (/ 100.0 20 2)
возвращает возвращает возвращает возвращает возвращает
50 50.000000 2.500000 2.500000 2.500000
12 (/ 100 20 2) (/ 135 360) (/ 135 360.0)
возвращает 2 возвращает 0 возвращает 0.375000
(= ...) Эта функция реализует отношение "равно". Она возвращает "T" при численном равенстве всех своих аргументов, и "nil" в противном случае. В качестве аргументов можно задавать числа и строки. Например: (= 4 4.0) возвращает T (= 20 388) возвращает nil (= 2.4 2.4 2.4) возвращает T (= 499 499 500) возвращает nil (= "я" "я") возвращает T возвращает nil . (= "я" "ты") (/= ) Эта функция реализует отношение "не равно". Она возвращает "Т", если аргументы численно не равны, и "nil" в противном случае. При количестве аргументов, большем двух, функция не определена. Примеры: (/= 10 20) возвращает Т (/= "ты" "ты") возвращает nil (/= 5.43 5.44) возвращает Т . (< ...) Эта функция реализует отношение "меньше". Она возвращает "Т", если первый аргумент численно меньше второго, и "nil" в противном случае. При количестве аргументов, большем двух, "Т" возвращается в том случае, если каждый аргумент меньше своего правого соседа. Примеры: (< 10 20) возвращает T (< "b" "c") возвращает T (< 357 33.2) возвращает nil (< 2 3 88) возвращает T (< 2 3 4 4) возвращает nil . ( 77 4 4) возвращает nil . (>= ...) Эта функция реализует отношение "больше или равно". Она возвращает "Т", если первый аргумент численно больше второго или равен ему, и "nil" в противном случае. При количестве аргументов, большем двух, "Т" возвращается в том случае, если каждый аргумент больше своего правого соседа или равен ему. Примеры: (>= 120 17) возвращает T (>= "c" "с") возвращает T (>= 3.5 1792) возвращает nil (>= 77 4 4) возвращает T (>= 77 4 9) возвращает nil . (1+ ) Эта функция возвращает , увеличенное на 1; аргумент может быть целым или вещественным. Примеры: (1+ 5) возвращает 6 (1+ -17.5) возвращает -16.500000 (1- ) Эта функция возвращает , уменьшенное на 1; аргумент может быть целым или вещественным. Примеры: (1- 5) возвращает 4 (1- -17.5) возвращает -18.500000
14 (abs ) Эта функция возвращает абсолютное значение аргумента, который может быть вещественным или целым. Примеры: (abs 100) возвращает 100 (abs -100) возвращает 100 (abs -99.25) возвращает 99.250000 (cos ) Эта функция возвращает косинус аргумента , задаваемого в радианах. Примеры: (cos 0.0) возвращает 1.000000 (cos pi) возвращает -1.000000 (eval ) Функция возвращает результат вычислени аргумента , который может быть представлен любым выражением Автолиспа. Если даны присваивания: (setq a 123) (setq b 'a) то (eval 4.0) возвращает 4.000000 (eval (abs -10) возвращает 10 (eval a) возвращает 123 (eval b) возвращает 123
(exp ) Эта функция возвращает "е" в степени, заданной аргументом (натуральный антилогарифм). Возвращаемое значение представляет собой вещественное число. Например: (exp 1.0) возвращает 2.718282 (exp 2.2) возвращает 9.025013 (exp -0.4) возвращает 0.670320 (expt ) Эта функция возвращает результат возведения в заданную . Если оба аргумента представлены целыми числами, результат также будет целочисленным, в противном случае результат будет вещественным. Примеры: (expt 2 4) возвращает 16 (expt 3.0 2.0) возвращает 9.000000
15
(log ) Эта функция возвращает в виде вещественного числа натуральный логарифм аргумента . Например: (log 4.5) возвращает 1.504077 (log 1.32) возвращает 0.198850 (max ...) Эта функция возвращает наибольший из своих аргументов, каждый из которых может быть целым или вещественным. Например: (max 4.07 -144) возвращает 4.070000 (max -88 19 5 2) возвращает 19 (min ...) Эта функция возвращает наименьший из своих аргументов, каждый из которых может быть вещественным или целым. Например: (min 683 -10.0) возвращает -10.000000 (min 732 48 5) возвращает 2 (rem ...) Эта функция возвращает остаток от деления на , используя по обычным правилам как целые, так и вещественные числа. Примеры: (rem 42 12) возвращает 6 (rem 12.0 16) возвращает 12.000000 (rem 60 3) возвращает 0 (sin ) Эта функция возвращает вещественное число, представляющее собой синус , заданного в радианах. Например: (sin 1.0) возвращает 0.841471 (sin 0.0) возвращает 0.000000 (sqrt ) Эта функция возвращает квадратный корень. Например: ( sqrt 4) возвращает 2.000000 (sqrt 2.0) возвращает 1.414214 Логические функции ( and ...) Эта функция возвращает результат логического умножения аргментов, представляющих собой выражения. Функция прекращает дальней-
16 шие вычисления и возвращает "nil", если какое-либо из выражений равно нулю, в противном случае возвращает "T". Если, например, выполнены следующие присваивания: (setq a 103) (setq b nil) (setq c "string") то (and 1.4 a c) (and 1.4 a b c)
возвращает Т возвращает nil
(or ...) Эта функция возвращает результат логического сложения аргументов . Функция OR просматривает слева направо в поиске , отличного от нуля. Встретив такое , функция прекращает дальнейшие вычисления и возвращает "Т". Если все имеют значение "nil", функция возвращает "nil". Например: (or nil 45 '()) (or nil '())
возвращает возвращает
Т nil
(not) Функция NOT используется для выполнения логического отрицания над операндом. Она возвращает Т, если NIL, и NIL в том случае, если определен (имеет какое-либо значение). Например: (setq pt1 '(10 20) pt2 nil pt3 '()) (not pt1) (not pt2) (not pt3)
возвращает NIL возвращает T возвращает T
(null ) Эта функция подобна функции NOT и возвращает "Т", если имеет значение "nil", и "nil" в противном случае. Если даны присваивания: (setq a 123) (setq b "string") (setq c nil) то
17
(null a) (null b) (null c) (null '())
возвращает возвращает возвращает возвращает
nil nil T T
Функции сравнения выражений (eq ) Эта функция устанавливает идентичность выражений и ; выражения идентичны, если они связаны с одним и тем же объектом (скажем, с помощью функции "setq"). Функция EQ возвращает "Т", если выражения идентичны, и "nil" в противном случае. Обычно эта функция используется для установления идентичности двух списков. Например, если даны присваивания: (setq f1 '(a b c)) (setq f2 '(a b c)) (setq f3 f2) то (eq f1 f3) возвращает nil (f1 и f3 -- разные списки!) (eq f3 f2) возвращает T (f3 и f2 -- это один и тот же список) Смотрите также описание функции EQUAL. (equal ) Эта функция устанавливает, равны или нет аргументы и ; выражения равны между собой, если их вычисление приводит к одному и тому же результату. Если даны следующие присваивания: (setq f1 '(a b c)) (setq f2 '(a b c)) (setq f3 f2) то (equal f1 f3) возвращает Т (вычисление f1 и f3 дает одинаковый результат) (equal f3 f2) возвращает Т (f3 и f2 -- это один и тот же список) Заметим, что для одних и тех же списков отношение EQUAL может выполняться, а отношение EQ - нет. Если для каких-либо атомов выполняется отношение EQUAL, то для них выполняется и отношение EQ. Кроме того, если для двух списков или атомов выполняется отношение EQ, то для них выполняется и отношение EQUAL.
18
ЛАБОРАТОРНАЯ РАБОТА N2
СОЗДАНИЕ ФУНКЦИЙ ПОЛЬЗОВАТЕЛЯ НА ЯЗЫКЕ АВТОЛИСП 1. Подготовка к работе Изучить по лекциям и методической разработке вопросы связанные с лексикой, особенностями представления данных и выражений на АВТОЛИСПе. Изучить основные математические функции АВТОЛИСПа. Изучить функцию DEFUN и основные функции ввода -вывода для организации диалога с пользователем. 2. Контрольные вопросы 1. Типы данных в АВТОЛИСПе. 2. Пользовательская функция DEFUN. Локальные переменные и аргументы. 3. Интерактивные процедуры и семейство функций GETxxx. 4. Функция GETINT. 5. Функция GETREAL. 6. Функция GETKWORD. 7. Функция INITGET. 8. Вывод информации в интерактивных процедурах. 9. Правила записи S- выражений в АВТОЛИСПе. 10. Арифметические функции и правила записи арифметических выражений. 3. Задание на выполнение работы 1. Загрузить АВТОКАД и выйти в его графический редактор, обеспечив при этом работу АВТОЛИСПу. 2. Создать функцию ANGLE производящую перевод вводимых в градусах углов в радианы по формуле: a*pi/180, где а - угол в градусах, a>0. 3.Создать функции SINS, COSN, TUN вычисляющие синус, косинус и тангенс положительных углов, вводимых в градусах.
19
4.Создать функцию LG, вычисляющую десятичный логарифм вводимого числа по формуле: LG X= LN X/LN 10 при X /= 0. 5.Создать функцию CBR вычисляющую корень N-ой степени из вводимого числа при N>=0. 6.Создать функцию STEP, производящую возведение вводимого числа X в дробную степень, с показателем M/N. При создании функций использовать диалог в виде запросов и подсказок, созданный функциями семейства GET и INITGET. 7. Выйти из АВТОКАДа командой END. 9. Составить отчет, который должен содержать все вводимые функции АВТОЛИСПа и возвращаемые результаты по всем пунктам задания. 4.Общие сведения Создание функций пользователя в АВТОЛИСПе Для определения новых функций используется специальная встоенная функция DEFUN (DEFine FUNction - определить функцию). Эта функция создает свою собственную замкнутую область локальных переменных. Формат этой функции: (defun ...) С помощью функции DEFUN определяется функция с именем, задаваемым аргументом (заметим, что имя функции заключается в кавычки автоматически, и пользователь не должен делать это "вручную". За аргументом следует (возможно, пустой); за списком может следовать косая черта, а за ней - одно или несколько имен локальных переменных определяемой функции. Косая черта должна быть отделена по крайней мере одним пробелом и от последнего аргумента определяемой функции (если таковые есть), и от первой локальной переменной. При отсутствии аргументов и переменных после имени определяемой функции задается пустой список, заключенный в круглые скобки. Например: (defun имя (x y)...)
;определяемая функция "имя" имеет ;два аргумента (defun имя (/ a b)...) ;две локальных переменных (defun имя (x / temp)...) ;один аргумент и одна локальная ;переменная (defun имя ()...) ;нет ни аргументов, ни локальных ;переменных После аргументов и локальных переменных могут задаваться выражения, котрые нужно вычислить при исполнении определяемой функции.
20 Сама функция DEFUN возвращает имя определенной пользователем функции. При вызове пользовательской функции она вычисляет и присваивает результаты аргументам из . При использовании локальных переменных значения, который они имели вне функции, сохраняются. Пользовательская функция возвращает результат вычисления последнего выражения. Результаты вычисления предыдущих выражений не сохраняются. Примеры: (defun плюс10 (X) (+ 10 X) ) (плюс10 5) (плюс10 -7,4)
возвращает возвращает возвращает
ПЛЮС10 15 2.600000
(defun точки (x y / temp) (setq temp (strcat x "...")) (strcat temp y) ) (точки "а" "б") (точки "из" "в")
возвращает возвращает возвращает
ТОЧКИ "а...б" "из...в"
ПРИМЕЧАНИЕ: Никогда не задавайте имя встроенной функции в качестве аргумента , иначе возможность доступа к этой функции будет утрачена. Организация ввода информации в интерактивных процедурах Для ввода различных типов данных в АВТОЛИСПЕе существует семейство функций GETxxx. Эти функции могут иметь в качестве аргумента произвольную строковую переменную, в которой может содержаться текст запроса или подсказка, позволяющая пользователю ввести данные определенного типа. Функции этого типа приостанавливают выполнение программы до осуществления ввода данных с клавиатуры или при помощи устройства указания. При этом в ответ на запрос функций семейства GETxxx нельзя вводить выражения АВТОЛИСПа. Механизм использования этих функций сходен, разницу составляет лишь тип данных, принимаемых каждой функцией. Рассмотрим некоторые из них: (getint []) Эта функция приостанавливает вычисления для ввода целого числа и возвращает это целое число. Необязательный аргумент
21
представляет собой строку, отображаемую на экране в виде приглашения на ввод. Например: (setq число (getint)) Здесь функция (GETINT) используется без аргументов, поэтому на командной строке не появляется никакого запроса-подсказки. (setq число (getint "Введите масштаб:")) Здесь в качестве аргумента используется запрос "Введите масштаб:", поэтому в командной строке появляется запрос "Введите масштаб:" и вычисления приостанавливаются до завершения ввода. В ответ на запрос функции GETINT нельзя вводить выражение АВТОЛИСПАа. Смотрите также описание функции INITGET. (getreal []) Эта функция приостанавливает вычисления для ввода вещественного числа и возвращает это число. Необязательный аргумент представляет собой отображаемую на экране строку. Примеры: (setq число (getreal)) (setq число (getreal "Масштабный коэффициент:")) В ответ на запрос функции GETREAL нельзя вводить выражение АВТОЛИСПа. Смотрите также описание функции INITGET. (getkword []) Функция GETKWORD запрашивает ключевое слово. Список допустимых ключевых слов определяется заранее с помощью функции INITGET. Функция GETKWORD возвращает строку, соответствующую введенному пользователем ключевому слову. При вводе недопустимого ключевого слова АВТОКАД вновь запрашивает ввод. В ответ на нулевой ввод (если он допустим) возвращается нуль. Нуль возвращается и в том случае, если не обнаружена строка, соответствующая заданному ключевому слову. Например, последовательность вызовов: (initget 1 "Да" "Нет") (setq x (getkword "Вы уверены? (Да или Нет) ")) выдает пользователю подсказку "Вы уверены? (Да или Нет)" и присваивает переменной X значение "Да" или "Нет" в зависимости от ответа пользователя. Если ответ не совпадает ни с одним из ключевых слов или является нулевым, АВТОКАД вновь запросит ввод.
22 В ответ на запрос выражения АВТОЛИСПа.
функции
GETKWORD
нельзя
вводить
initget [] []) Эта функция определяет варианты применения GET-функций, кроме функций GETSTRING и GETVAR. Функция INITGET всегда возвращает нуль. Необязательный аргумент представляет собой целое число с одним из следующих значений: 1 2 4 8 16 32
Смысл Запрет пустого отклика Запрет нулевых значений Запрет отрицательных значений Отказ от контроля пределов, чертежа Возвращение трехмерной, а не двухмерной точки Использование штриховых линий при изображении резиновой нити
Эти значения можно складывать в любом сочетании, формируя число в диапазоне от 0 до 63. Если при пользовательском вводе не выполняются какие-либо из специфицированных условий (например, вводится нуль при наличии запрета на ввод нулевых значений), АВТОКАД выводит на экран соответствующее сообщение и повторяет запрос на ввод. Например, последовательность вызовов: (initget (+ 1 2 4)) (setq возраст (getint "Сколько Вам лет?")) запрашивает возраст пользователя, автоматически повторяя запрос, если пользователь вводит нулевое или отрицательное значение. Отсутствию аргумента соответствует нулевое значение (нет условий). Значения этого аргумента обрабатываются только теми GETфункциями, для которых они имеют смысл, как показано в следующей таблице: GET-функция Управляющие разряды функции INITGET "getint" "getreal"
1, 2, 4 1, 2, 4
23
"getdist" "getangle" "getorient" "getpoint" "getcorner" "getkword" "getorient" "getorient"
1, 1, 1, 1, 1, 1 ---
2, 2, 2, 8, 8,
4, 32 32 32 16, 32 16, 32
Организация вывода информации в интерактивных процедурах АВТОЛИСП содержит несколько функций, предназначенных для выполнения вывода данных. Они позволяют выводить информацию на экран для организации диалога с пользователем. (prompt ) Эта функция выводит на экран сообщение в поле подсказок системы АВТОКАД и возвращает NIL. здесь - это строка литер, заключенная в кавычки. Например, если в каком либо месте программы понадобилось напечатать "Попытайтесь еше раз", то в программу можно ввести следующаю строку: (prompt "Попытайтесь еше раз") Функция TERPRI печатает пустую строку в поле подсказок системы АВТОКАД и возвращает NIL. Она имеет формат: (terpri) Ее используют для того, чтобы в программе запросы функций АВТОЛИСПа выводились с новой строки. Вместо этой функции часто используют управляющий символ "\n" непосредственно внутри запроса или сообщения: (prompt "\n Программа выполнена") ЛАБОРАТОРНАЯ РАБОТА N3
ПРОГРАММИРОВАНИЕ ПЕРЕХОДОВ ПО УСЛОВИЯМ И ЦИКЛОВ НА ЯЗЫКЕ АВТОЛИСП. ИЗУЧЕНИЕ РАСШИРЕННЫХ СРЕДСТВ РАБОТЫ СО СПИСКАМИ 1. Подготовка к работе
24 Изучить по лекциям и методической разработке вопросы связанные с лексикой, особенностями представления данных, выражений на АВТОЛИСПе. Изучить основные математические функции АВТОЛИСПА. Изучить функцию DEFUN и основные функции ввода -вывода для организации диалога с пользователем. Изучить функции организации переходов по условиям, организации циклов и функции работы со списками. 2. Контрольные вопросы 1. Создание пользовательских функций , формат функции DEFUN. 2. Списки, их создание и работа с ними. 3. Элементарные селекторы и конструкторы АВТОЛИСПа. 4. Функции отношения и сравнения в АВТОЛИСПе. 5. Организация переходов по условию в АВТОЛИСПе. 6. Использование функции IF, PROGN для организации переходов по условиям. 7. Использование функции COND для организации переходов по условиям. 8. Организация циклов в АВТОЛИСПе. Функции REPEAT, WHILE. 9. Расширенные средства работы со списками. 10. Функции APPLY, MAPCAR. 11. LAMBDA функция и ее использование при создании пользовательских функций. 3.Задание на выполнение работы 1. Загрузить АВТОКАД и выйти в его графический редактор, обеспечив при этом работу АВТОЛИСПУ. Войти в текстовый редактор АВТОКАДА для создания или редактирования разрабатываемых программ. 2. Используя функции переходов по условиям создать функцию LEN4, которая вычисляет длину списка Х, содержащего 0...4 элемента. Убедитесь в правильности работы созданной функции. 3. Используя функции переходов по условиям создать функцию SUM4, производящую суммирование элементов списка А, состоящего из 0...4 действительных чисел. Убедитесь в правильности работы созданной функции.
25
4.Создать список S1 из элементов а, b, (c + D), 12,5, 0,08 и список S2 из элементов (ab), -10,5, "dog", "time" и образовать из них новый список S. 5.С помощью функций переходов по условиям, циклов и функции CONS создать функцию LISTY, которая формирует список SC из 10 четных чисел, если введенное число четное и список SN из 10 нечетных чисел, если введенное число нечетное. Числа в списках SC и SN расположить в порядке убывания. 6.С помощью функции MAPCAR создать функцию F1, производящую умножение каждого элемента созданного списка SN на первый элемент этого списка. 7.Обратить списки SC и SN. 8.Извлечь последние элементы из списков SN и SC и определить их длину. 9.С помощью функции MAPCAR произвести умножение каждого элемента списка SN на 3 и деление каждого элемента списка SC на 2. 10.При создании функций использовать диалог в виде запросов и подсказок, созданный функциями семейства GET и INITGET. 11. Выйти из АВТОКАДа командой END. 12. Составить отчет, который должен содержать все вводимые функции АВТОЛИСПА и возвращаемые результаты по всем пунктам задания. 4.Общие сведения Организация переходов по условию АВТОЛИСП дает возможность создавать конструкции, подобные условным переходам в языках программирования высокого уровня. В языке имеется две функции, реализующие такие конструкции - IF и COND. Для задания самих условий в этих случаях используются функции сравнения и логические функции. Функция IF Эта функция позволяет задать выполнение какой-либо операции в случае выполнения заданного условия. Кроме того имеется возможность задания альтернативной операции в случае, если условие не выполняется. Формат этой функции: (if []) При выполнении функции осуществляется проверка истинности . Если оно истинно, то выполняется и возвращается результат этого выполнения, в противном случае
26 выполняется необязательное и возвращается его результат. Если результат NIL и отсутствует , то возвращается NIL. Например: (if (= 1 3) "Да!!" "Нет") возвращает "Нет" (if (= 2 (+ 1 1)) "Да!!") возвращает "Да!!" (if (= 2 (+ 3 4)) "Да!!") возвращает nil Если по результатам тестирования нужно выполнить не одно, а несколько выражений, то используют функцию PROGN (progn ...) Эта функция вычисляет одно за другим, возвращая значение последнего из них. Функция PROGN может быть использована для вычисления нескольких выражений там, где обычно вычисляется только одно. Например: (if (= a b) (progn) (setq a (+ a 10)) (setq b (- b 10)) ) ) Функция IF обычно вычисляет одно выражение типа "then". В этом примере использование функции PROGN обеспечивает возможность вычисления не одного, а двух выражений. Функция COND в отличии от функции IF позволяет построить конструкцию,в которой можно проверять не одно, а несколько условий: (cond ( ...)...) Работает она так: вычисляется . Если оно выполняется, то выполняются действия, следующие за этим условием . Затем управление передается функциям, следующим за функцией COND. Если же не выполняется, то выражения, следующие за ним также не выполняются, а проверяется и т.д. При этом, в отличие от функции IF, за каждым условием может следовать любое количество выражений , которые нет необходимости объединять с помощью функции PROGN. Если ни одно из условий не выполняется, то работа функции COND а этом заканчивается. Функция COND является основной функцией языка АВТОЛИСП, используемой для проверки условий. Например, следующая функция COND используется для вычисления абсолютной величины:
27
(cond ((minusp a) (-a)) (t a) Если переменной "а" присвоено значение -10, функция возвращает значение 10. Функция COND может быть использована как функция выбора. Чаще всего в качестве последнего выражения типа используется константа "Т". Рассмотрим еще один простой пример. Функция проверяет ввод пользовательской строки, обозначенной символом "s", и возвращает 1, если эта строка равна "Y" или "y" и 0, если она равна "N" или "n", и "nil" в любом другом случае. (cond ((= s "Y") 1) ((= s "y") 1) ((= s "N") 0) ((= s "n") 0) (t nil) ) Организация циклов в АВТОЛИСПЕ АВТОЛИСП имеет средства организации повторных выполнений некоторого набора действий определенное количество раз или до выполнения некоторого условия. Простейшей функцией, организующей цикл, является функция REPEAT: (repeat ...) В качестве аргумента этой функции может быть задано любое целое положительное число. Функция вычисляет последовательность столько раз, сколько задано аргументом и возвращает значение последнего . Если дано: (setq a 10) (setq b 100) , то вызов (repeat 4 (setq a (+ a 10)) (setq b (+ b 10)) ) возвращает 140. Функция WHILE отличается от функции REPEAT тем, что число повторов в ней не задается, а задается условие выхода из цикла: (while ...) Эта функция проверяет и, если оно выполняется, вычисляет последовательность ; затем вновь проверяет . Это продолжается до тех пор, пока перестанет
28 выполняться; тогда цикл закончится, и функция WHILE возвратит самое последнее значение последнего . Если дано: (setq a 1) , то цикл (while (