Skip to content

Commit

Permalink
chore: Add basic simplification step before reification.
Browse files Browse the repository at this point in the history
  • Loading branch information
arbimo committed Dec 1, 2023
1 parent 56b9ff1 commit 3da5b94
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions solver/src/model/model_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,44 @@ impl<Lbl: Label> Model<Lbl> {
/// If the expression was already interned, the handle to the previously inserted
/// instance will be returned.
pub fn reify<Expr: Reifiable<Lbl>>(&mut self, expr: Expr) -> Lit {
let decomposed = expr.decompose(self);
let mut decomposed = expr.decompose(self);
self.simplify(&mut decomposed);
self.reify_core(decomposed, false)
}

fn simplify(&self, expr: &mut ReifExpr) {
let entailed = |lit| {
if self.state.current_decision_level() == DecLvl::ROOT {
self.entails(lit)
} else {
lit == Lit::TRUE
}
};
let negated = |lit: Lit| entailed(!lit);
match expr {
ReifExpr::Or(disjuncts) if disjuncts.iter().any(|&l| entailed(l)) => *expr = ReifExpr::Lit(Lit::TRUE),
ReifExpr::Or(disjuncts) => {
disjuncts.retain(|&l| !negated(l));
match disjuncts.len() {
0 => *expr = ReifExpr::Lit(Lit::FALSE),
1 => *expr = ReifExpr::Lit(disjuncts[0]),
_ => {}
}
}
ReifExpr::And(conjuncts) if conjuncts.iter().any(|&l| negated(l)) => *expr = ReifExpr::Lit(Lit::FALSE),
ReifExpr::And(conjuncts) => {
conjuncts.retain(|l| !entailed(*l));
match conjuncts.len() {
0 => *expr = ReifExpr::Lit(Lit::TRUE),
1 => *expr = ReifExpr::Lit(conjuncts[0]),
_ => {}
}
}
ReifExpr::Linear(lin) => *lin = lin.simplify(),
_ => {}
}
}

pub(crate) fn reify_core(&mut self, expr: ReifExpr, use_tautology: bool) -> Lit {
if let Some(l) = self.shape.expressions.interned(&expr) {
l
Expand Down Expand Up @@ -403,7 +437,8 @@ impl<Lbl: Label> Model<Lbl> {
/// is valid and absent otherwise.
pub fn enforce<Expr: Reifiable<Lbl>>(&mut self, expr: Expr, scope: impl IntoIterator<Item = Lit>) {
debug_assert_eq!(self.state.current_decision_level(), DecLvl::ROOT);
let expr = expr.decompose(self);
let mut expr = expr.decompose(self);
self.simplify(&mut expr);

let scope = self.new_conjunctive_presence_variable(scope);
debug_assert!(
Expand Down

0 comments on commit 3da5b94

Please sign in to comment.