Add sf:rewrite-disjunction-in-conditional.
authorJoe Marshall <jmarshall@alum.mit.edu>
Mon, 8 Mar 2010 21:56:26 +0000 (13:56 -0800)
committerJoe Marshall <jmarshall@alum.mit.edu>
Mon, 8 Mar 2010 21:56:26 +0000 (13:56 -0800)
src/sf/sf.pkg
src/sf/subst.scm

index 12b0489978e561f4a2b142ce93da47739a31898e..6130b2f9e2a1cc32b53e8c76c118f2f765eb5f23 100644 (file)
@@ -94,7 +94,8 @@ USA.
          sf:enable-disjunction-inversion?
          sf:enable-disjunction-linearization?
          sf:enable-elide-double-negatives?
-         sf:enable-rewrite-conditional-in-disjunction?)
+         sf:enable-rewrite-conditional-in-disjunction?
+         sf:enable-rewrite-disjunction-in-conditional?)
   (export (scode-optimizer)
          integrate/top-level
          integrate/get-top-level-block
index 1252ad40e9fc67a5df9d1c223e302d2849a07cf7..057927e3363de609e126b769c67254d2ca2a8823 100644 (file)
@@ -192,6 +192,11 @@ USA.
                                (first (combination/operands integrated-predicate))
                                alternative consequent))
 
+       ((disjunction? integrated-predicate)
+        (integrate/disjunction-in-conditional
+         operations environment expression
+         integrated-predicate consequent alternative))
+
        (else
         (conditional/make (and expression (conditional/scode expression))
                           integrated-predicate
@@ -199,6 +204,34 @@ USA.
                           (integrate/expression (operations/prepare-false-branch operations integrated-predicate)
                                                 environment alternative)))))
 
+(define sf:enable-rewrite-disjunction-in-conditional? #t)
+;; If #t, move disjunctions out of the predicate if possible.
+
+(define (integrate/disjunction-in-conditional operations environment expression 
+                                             integrated-predicate consequent alternative)
+  (let ((e1 (disjunction/predicate integrated-predicate))
+       (e2 (disjunction/alternative integrated-predicate)))
+    ;; (if (or e1 e2) e3 e4) => (if e1 e3 (if e2 e3 e4))
+    ;; provided that e3 can be duplicated
+
+    (let* ((e3a (integrate/expression operations environment consequent))
+          ;; In any case, e4 can only be evaluated if both e1 and e2 are false
+          (if-e1-false (operations/prepare-false-branch operations e1))
+          (e4 (integrate/expression (operations/prepare-false-branch if-e1-false e2) environment alternative)))
+
+    (if (and (expression/can-duplicate? e3a)
+            (noisy-test sf:enable-rewrite-disjunction-in-conditional? "Rewriting disjunction within conditional"))
+       (conditional/make (and expression (object/scode expression))
+                         e1
+                         e3a
+                         (integrate/conditional if-e1-false environment #f
+                                                e2 e3a e4))
+       ;; nothing we can do.  Just make the conditional.
+       (conditional/make (and expression (object/scode expression))
+                         integrated-predicate
+                         e3a
+                         e4)))))
+
 ;;; CONSTANT
 (define-method/integrate 'CONSTANT
   (lambda (operations environment expression)