Do not use bus field variables. (#3171)

Removes the special introduction and removal of bus variables because
the solver can now handle this on its own through the `LinearizedSolver`
component. It also has the benefit that we do not need to run the
optimizer twice any more (once with bus interaction variables and once
without).

Previously we would introduce a new variable type outside of the solver
and replace all bus interactions `bus_interaction(1, x + y * z)` by
`bus_interaction(1, bus_var_1)` and the algebraic constraint `bus_var_1
= x + y * z`.

Now the `LinearizedSolver` is a component inside the solver that
replaces all bus interaction fields (that are not already constants or
simple variables) and also replaces all non-linear components:

`bus_interaction(1, x + y * z)`

becomes

```
bus_interaction(1, v1)
v1 = x + v2
v2 = y * z
```

The reason behind also replacing non-linear parts is because range
constraints are only stored for variables, not for all sub-expressions.
Also if we find the same non-linear sub-expression multiple times, we
can now replace it directly by the same variable.

---------

Co-authored-by: Georg Wiese <georgwiese@gmail.com>
This commit is contained in:
chriseth
2025-08-20 16:20:15 +02:00
committed by GitHub
parent 3166a8e99f
commit 5e83a8a93a
10 changed files with 79 additions and 158 deletions

View File

@@ -217,7 +217,7 @@ fn retain<V, Item>(
occurrences.retain(|_, occurrences| !occurrences.is_empty());
}
impl<T: RuntimeConstant, V: Clone + Ord + Hash> IndexedConstraintSystem<T, V> {
impl<T: RuntimeConstant, V: Clone + Eq + Hash> IndexedConstraintSystem<T, V> {
/// Adds new algebraic constraints to the system.
pub fn add_algebraic_constraints(
&mut self,

View File

@@ -68,6 +68,24 @@ impl<T: RuntimeConstant + Substitutable<V>, V: Ord + Clone + Eq + Hash + Display
}
}
impl<T: RuntimeConstant, V: Clone + Eq + Hash> JournalingConstraintSystem<T, V> {
/// Adds new algebraic constraints to the system.
pub fn add_algebraic_constraints(
&mut self,
constraints: impl IntoIterator<Item = GroupedExpression<T, V>>,
) {
self.system.add_algebraic_constraints(constraints);
}
/// Adds new bus interactions to the system.
pub fn add_bus_interactions(
&mut self,
bus_interactions: impl IntoIterator<Item = BusInteraction<GroupedExpression<T, V>>>,
) {
self.system.add_bus_interactions(bus_interactions);
}
}
impl<T: RuntimeConstant, V: Clone + Eq> JournalingConstraintSystem<T, V> {
/// Removes all algebraic constraints that do not fulfill the predicate.
pub fn retain_algebraic_constraints(

View File

@@ -1,4 +1,5 @@
use itertools::Itertools;
use num_traits::Zero;
use powdr_number::{ExpressionConvertible, FieldElement};
use crate::constraint_system::{BusInteraction, BusInteractionHandler, ConstraintRef};
@@ -84,7 +85,7 @@ where
) {
self.equivalent_expressions_cache.clear();
self.constraint_system
.add_algebraic_constraints(constraints);
.add_algebraic_constraints(constraints.into_iter().filter(|c| !c.is_zero()));
}
fn add_bus_interactions(