-
Notifications
You must be signed in to change notification settings - Fork 23
/
symex-computations.el
243 lines (205 loc) · 9.22 KB
/
symex-computations.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
;;; symex-computations.el --- An evil way to edit Lisp symbolic expressions as trees -*- lexical-binding: t -*-
;; URL: https://github.com/countvajhula/symex.el
;; This program is "part of the world," in the sense described at
;; https://drym.org. From your perspective, this is no different than
;; MIT or BSD or other such "liberal" licenses that you may be
;; familiar with, that is to say, you are free to do whatever you like
;; with this program. It is much more than BSD or MIT, however, in
;; that it isn't a license at all but an idea about the world and how
;; economic systems could be set up so that everyone wins. Learn more
;; at drym.org.
;;
;; This work transcends traditional legal and economic systems, but
;; for the purposes of any such systems within which you may need to
;; operate:
;;
;; This is free and unencumbered software released into the public domain.
;; The authors relinquish any copyright claims on this work.
;;
;;; Commentary:
;; Standard computations that can be performed as part of traversing symexes.
;;; Code:
(require 'cl-lib)
(require 'symex-data)
;;;;;;;;;;;;;;;;;;;;
;;; COMPUTATIONS ;;;
;;;;;;;;;;;;;;;;;;;;
(defun symex--type-integer (obj)
"Convert an object OBJ to the integer type."
(cond ((integerp obj)
obj)
((stringp obj)
(string-to-number obj))
((listp obj)
(length obj))
(t (error "Unexpected type %s in integer type conversion!" obj))))
(defun symex--type-list (obj)
"Convert an object OBJ to the list type."
(cond ((symex-traversal-p obj)
(list obj))
((listp obj)
obj)
(t (list obj))))
(cl-defun symex-make-computation (&key
components
(perceive #'identity)
(select #'identity)
(filter #'identity)
(decide #'identity)
(express #'identity)
(act #'identity))
"A computation to be performed as part of a traversal.
COMPONENTS - a list of nested computations that will each process the
input independently and produce a result. These results will then be
filtered and finally considered collectively to produce a decision.
PERCEIVE - the function to be applied to the result of each traversal step,
which transforms it to the perceived type.
SELECT - a predicate function that is applied to perceived values in order
to select the subset of perceptions that will be operated on by nested
computations.
FILTER - a predicate function to be applied to results from nested computations
to select those that will factor into the decision.
DECIDE - a binary function to be applied in combining results from nested
computations (each of the \"perceived\" type) to yield the provisional result
\(also of the perceived type).
EXPRESS - a function to transform data of the perceived type (e.g. the
type produced by the decision) to the application type (the type that can be
used by the application).
ACT - a binary function to be applied in combining results from the overall
computation (each of the \"expressed\" type) to yield the final result
\(also of the expressed type)."
(list 'computation
components
perceive
select
filter
decide
express
act))
(defun symex--computation-components (computation)
"The components of the COMPUTATION."
(nth 1 computation))
(defun symex--computation-perceive (computation)
"The perception procedure of the COMPUTATION."
(nth 2 computation))
(defun symex--computation-select (computation)
"The selection procedure of the COMPUTATION."
(nth 3 computation))
(defun symex--computation-filter (computation)
"The filtration/redaction procedure of the COMPUTATION."
(nth 4 computation))
(defun symex--computation-decide (computation)
"The decision procedure of the COMPUTATION."
(nth 5 computation))
(defun symex--computation-express (computation)
"The expression procedure of the COMPUTATION."
(nth 6 computation))
(defun symex--computation-act (computation)
"The act procedure of the COMPUTATION."
(nth 7 computation))
(defun symex--ruminate (computation components input)
"Helper to process input in nested computations.
COMPUTATION - the computation
COMPONENTS - the components of the computation
INPUT - the input."
(let ((current (car components))
(remaining (cdr components)))
(if current
(funcall (symex--computation-decide computation)
(symex-ruminate current
input)
(symex--ruminate computation
remaining
input))
input)))
(defun symex-ruminate (computation input)
"Have the COMPUTATION process the INPUT and produce a result."
(let ((perceived-input (funcall (symex--computation-perceive computation)
input)))
(let ((components (symex--computation-components computation)))
(funcall (symex--computation-express computation)
(symex--ruminate computation components perceived-input)))))
(defconst symex--computation-default
;; each result is wrapped in a list
;; the results are concatenated using list concatenation
(symex-make-computation :perceive #'symex--type-list
:act #'append))
(defun symex--side-effect-noop (&rest args)
"A null side-effect, i.e. which does nothing.
Any arguments ARGS passed in are ignored."
(interactive)
(ignore args))
(defun symex--traversal-account (obj)
"Represents the result OBJ of a traversal as a traversal."
(cond ((symex-traversal-p obj)
obj)
(t (apply #'symex-make-maneuver obj))))
;; (defconst computation-account
;; ;; each result is cast as a maneuver and wrapped in a list for composition
;; ;; the results are concatenated using list concatenation
;; (symex-make-computation :f-to-aggregation #'symex--type-list
;; :map #'symex--traversal-account
;; :reduce #'append
;; :f-from-aggregation #'car))
(defun symex--simplify-maneuver-phases (phases)
"Helper to flatten maneuver PHASES to moves."
(when phases
(let ((phase (car phases))
(remaining-phases (cdr phases)))
(let ((moves (if (symex-move-p phase)
(list phase)
(let ((simplified-phase (symex--simplify-maneuver phase)))
(symex--maneuver-phases simplified-phase)))))
(append moves
(symex--simplify-maneuver-phases remaining-phases))))))
(defun symex--simplify-maneuver (maneuver)
"Reduce a complex MANEUVER to a flat maneuver whose phases are moves."
(let ((phases (symex--maneuver-phases maneuver)))
(let* ((simplified-phases (symex--simplify-maneuver-phases phases))
(maneuver-length (length simplified-phases)))
(cond ((= maneuver-length 1)
;; just return the move
(nth 0 simplified-phases))
((> maneuver-length 1)
(apply #'symex-make-maneuver simplified-phases))))))
(defun symex--interpret-simple-traversal (traversal)
"Interpret a TRAVERSAL as a single, flat maneuver or move."
(cond ((symex-maneuver-p traversal)
(symex--simplify-maneuver traversal))
((symex-move-p traversal)
traversal)
(t (error "Syntax error: unrecognized traversal type!"))))
;; (defconst computation-simple-account
;; ;; each result is cast as a maneuver and wrapped in a list for composition
;; ;; the results are concatenated using list concatenation
;; (symex-make-computation :f-to-aggregation #'symex--type-list
;; :map (-compose #'symex--interpret-simple-traversal
;; #'symex--traversal-account)
;; :reduce #'append
;; :f-from-aggregation #'car))
(defun symex--streamline-to-maneuver (maneuver-or-move)
"Streamline traversal to a representation as a maneuver.
If MANEUVER-OR-MOVE is a maneuver, leave as is.
If it is a move, convert to the equivalent maneuver (via simple casting)."
(if (symex-move-p maneuver-or-move)
(symex-make-maneuver maneuver-or-move)
maneuver-or-move))
(defun symex--add-numbers (&rest numbers)
"Sum NUMBERS."
(apply #'+ numbers))
;; (defconst computation-length
;; ;; each result is interpreted down to a simple maneuver
;; ;; the phases of this maneuver are extracted and summed using
;; ;; move addition.
;; ;; the results are accumulated using addition of numbers
;; (symex-make-computation :f-to-aggregation #'symex--type-integer
;; :map (-compose #'symex--move-length
;; #'symex--add-moves
;; #'symex--maneuver-phases
;; #'symex--streamline-to-maneuver
;; #'symex--interpret-simple-traversal
;; #'symex--traversal-account)
;; :reduce #'symex--add-numbers
;; :f-from-aggregation #'car))
(provide 'symex-computations)
;;; symex-computations.el ends here