(save-buffer)
(let ((org-confirm-babel-evaluate
(lambda (lang body)
(declare (ignorable lang body))
nil)))
(org-latex-export-to-pdf))
(save-buffer)
(let ((python-indent-offset 4))
(org-babel-tangle))
CLOSED: [2016-05-01 Sun 14:33]
As a part of my lisp-based Computer Algebra System, an algebraic manipulation toolkit is required. This will be used to simplify equations, or for that matter solve them. This creates this toolkit, but does not create a complete simplifier or solver. It does this by providing manipulators and automatic rewriters. These together will provide simplification and solving utilities.
[0/2]
Foo
(defmacro defmanipulator (name arity &body body)
(check-type name symbol)
(check-type arity (or (integer 1 26) (eql rest) (cons symbol *)))
(cond
((listp arity)
`(defun ,name (,@arity)
,@body))
((typep arity '(integer 1 26))
(if (= arity 1)
`(defun ,name (expression)
,@body)
(let* ((letters '(a b c d e f g h i j k l m n o p q r s t u v w x y z))
(args (loop for i from 1 to arity
collect (symbolicate 'expression- (nth (1- i) letters)))))
`(defun ,name (,@args)
,@body))))
((eq arity 'rest)
`(defun ,name (&rest expressions)
,@body))))
[0/4]
Foo
Foo
Foo
Foo
Foo
(defun expression-type (expression)
(cond
((numberp expression) 'number)
((symbolp expression) 'variable)
((eq '+ (first expression)) 'additive)
((eq '- (first expression)) 'subtractive)
((and (eq '* (first expression))
(= 2 (length (rest expression)))
(expression-type-p (third expression) 'power)) 'polynomial-term)
((eq '* (first expression)) 'multiplicative)
((eq 'expt (first expression)) 'power)))
(defun expression-type-p (expression type)
(eq type (expression-type expression)))
Foo
(defun coefficient (term)
(second term))
(defun term-variable (term)
(second (third term)))
(defun get-power (term)
(cond
((expression-type-p term 'polynomial-term) (third (third term)))
((expression-type-p term 'power) (third term))))
(defun same-order-p (term-a term-b)
(= (get-power term-a)
(get-power term-b)))
(defun same-variable-p (term-a term-b)
(eq (term-variable term-a)
(term-variable term-b)))
(defun single-term-combinable-p (term-a term-b)
(and (same-order-p term-a term-b)
(same-variable-p term-a term-b)))
(defun combine-polynomial-terms (operation term-a term-b)
(if (single-term-combinable-p term-a term-b)
`(* ,(if (eq operation '+)
(+ (coefficient term-a)
(coefficient term-b))
(- (coefficient term-a)
(coefficient term-b)))
(expt ,(term-variable term-a) ,(get-power term-a)))
`(,operation ,term-a ,term-b)))
[0/6]
Foo
(defun manipulate (action &rest expressions)
(case action
(+
(reduce #'add expressions))
(-
(reduce #'subtract expressions))
(*
(reduce #'multiply expressions))
(/
(reduce #'divide expressions))
(sin
(reduce #'manip-sin expressions))
(cos
(reduce #'manip-cos expressions))
(tan
(reduce #'manip-tan expressions))
(expt
(reduce #'powers expressions))))
Foo
(defmanipulator add 2
(if (and (expression-type-p expression-b 'number)
(not (eq 'number (expression-type expression-a))))
(add expression-b expression-a)
(cond
((and (expression-type-p expression-a 'number)
(expression-type-p expression-b 'number))
(+ expression-a expression-b))
((and (expression-type-p expression-a 'number)
(expression-type-p expression-b 'additive))
(let ((total expression-a)
(the-other (rest expression-b))
(non-numbers '()))
(loop for other in the-other
do (if (numberp other)
(incf total other)
(push other non-numbers)))
(if (null non-numbers)
total
`(+ ,total ,@non-numbers))))
((and (expression-type-p expression-a 'additive)
(expression-type-p expression-b 'additive))
(let ((total 0)
(elements (append (rest expression-a)
(rest expression-b)))
(non-numerics '()))
(loop for element in elements
do (if (numberp element)
(incf total element)
(push element non-numerics)))
(if (null non-numerics)
total
`(+ ,total ,@non-numerics))))
((and (expression-type-p expression-a 'number)
(expression-type-p expression-b 'subtractive))
(let ((total expression-a)
(the-other (rest expression-b))
(non-numeric '()))
(loop for other in the-other
do (if (numberp other)
(decf total other)
(push other non-numeric)))
(if (null non-numeric)
total
`(+ ,total (- ,@(reverse non-numeric))))))
((and (expression-type-p expression-a 'polynomial-term)
(expression-type-p expression-b 'polynomial-term))
(combine-polynomial-terms '+ expression-a expression-b)))))
Foo
Foo
Foo
Foo
Foo
Foo
(defpackage #:manipulator
(:use #:cl)
(:import-from #:alexandria
#:symbolicate)
(:export #:manipulate))
(in-package #:manipulator)
<<define-expression-manipulator>>
<<determine-expression-type>>
<<combine-polynomial-terms>>
<<addition-manipulator>>
<<external-manipulator>>