@@ -127,9 +127,9 @@ pub(crate) trait IteratorConstraintsExtension<T> {
127127
128128 /// Returns the constraints under which every element of the iterator holds.
129129 ///
130- /// This method short-circuits; if we encounter any element that
131- /// [`is_never_satisfied`][ConstraintSet::is_never_satisfied], then the overall result
132- /// must be as well, and we stop consuming elements from the iterator .
130+ /// This method is not guaranteed to short-circuit — we might invoke your callback for later
131+ /// iterator elements even if you produce
132+ /// [`is_never_satisfied`][ConstraintSet::is_never_satisfied] for earlier elements.
133133 fn when_all < ' db > (
134134 self ,
135135 db : & ' db dyn Db ,
@@ -156,13 +156,9 @@ where
156156 db : & ' db dyn Db ,
157157 mut f : impl FnMut ( T ) -> ConstraintSet < ' db > ,
158158 ) -> ConstraintSet < ' db > {
159- let mut result = ConstraintSet :: always ( ) ;
160- for child in self {
161- if result. intersect ( db, f ( child) ) . is_never_satisfied ( db) {
162- return result;
163- }
164- }
165- result
159+ let inputs: Vec < _ > = self . map ( |element| f ( element) . node ) . collect ( ) ;
160+ let node = Node :: distributed_and ( db, & inputs) ;
161+ ConstraintSet { node }
166162 }
167163}
168164
@@ -1203,6 +1199,20 @@ impl<'db> Node<'db> {
12031199 }
12041200 }
12051201
1202+ fn distributed_and ( db : & ' db dyn Db , inputs : & [ Self ] ) -> Self {
1203+ match inputs {
1204+ [ ] => Node :: AlwaysTrue ,
1205+ [ one] => * one,
1206+ [ first, second] => first. and_with_offset ( db, * second) ,
1207+ _ => {
1208+ let ( first, second) = inputs. split_at ( inputs. len ( ) / 2 ) ;
1209+ let first = Self :: distributed_and ( db, first) ;
1210+ let second = Self :: distributed_and ( db, second) ;
1211+ first. and ( db, second)
1212+ }
1213+ }
1214+ }
1215+
12061216 /// Returns the `and` or intersection of two BDDs.
12071217 ///
12081218 /// In the result, `self` will appear before `other` according to the `source_order` of the BDD
0 commit comments