mirror of
https://github.com/powdr-labs/powdr.git
synced 2026-01-09 14:48:16 -05:00
Inline only at end (#3173)
Fixes https://github.com/powdr-labs/powdr/issues/3113 --------- Co-authored-by: Georg Wiese <georgwiese@gmail.com> Co-authored-by: schaeff <thibaut@powdrlabs.com>
This commit is contained in:
@@ -32,21 +32,28 @@ pub fn replace_constrained_witness_columns<
|
||||
.indexed_system()
|
||||
.algebraic_constraints()
|
||||
.len();
|
||||
for curr_idx in (0..constraint_count).rev() {
|
||||
let constraint = &constraint_system.indexed_system().algebraic_constraints()[curr_idx];
|
||||
loop {
|
||||
let inlined_vars_count = inlined_vars.len();
|
||||
for curr_idx in (0..constraint_count).rev() {
|
||||
let constraint = &constraint_system.indexed_system().algebraic_constraints()[curr_idx];
|
||||
|
||||
for (var, expr) in find_inlinable_variables(constraint) {
|
||||
if should_inline(&var, &expr, constraint_system.indexed_system()) {
|
||||
log::trace!("Substituting {var} = {expr}");
|
||||
log::trace!(" (from identity {constraint})");
|
||||
for (var, expr) in find_inlinable_variables(constraint) {
|
||||
if should_inline(&var, &expr, constraint_system.indexed_system()) {
|
||||
log::trace!("Substituting {var} = {expr}");
|
||||
log::trace!(" (from identity {constraint})");
|
||||
|
||||
constraint_system.substitute_by_unknown(&var, &expr);
|
||||
to_remove_idx.insert(curr_idx);
|
||||
inlined_vars.insert(var);
|
||||
constraint_system.substitute_by_unknown(&var, &expr);
|
||||
to_remove_idx.insert(curr_idx);
|
||||
inlined_vars.insert(var);
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if inlined_vars.len() == inlined_vars_count {
|
||||
// No more variables to inline
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove inlined constraints from system
|
||||
|
||||
@@ -363,6 +363,10 @@ where
|
||||
while let Some(item) = self.constraint_system.pop_front() {
|
||||
let effects = match item {
|
||||
ConstraintRef::AlgebraicConstraint(c) => {
|
||||
if let Some((v1, expr)) = is_simple_equivalence(c) {
|
||||
self.apply_assignment(&v1, &expr);
|
||||
continue;
|
||||
}
|
||||
c.solve(&self.range_constraints)
|
||||
.map_err(Error::QseSolvingError)?
|
||||
.effects
|
||||
@@ -556,6 +560,24 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn is_simple_equivalence<T: RuntimeConstant, V: Clone + Ord + Eq>(
|
||||
expr: &GroupedExpression<T, V>,
|
||||
) -> Option<(V, GroupedExpression<T, V>)> {
|
||||
if !expr.is_affine() {
|
||||
return None;
|
||||
}
|
||||
let (_, linear, offset) = expr.components();
|
||||
let [(v1, c1), (v2, c2)] = linear.collect_vec().try_into().ok()?;
|
||||
if offset.is_zero() && (c1.is_one() || c2.is_one()) && (c1.clone() + c2.clone()).is_zero() {
|
||||
Some((
|
||||
v2.clone(),
|
||||
GroupedExpression::from_unknown_variable(v1.clone()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// The currently known range constraints for the variables.
|
||||
pub struct RangeConstraints<T: FieldElement, V> {
|
||||
pub range_constraints: HashMap<V, RangeConstraint<T>>,
|
||||
|
||||
Reference in New Issue
Block a user