Пример программы на lisp

Для хранения большого количества данных в лиспе используются массивы.
Массив — это переменных, ячеек, имеющих одно имя, но разные номера, обеспечивающие доступ к этим ячейкам.

Для определения массива заданной размерности используется функция make-array (make-array ) поддерживаются только одномерные массивы-векторы.

Пример :
(setq data (make-array 10))

# (0 0 0 0 0 0 0 0 0 0)
data — имя массива,
0 — начальное наполнение.

Доступ производится с помощью функции aref. AREF имеет два аргумента — имя массива и индекс и возвращает значение ячейки
(aref )
* (aref data 8)
0,

так как там записан 0.

Особенности: первый аргумент не блокируется, первая ячейка имеет номер 0.

Поместить данные в массив можно ,используя функцию setf

* (setf (aref data 2) ‘dog)
aref -вызывает значение ячейки, функция setf помещает значение.

Рассмотрим массив testdata
(setq testdata (make-array 4))
# * (setf (aref testdata 1) ‘dog)

Пример простой программы на LISP


* (setf (aref testdata 0) 18 )
* (setf (aref testdata 2) ‘(a b) )
* (setf (aref testdata 3) 4 )

Можно (setq testdata ( vector 18 ‘dog ‘(a b) 0)) (aref d 1)

В результате получим
testdata 0 1 2 3
18 dog (a b) 0

Можно использовать эти данные
(cons (aref testdata 1) (list (aref testdata 3)
(aref testdata 2)))

(dog 0 ( a b))
(aref testdata (aref testdata 3))
18

Так как доступ к элементам массива производится по номерам, то удобно использовать численные итерации и рекурсии.

Рассмотрим функцию, которая берет два аргумента имя массива и его длину и возвращает все значения, помещенные в список
(defun array-list (arnam len)
(do (( i 0 ( + 1 i))
( result nil (append result (list (aref arnam i)))))
(( equal i len) result)))
(array-list testdata 4)
( 18 dog (a b) 0)

(array-length ) возвращает длину массива.
(array-length testdata) возвращает длину массива 4.

Обычная блокировка не позволяет вычислять выражения
* ‘(a b c)
(a b c)

Иногда возникает необходимость вычислить только часть выражения.
Если
(setq b ‘(x y z))
И мы запишем
* `( a ,b c) ,то b — будет вычислено и мы получим
(a (x y z) c)
` — обратная верхняя запятая обозначает блокировку, которая может частично сниматься запятой.
Обратная блокировка может использоваться при печати:
(setq n ‘john)
(setq m ‘Robert)
(print `(boys ,n and ,m))
(boys john and roberts)

Наиболее часто обратная блокировка используется в мощном средстве лиспа — макросах.

Это специальное средство,позволяющее формировать вычисляемое выражение в ходе выполнения программы.

Рассмотрим например функцию blancs , которая производит n переводов каретки (пропускает n линий)
(defun blancs (n)
(do ((count n ( — count 1)))
(( zerop count) nil)

Язык LISP для студентов и инженеров. Первая программа


(terpri)))

(blancs 4) пропустит четыре строки.

Будем писать программу, которая позволит выполнять некоторое действие n раз
Для blancs:
(do-times ‘(terpri) 4)
Или
(do-times ‘(print ‘hello) 3)
Напечатает hello три раза

Можно через eval определить
(defun do-times (operation n)
(do ((count n ( — count 1)))
(( zerop count) nil)
(eval operation)))

Это можно сделать также через специальную форму : defmacro

(defmacro do-times (operation n)
` (do ((count ,n ( — count 1)))
(( zerop count) nil)
,operation))

Как видно, форма макро похожа на определение функции, но есть отличия :

1. Аргументы макро не вычисляются перед их использованием.
Тогда обращение записывается:
(do-times (print ‘hello) 3)

2. Когда макро вызывается, лисп сначала вычисляет тело макро, а затем выполняет получившееся выражение.
Например,после обращения
(do-times (print ‘hello) 3)
Получим
(do ((count 3 ( — count 1)))
(( zerop count) nil)
(print ‘hello))
Этот список потом вычисляется.
Таким образом при вызове макро сначала вычисляется тело (этап называется расширением) и формируется выражение.
На втором этапе вычисляется полученное выражение, и полученное значение возвращается как результат.
Вызывая macro с разными аргументами получим разные результаты. Если мы вызываем:
(do-times (print count) 10)

После вычисления тела получим:
(do ((count 10 ( — count 1)))
(( zerop count) nil)
(print count))

Печатается числа от 10 до 1.
Можно определить функцию обратной печати чисел

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

(defun print-number (n)
(do-times (print count) n))
( print-number 5)

При разработке макро необходимо выполнить три шага:

  1. Написать пример функции,которую должна формировать макро,
  2. Выделить общие части для нескольких функций и переменные. Переменные части обозначить переменными, выделить запятыми и вынести в аргументы. Постоянные части записать напрямую.
  3. Определить макро,которое реализует этот вызов.

Шаг1. Сформулируем пример. Запишем тело для поиска чисел:

(setq l ‘(s d 3 d)) (setq item 5) _ (do (( tail l (cdr tail))) ((null tail) nil) ( cond ((numberp (car tail)) (return (car tail))))) ~~~~~~~
Шаг2. Выделяем общие части список lis — l и предикат predicate — number .
(defmacro term-search ( predicate lis) ` (do (( tail , lis (cdr tail))) ((null tail) nil) (cond ((,predicate (car tail)) (return (car tail))))))

Напишем программу дифференцирования алгебраических выражений. Для наглядности ограничимся алгебраическими выражениями в следующей форме:
(+ x y) (* x y)

Сложение и умножение можно свободно комбинировать.
Например,
(*(+ a ( * a b)) c) Программируя непосредственно получаем

(defun diff0 ( l x) (cond (( atom l) (if (eq l x) 1 ;l=1 0));l=константа (( eq (first l) ‘+) (list ‘+ (diff0 (second l) x) (diff0 (third l) x))) (( eq (first l) ‘*) (list ‘+ (list ‘* (diff0 (second l) x) (third l)) (list ‘* (diff0 (third l) x) (second l)))) (t l)))
Испoльзуем
(diff0 ‘(+ x (* 3 x)) ‘x) ( + 1 (+ (* 0 x) (* 1 3))) = 4 (diff0 ‘(- x (* 3 x)) ‘x) return (- x (* 3 x)) Why? (diff0 ‘(* x ( + x 1)) ‘x) (+ (* 1 ( x 1))(*(1 0) x))
Вычисляемые выражения не упрощаются,хотя это не трудно сделать.

Эта программа неудобна,так как трудно расширять,приходится все группировать в один cond. Она не является модульной.
Мы получим более удобное решение,если для каждого действия определим свою дифференцирующую функцию и через свойство diff свяжем эту функцию с символом ,обозначающим действие.

Прoстим запись самой дифференцирующей функции:

(defun dif1 (l x) (cond (( atom l) (if (eq l x) 1 0)) ( t (funcall (get (first l) ‘diff) (cdr l) x))))
Функции дифференцирования становятся значениями свойства ‘diff :

(setf (get ‘+ ‘diff) ‘dif+) (setf (get ‘* ‘diff) ‘dif*)
Таким образом извлекаем действие из данных. Сами функции записываются:

(defun dif* (l x) (list ‘+ (list ‘* (dif1 (first l) x) (second l)) (list ‘* (dif1 (second l) x) (first l)))) (defun dif+ (l x) (list ‘+ (dif1 (first l) x) (dif1 (second l) x)))
Благодаря модульности можно дополнить для —
(defun dif- (l x) (list ‘- (dif1 (first l) x) (dif1 second l) x)))

Таким образом, первоначальное упрaвление вычислительным процессом, связанное со структурой программы, мы преобразовали в динамическое управление основанное на данных.
Можно использовать макросы.
Определим макрос defdif , c помощью которого определяются дифференцирующие функции для новых действий:

(defmacro defdif (act args body) `(setf (get ‘,act ‘diff) ‘(lambda,args,body)))
Тогда дифф. функции задаются:
(defdif + (l x) (list ‘+ (dif1 (first l) x) (dif1 (second l) x))) (defdif * (l x) (list ‘+ (list ‘* (dif1 (first l) x) (second l)) (list ‘* (dif1 (second l) x) (first l)))) (dif1 ‘(+ x x) ‘x) (defdif — (l x) (list ‘- (dif1 (first l) x) (dif1 (second l) x))) (dif1 ‘(+ x (* 3 x)) ‘x) (dif1 ‘(- x (* 3 x)) ‘x) (dif1 ‘(* x ( — x 1)) ‘x)

Дополним программу несколькими функциями,обеспечивающими ввод информации:
Чтение дифф. списка
(defun read-list () (princ » diff-list ? «) (setq l (read)))

Пусть продолжает вычисления до тех пор пока не будет введено не d.

(defun d () (princ «enter command : d -diff;q — quit») (terpri) (if (eq (read) ‘d) (progn (read-list) (print (dif1 l ‘x )) (terpri) (d)) ‘end))
Вызов программы теперь (d)

Можно сразу загружать программу и начать ее выполнение, для этого используют функцию load
(load )

Записываются обычным образом,но \ надо использовать двойные.
(load «diff1») и сразу начинается выполнение.

(c) M.N.Morozov, 1999.

Источник: www.mari-el.ru

Язык программирования Lisp: функции, синтаксис, среда разработки

легкие цены

Более сорока лет назад разработан и внедрен в использование для выполнения целей искусственного интеллекта язык программирования LISP (ЛИСП), позднее ставший популярным среди пользователей ПО AutoCAD. Он создан для символьных вычислений. С течением времени был преобразован, чтобы соответствовать новым потребностям ИИ.

Читайте также:
Кто может стать участником программы молодежи доступное жилье

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

Это imperative language (императивный), действия которого описывают выполнение алгоритма, отличается от других, декларативных, предполагающих определение ограничений и соотношений в предметной сфере поставленной цели. По сравнению с другими подобными разработками С++ и FORTRAN, ЛИСП наделен большей функциональностью. Его популярность обусловлена большими возможностями для программирования в сочетании с мощным набором:

Это средства построения данных структур обозначения высокого уровня.

Конструкция

LISP синтаксис и семантика, разработанные программистами, обусловлены теорией рекурсивных функций. Символьные, s-выражения, являются элементами предложений, сочетаний. В них представлены софты и файлы. Они могут отображаться в виде списка (list) или атомов (atom).

язык lisp

Несколько поочередно идущих абзацев составляют каталог. Они обязательно разделяются пробелами и замыкаются в скобки.

установка lisp

Составляющими одних перечислений могут служить другие, более мелкие, подпункты. Символьные структуры разной формы и уровня сложности можно создавать благодаря произвольной углубленности и вложенности. Существует пустая строка, она обозначается – () и называется «nill». При возведении информационной структуры, а также при способе управления ею, она играет особенную роль, представляясь одновременно и атомом, и списком.

Язык LISP относится к языкам программирования, которые используются для создания дополнительных загрузок к ПО по проектированию и моделированию. Для их использования необязательно хорошо разбираться в компьютере на уровне профессионала.

После изучения основных принципов работы в таких пакетах, как AutoCAD или ZWCAD Professional, который является аналогом ACAD, появляется необходимость упростить выполнение длительных рутинных операций или полностью избавиться от них. Для этого дополнения и нужны. Если они написаны на ЛИСПе, скрипты называются LISP-приложения.

Каждое из них представляет собой текстовый файл с определенным встроенным кодом для выполнения команды и подсказками от производителя. Определитесь с нужными для работы свойствами, выбирайте надстройку, скачивайте ее и загружайте в ZWCAD или другую платформу. Начиная с версии ZWCAD 2020, в платформу встроен Отладчик Lisp приложений, разработанный на базе Visual Studio Code от Microsoft.

Рассмотрим возможности одного такого модуля на образце скрипта «Выравнивание текстов».

Источник: sapr-soft.ru

Урок 2. Пример простой программы на LISP.

LISP или AutoLISP это традиционный язык программирования для AutoCAD. С его помощью можно создавать свои программы в любой области проектирования. Создание таких программ избавляет пользователя от типовых, рутинных операций и существенно повышают производительность работы в AutoCAD.

В этом уроке мы рассмотрим пример простой программы на языке LISP. Подробно разберем ее программный код. В следующих уроках, двигаясь от простого к сложному, мы будем ее постепенно усложнять и модифицировать. Я надеюсь, что в результате, вы получите знания, которые сделают вашу работу в Автокад более эффективной.

Приставленные примеры предполагают, что у читателя уже есть начальные знания работы в AutoCAD.

Для выполнения примера нам понадобиться только программа AutoCAD. Специальная инсталляция AutoLISP не требуется. Он поставляется с каждой копией AutoCADа.

И первое с чего мы должны начать – это поставить перед собой задачу. И в качестве примера я предлагаю написать программу, которая попросит нас указать базовую точку р1. и после указания, построит куб со сторонами 200.

Пример программы LISP

Программный код мы будем писать в редакторе «Visual Lisp». Чтобы его открыть, в начале нужно запустить AutoCAD.

Далее на ленте выбираем вкладку «Управление» и на панели «Приложение» щелкаем на пункте «Редактор Visual Lisp»

редактор Visual lisp

Создаем новый файл: щелкаем на кнопку обведенную красным .

Visual lisp

И в открывшимся окне, набираем текст нашей программы или копируем его с сайта

lisp

Программный код на языке LISP:

(DEFUN c:mp_kub (/ p1 p2 p3 p4 p5 p6 p7 p8) ; начало функции mp_kub (setq p1 (getpoint «nУкажите базовую точку : «)) ; запрос координат базовой точки (setq p2 (polar p1 0 200)) ; определение координат точки р2 (setq p3 (polar p2 (/ pi 2) 200)) ; определение координат точки р3 (setq p4 (polar p3 pi 200)) ; определение координат точки р4
(setq p5 (polar p1 (/ pi 4) 200)) ; определение координат точки р5 (setq p6 (polar p2 (/ pi 4) 200)) ; определение координат точки р6 (setq p7 (polar p3 (/ pi 4) 200)) ; определение координат точки р7 (setq p8 (polar p4 (/ pi 4) 200)) ; определение координат точки р8
(setq osm (getvar «osmode»)) ; запоминаем привязки пользователя (setvar «osmode» 0) ; отключаем привязки
(command «_line» p1 p2 p3 p4 p1 «») ; рисуем передную грань (command «_line» p5 p6 p7 p8 p5 «») ; рисуем задную грань (command «_line» p1 p5 «») ; рисуем линию 1-5 (command «_line» p2 p6 «») ; рисуем линию 2-6 (command «_line» p3 p7 «») ; рисуем линию 3-7 (command «_line» p4 p8 «») ; рисуем линию 4-8
(setvar «osmode» osm) ; возвращает привязки пользователя ) ; окончание функции

Читайте также:
Лучшая программа 3d моделирования для Андроид

 Скачать программу Mp_kub.lsp

Скачать программу Mp_kub.lsp (Размер файла: 449 bytes)

В программном коде после «;» можно оставлять свои комментарии, которые в дальнейшем никак не влияют на выполнение команды.

Давая имя командам и файлам, стараемся присвоить им уникальные имена. Чтобы в дальнейшем избежать пересечения со стандартными командами или с командами созданными другими пользователями. Я назову наш файл и команду «mp_kub» (подразумевая my program Kub)

В конце сохраняем нашу программу в удобном для вас месте. Я сохраняю ее в папке «D:/MyLisp» под именем «mp_kub».

Пример программы LISP

Теперь, чтобы использовать нашу программу в AutoCADе, ее предварительно нужно загрузить. Щелкаем по кнопке выделенной зеленым .

lisp

Если программа набрана без ошибок. Ниже в окне «Консоль Visual LISP» появиться надпись о том, что наша программа загружена.

консоль Visual lisp

Переходим в AutoCAD, вводим «mp_kub» в командную строку и нажимаем Enter.

Пример программы LISP

Появится подсказка: «Укажите базовую точку :» Щелкните в любой точки рабочего окна AutoCAD и он нарисует куб.

Пример программы LISP

ДОПОЛНИТЕЛЬНЫЕ ПОЯСНЕНИЯ .

Давайте более подробно разберем функции языка LISP, которые мы использовали в программном коде.

(defun c:mp_kub (/ p1 p2 p3 p4 p5 p6 p7 p8) )

Создание функции пользователя с именем «mp_kub».

Префикс «с:» означает, что эту функцию можно будет использовать как стандартную команду AutoCAD. Достаточно ввести имя в командную строку AutoCADа.

( / p1 p2 p3 p4 p5 p6 p7 p8 ) – временные переменные, которые используются в выражениях.

(setq p1 (getpoint «nУкажите базовую точку : «))

Функция getpoint – даёт возможность пользователю указать точку при помощи мыши.

Результатом функции будут координаты точки указанные пользователем.

«nУкажите базовую точку : » — текст приглашения.

Префикс «n» означает переход на новую командную строку.

Функция присвоения (setq p1 ) позволяет сохранить в переменной p1.

(setq p2 (polar p1 0 200))

Пример программы LISP

Функция ( polar p1 0 200 ) вычисляет координаты точки отстоящей от точки р1 на расстояние 200 в направлении луча образующим с ось Х угол 0 радиан.

( setq p2 ) — Затем эти координаты присваиваются р2 .

(command «_line» p1 p2 p3 p4 p1 «»)

Функция command выполняет стандартные функции AutoCADа. В нашем случаи проводит отрезки по точкам с координатами р1, р2, р3, р4, р1 .

«_line» — имя стандартной функции AutoCAD.

«» — имитирует нажатие клавиши .

Таким образом в этой статье мы узнали:

Как запускать редактор Visual Lisp.

Как создавать программу на языке Lisp.

Как загружать программу и как запускать ее на выполнение.

Чтобы лучше, понять, как работают функции, поэкспериментируйте с ними, поменяйте какие либо значения, посмотрите, как это повлияет на результат.

В дополнение к этому уроку смотрите видео: Пример простой программы на LISP.

В следующем уроке мы будем учится создавать кнопку для запуска своих программ.

Пишите в комментариях: все ли у вас получилось?; трудно ли было выполнить этот урок?; где у вас возникли трудности? Я с удовольствием отвечу на все ваши комментарии.

Если вы хотите получать новости с моего сайта. Оформляйте подписку.

Источник: acad-prog.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru