Browse Source

Don't bother to start a disjunction branch at a disjunction node

If you have an Or that's a child of an Or, for example, there's no point
considering the child Or to be its own disjunction branch, since each of
the children of _that_ Or will be its own disjunction branch.
Ian Goldberg 4 months ago
parent
commit
bf90a33cbf
1 changed files with 38 additions and 4 deletions
  1. 38 4
      sigma_compiler_core/src/sigma/combiners.rs

+ 38 - 4
sigma_compiler_core/src/sigma/combiners.rs

@@ -205,8 +205,9 @@ impl StatementTree {
     /// A _disjunction node_ is an [`Or`](StatementTree::Or) or
     /// [`Thresh`](StatementTree::Thresh) node in the [`StatementTree`].
     ///
-    /// A _disjunction branch_ is a subtree rooted at the child of a
-    /// disjunction node, or at the root of the [`StatementTree`].
+    /// A _disjunction branch_ is a subtree rooted at a non-disjuction
+    /// node that is the child of a disjunction node, or at the root of
+    /// the [`StatementTree`].
     ///
     /// The _disjunction invariant_ is that a private variable (which is
     /// necessarily a `Scalar` since there are no private `Point`
@@ -375,8 +376,16 @@ impl StatementTree {
         closure: &mut dyn FnMut(&mut StatementTree) -> Result<()>,
         is_new_branch: bool,
     ) -> Result<()> {
-        if is_new_branch {
-            (closure)(self)?;
+        // We're starting a new branch (and should call the closure) if
+        // and only if both is_new_branch is true, and also we're at a
+        // non-disjuction node
+        match self {
+            StatementTree::Leaf(_) | StatementTree::And(_) => {
+                if is_new_branch {
+                    (closure)(self)?;
+                }
+            }
+            _ => {}
         }
         match self {
             StatementTree::Leaf(_) => {}
@@ -1048,6 +1057,31 @@ mod test {
             ],
         );
 
+        disjunction_branch_leaf_tester(
+            parse_quote! {
+               AND (
+                   C = c*B + r*A,
+                   D = d*B + s*A,
+                   OR (
+                       c = d,
+                       OR (
+                           c = d + 1,
+                           c = d + 2,
+                        )
+                   )
+               )
+            },
+            vec![
+                vec![
+                    parse_quote! { C = c*B + r*A },
+                    parse_quote! { D = d*B + s*A },
+                ],
+                vec![parse_quote! { c = d }],
+                vec![parse_quote! { c = d + 1 }],
+                vec![parse_quote! { c = d + 2 }],
+            ],
+        );
+
         disjunction_branch_leaf_tester(
             parse_quote! {
                 AND (