Разработка и применение пользовательских функций
Тема № 1.
Знакомство с префиксной нотацией и примитивами ЛИСПа
Задание №1
Представить в старой и новой префиксной нотации заданное алгебраическое выражение
Новая префиксная нотация:
(- (/ (sqrt (+ (sin x) (cos x))) (+ (expt a b) (expt c d) (expt e t))) (/ (* m n k) (* q r s)))
Старая префиксная нотация:
(difference(quotient(sqrt(plus (sin x) (cos x))) (plus(pow a b) (pow c d) (pow e t))) (quotient (times m n k) (times q r s)))
Задание №2
Представить выражение на ЛИСПе в новой нотации и математической форме, вычислить выражение
Plus(quotient(difference 12 4 3)(add1 4))(sub1 0)).
Новая префиксная нотация:
(+ (/ (- 12 4 3) (1+ 4)) (1- 0))
Математическая форма:
=0
Результат:
Задание №3
Задан список M: (SETQ M ‘((x y v) (w z a))).
a) Сформировать с помощью комбинаций встроенных функций CAR и CDR языка Лисп запрос к списку M, возвращающий элемент z.
(cadadr M)
Результат:
Z
б)Определить значения следующих S-выражений:
(REVERSE M)
((W Z A) (X Y V))
(CADR M)
(W Z A)
(CAR M)
(X Y V)
(LAST M)
((W Z A))
(LENGTH M)
Задание №4
Определить значение S-выражения:
(OR (NUMBERP ‘(A B)) (LESSP 2 7 1) (EQUAL (SETQ X 1) X)))).
Результат:
Т
Тема № 2.
Разработка и применение пользовательских функций
Разработать пользовательские функции, используя функцию DEFUN.Продемонстрировать применение разработанных функций. Каждый пункт индивидуального задания выполнить в соответствии с требованиями:
(1)используя только встроенные алгебраические и логические функции;
(2)используя функционалы APPLY и MAPCAR;
(3)используя условную функцию COND;
(4)используя рекурсивные вызовы пользовательских функций;
(5)используя ƛ-функции;
(6)создавая циклы с помощью встроенных функций PROG, GO и RETURN;
(7)используя все возможности для разработки рекурсивных функций обработки списков на ЛИСПе.
Задание №1
Функция, вычисляющая площадь треугольника по формуле Герона.
(defun ger(a b c)
(sqrt(* (/(+ a b c) 2) (- (/(+ a b c) 2) a) (- (/(+ a b c) 2) b) (- (/(+ a b c) 2) c))
)
)
GER
(ger 3 4 5)
Результат:
6.0
Задание №2
Функции, вычисляющие среднее квадратическое значение числового списка.
(defun rms(l)
(sqrt (/(apply '+(mapcar '* l l)) (LENGTH l))
)
)
RMS
(rms '(1 2 3 4 5))
Результат:
3.3166253
Задание №3
Функция, программирующую нелинейную зависимость типа «люфт».
(defun gap(x a y)
(cond ((<= y (- x a)) (- x a))
((>= y (+ x a)) (+ x a))
(T y)
)
)
GAP
(gap 2 3 4)
Результат:
Задание №4
Рекурсивная функция
(defun rek (q p n)
(cond ((zerop n) (/ p (+ q (rek q p (- n 1)))))
((> n 0) (+ q (/ p (+ q (rek q p (- n 1) )))))
(t 0)
)
)
REK
(rek 15.0 5.0 10.0)
Результат:
15.165751
Задание №5
Функция, вычисляющая сумму значений функций f(x)=exp(x)*cos(x) от элементов числового списка.
(defun sum(L)
(apply '+ (mapcar (lambda(x)(* (exp x) (cos x))) L))
)
SUM
(sum '(1 2 3))
Результат:
-21.49077
Задание №6
Функция вычисляющая:
(defun odd(i)
(cond
((=(mod i 2) 0) 1)
((=(mod i 2) 1) -1)
)
)
(defun func(n) (prog(i sum subsum result)
(setq i 1)
(setq sum 0)
start (setq subsum (/(odd i)(*
(-(* 2 i) 1)
(+(* 2 i) 1)
(+(* 2 i) 3)
(+(* 2 i) 5)
(+(* 2 i) 7))))
(setq sum (+ sum subsum))
(setq i (1+ i))
(cond
((<= i n)(go start))
((> i n) (go end) ))
end (setq result(- (/ 64.0 21.0) (* 96.0 sum))) (return result) ))
FUNC
(func 5)
Результат:
3.141684
Задание №7
Функция shift, осуществляющая циклический сдвиг вперёд элементов списка.
(defun shift (L N)
(cond
((null L) nil)
((minusp N) L)
((zerop N) L)
(T (shift (append (cdr L) (cons (car L) Nil)) (1- N))
)
)
)
Результат:
(shift '(1 2 3) 1)
(2 3 1)
(shift '(1 2 3) 2)
(3 1 2)
(shift '(1 2 3) 3)
(1 2 3)
Тема № 3.
Используя свойства атомов разработать структурированную систему данных «Ракетоноситель». Разработать функции, обслуживающие структуру.
(setf (get 'launch-vehicle 'name) "Dnepr")
(setf (get (get 'launch-vehicle 'one-stage) 'ox-tank) 600)
(setf (get (get 'launch-vehicle 'one-stage) 'engine) 70000000)
(setf (get (get 'launch-vehicle 'one-stage) 'fuel-tank) 550)
(setf (get (get 'launch-vehicle 'two-stage) 'ox-tank) 600)
(setf (get (get 'launch-vehicle 'two-stage) 'engine) 70000000)
(setf (get (get 'launch-vehicle 'two-stage) 'fuel-tank) 550)
(setf (get (get 'launch-vehicle 'three-stage) 'fuel-tank) 550)
(setf (get (get 'launch-vehicle 'three-stage) 'ox-tank) 600)
(setf (get (get 'launch-vehicle 'three-stage) 'rotary-engines) 30000000)
(setf (get (get (get 'launch-vehicle 'three-stage) 'satellite) 'Sname) "Satellite-1")
(setf (get (get (get 'launch-vehicle 'three-stage) 'satellite) 'Sweight) 90)
(defun show (Property)
(cond ((get 'launch-vehicle Property))
((get (get 'launch-vehicle 'one-stage) Property))
((get (get 'launch-vehicle 'two-stage) Property))
((get (get 'launch-vehicle 'three-stage) Property))
((get (get (get 'launch-vehicle 'three-stage) 'satellite) Property))
(T nil)
)
)
(defun change (Property Value)
(cond ((get 'launch-vehicle Property)
(setf (get 'launch-vehicle Property) Value))
((get (get 'launch-vehicle 'one-stage) Property)
(setf (get (get 'launch-vehicle 'one-stage) Property) Value))
((get (get 'launch-vehicle 'two-stage) Property)
(setf (get (get 'launch-vehicle 'two-stage) Property) Value))
((get (get 'launch-vehicle 'three-stage) Property)
(setf (get (get 'launch-vehicle 'three-stage) Property) Value))
((get (get (get 'launch-vehicle 'three-stage) 'satellite) Property)
(setf (get (get (get 'launch-vehicle 'three-stage) 'satellite) Property) Value))
(T nil)
)
)
Результат:
(show 'name)
"Energy"
(change 'name "Dnepr")
"Dnepr"
(show 'name)
"Dnepr"
Итоговое Задание
Задание №1
Разработать рекурсивную функцию, заменяющую в любом месте префиксного алгебраического выражения (* f 1) на f.
(defun change(x)
(cond ((or (null x)(atom x)) x)
((and (equal (car x) '*)(equal (caddr x) '1))(change (cadr x)))
(T (mapcar 'change x))
)
)
Результат:
CHANGE
(change '(*(*(*(*(*(*(exp x)1)1)1)1)1)1))
(EXP X)
Задание №2
Разработать рекурсивную функцию, осуществляющую сложение числа с натуральным числом только с помощью функции прибавления единицы add1.
(defun sum (a b) (cond
((= b 1) (1+ a))
(t (1+ (sum a (1- b))
)
)
)
)
Результат:
SUM
(sum 14 6)
Триггер
Q2
S0
S1
Q1
S2
Q0
Описание предикатов
nand(integer,integer,integer,integer,integer) – логический элемент ИЛИ-НЕ, имеющий 4 входа и 1 выход.
trigger(integer,integer,integer,integer,integer,integer) – предикат, описывающий триггер, имеющий 3 входа и 3 выхода
Текст программы
predicates
nand(integer,integer,integer,integer,integer)
trigger(integer,integer,integer,integer,integer,integer)
clauses
nand(1,1,1,1,0).
nand(1,1,1,0,0).
nand(1,1,0,1,0).
nand(1,0,1,1,0).
nand(0,1,1,1,0).
nand(1,0,0,0,0).
nand(0,1,0,0,0).
nand(0,0,1,0,0).
nand(0,0,0,1,0).
nand(0,0,0,0,1).
nand(0,0,1,1,0).
nand(1,0,0,1,0).
nand(1,1,0,0,0).
nand(1,0,1,0,0).
nand(0,1,0,1,0).
nand(0,1,1,0,0).
trigger(S0,S1,S2,Q0,Q1,Q2):-
nand(Q0,S1,S0,Q1,Q2),
nand(Q2,S0,S2,Q0,Q1),
nand(Q1,S2,S1,Q2,Q0).
Результат: