-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathbetter-units.el
61 lines (52 loc) · 1.28 KB
/
better-units.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
(require 'utils)
(require 'recur)
(defstruct unit-atom name type abbreviation conversions)
(defstruct unit-comp num den)
(defalias 'unit-atom? #'unit-atom-p)
(defalias 'unit-comp? #'unit-comp-p)
(defun u*2 (u1 u2)
(make-unit-comp
:num
(cond
((and (unit-atom? u1)
(unit-atom? u2))
(list u1 u2))
((and (unit-atom? u1)
(unit-comp? u2))
(cons u1 (unit-comp-num u2)))
((and (unit-comp? u1)
(unit-atom? u2))
(suffix (unit-comp-num u1) u2))
((and (unit-comp? u1)
(unit-comp? u2))
(append (unit-comp-num u1)
(unit-comp-num u2))))
:den
(cond
((and (unit-atom? u1)
(unit-atom? u2))
(list u1 u2))
((and (unit-atom? u1)
(unit-comp? u2))
(cons u1 (unit-comp-den u2)))
((and (unit-comp? u1)
(unit-atom? u2))
(suffix (unit-comp-den u1) u2))
((and (unit-comp? u1)
(unit-comp? u2))
(append (unit-comp-den u1)
(unit-comp-den u2))))))
(defun u* (&rest us)
(reduce #'u*2 us))
(defun u-invert (u)
(if (unit-atom? u)
(make-unit-comp
:num '()
:den (list u))
(make-unit-comp
:num (unit-comp-den u)
:den (unit-comp-num u))))
(defun u/ (u1 &rest us)
(apply #'u* u1 (mapcar #'u-invert us)))
(u* (make-unit-atom :name 'grams :type 'mass :conversions '())
(make-unit-atom :name 'seconds :type 'time :conversions '()))