@@ -264,3 +264,58 @@ In category terms, `a → c^b` is isomorphic to `a → b → c`
264264 (curry (right (comp fun (gather fst x y))))))
265265 (prod (curry (curry (prod-left-assoc fun)))))))
266266 (rec f (mcar dom) (mcadr dom)))))))
267+
268+ (defun reducer (morph &optional (seen-set (fset :empty-set)))
269+ ; ; handle the piss easy cases, do the hard tracking later
270+ (typecase-of substmorph morph
271+ (alias (reducer morph))
272+ (project-left morph)
273+ (project-right morph)
274+ (inject-left morph)
275+ (inject-right morph)
276+ (terminal morph)
277+ (init morph)
278+ (distribute morph)
279+ (pair (pair (reducer (mcar morph))
280+ (reducer (mcdr morph))))
281+ (case (mcase (reducer (mcar morph))
282+ (reducer (mcadr morph))))
283+ (comp
284+ (let* ((linearized (linearize-comp morph))
285+ ; ; this code is absolutely horrible
286+ (left (mvfoldr (lambda (g flist)
287+ (let ((new-g (reducer g)))
288+ (typecase (car flist)
289+ (pair
290+ (typecase new-g
291+ (project-left (cons (mcar (car flist))
292+ (cdr flist)))
293+ (project-right (cons (mcdr (car flist))
294+ (cdr flist)))
295+ (otherwise (cons new-g flist))))
296+ (otherwise
297+ (cons new-g flist)))))
298+ (butlast linearized)
299+ (list (reducer (car (last linearized))))))
300+ (constructed (if (cdr left)
301+ (apply #' comp left)
302+ (car left))))
303+ ; ; g 。f
304+ (if (fset :member? constructed seen-set)
305+ (comp (reducer (mcar constructed)) (reducer (mcadr constructed)))
306+ (reducer constructed (fset :with seen-set constructed)))))
307+ (substobj morph)
308+ (otherwise (subclass-responsibility morph))))
309+
310+ (defmethod fset :compare ((a <substmorph>) (b <substmorph>))
311+ (if (and (eq (type-of a)
312+ (type-of b))
313+ (obj-equalp a b))
314+ :equal
315+ :unequal ))
316+
317+ (defun linearize-comp (morph)
318+ (if (typep morph ' comp)
319+ (append (linearize-comp (mcar morph))
320+ (linearize-comp (mcadr morph)))
321+ (list morph)))
0 commit comments