Coverage report: /home/runner/work/geb/geb/src/extensions/sub-expressions.lisp 
| Kind | Covered | All | % | 
| expression | 96 | 112 | 85.7 | 
| branch | 21 | 30 | 70.0 | 
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
 
1
 (in-package :geb.extensions)3
 (deftype obj-morph () `(or cat-obj cat-morph t))5
 (-> can-continuep (t) boolean)6
 (defun can-continuep (term)7
   (and (or (typep term 'pointwise-mixin)9
        (not (typep term 'cat-obj))10
        (not (typep term 'number))11
        (not (typep term 'string))12
        (not (typep term 'geb.vampir.spec:constant))))14
 (-> common-sub-expressions (obj-morph) (values obj-morph fset:map))15
 (defun common-sub-expressions (term)16
   "Compute common sub-expressions and return an object with the17
 appropriate sub-expressions uniquely identified"18
   (if (can-continuep term)19
       (keep-unique term (compute-common-usages term))20
       (values term (fset:empty-map))))22
 (-> compute-common-usages (obj-morph) fset:bag)23
 (defun compute-common-usages (obj)24
   ;; we are going to be smart about this25
   ;; no manual recursion, we don't need that26
   (labels ((reduce-fn (bag term)27
              (cond ((not (can-continuep term))29
                    ;; we don't want to actually add30
                    ;; to a total that is already32
                    ((fset:member? term bag)35
                     (recursive (fset:with bag term) term))))38
                  (reduce #'reduce-fn term :initial-value bag)39
                  (reduce-pointwise #'reduce-fn term bag))))41
      (fset:filter-pairs (lambda (x y) (declare (ignore x)) (<= 2 y))42
                         (recursive (fset:empty-bag) obj)))))44
 (-> keep-unique (obj-morph fset:bag) (values obj-morph fset:map))45
 (defun keep-unique (obj bag)46
   "given a BAG and an term, mark each term which appears in the bag as a47
 [COMMON-SUB-EXPRESSION][type].49
 We also return the map of names that each common expression is had,50
 for further processing.52
 This is part two of the COMMON-SUB-EXPRESSIONS pass."53
   (let ((mapping (fset:image (lambda (x y)56
                              (fset:convert 'fset:map bag))))57
     (labels ((recursive (obj)58
                (if (not (can-continuep obj))60
                    (let ((looked  (fset:lookup mapping obj))63
                                (mapcar #'recursive obj)64
                                (map-pointwise #'recursive obj))))66
                          (make-common-sub-expression :obj new-obj :name looked)68
       (values (recursive obj) mapping))))