Skip to content

Commit

Permalink
feat(cp): add EqVarMulLit to ReifExpr
Browse files Browse the repository at this point in the history
  • Loading branch information
Shi-Raida committed Oct 31, 2024
1 parent a399d63 commit 3617a6b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions solver/src/model/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod fixed;
mod int;
pub mod linear;
pub mod max;
pub mod mul;
pub mod reification;
mod sym;
mod validity_scope;
Expand Down
4 changes: 2 additions & 2 deletions solver/src/model/lang/max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::reif::ReifExpr;
use itertools::Itertools;
use std::fmt::{Debug, Formatter};

/// Constraint equivalent to `lhs = max { e | e \in rhs }
/// Constraint equivalent to `lhs = max { e | e \in rhs }`
pub struct EqMax {
lhs: IAtom,
rhs: Vec<IAtom>,
Expand All @@ -20,7 +20,7 @@ impl EqMax {
}
}

/// Constraint equivalent to `lhs = min { e | e \in rhs }
/// Constraint equivalent to `lhs = min { e | e \in rhs }`
pub struct EqMin {
lhs: IAtom,
rhs: Vec<IAtom>,
Expand Down
15 changes: 15 additions & 0 deletions solver/src/model/lang/mul.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::core::{Lit, VarRef};
use std::fmt::{Debug, Formatter};

#[derive(Eq, PartialEq, Hash, Clone)]
pub struct NFEqVarMulLit {
pub lhs: VarRef,
pub rhs: VarRef,
pub lit: Lit,
}

impl Debug for NFEqVarMulLit {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?} = {:?} * {:?}", self.lhs, self.lit, self.rhs)
}
}
11 changes: 11 additions & 0 deletions solver/src/reasoners/cp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ use crate::core::{IntCst, Lit, SignedVar, VarRef, INT_CST_MAX, INT_CST_MIN};
use crate::create_ref_type;
use crate::model::extensions::AssignmentExt;
use crate::model::lang::linear::NFLinearLeq;
use crate::model::lang::mul::NFEqVarMulLit;
use crate::reasoners::{Contradiction, ReasonerId, Theory};
use anyhow::Context;
use mul::VarEqVarMulLit;

use crate::reasoners::cp::linear::{LinearSumLeq, SumElem};
use crate::reasoners::cp::max::AtLeastOneGeq;
Expand Down Expand Up @@ -121,6 +123,15 @@ impl Cp {
self.add_propagator(propagator);
}

pub fn add_eq_var_mul_lit_constraint(&mut self, mul: &NFEqVarMulLit) {
let propagator = VarEqVarMulLit {
reified: mul.lhs,
original: mul.rhs,
lit: mul.lit,
};
self.add_propagator(propagator);
}

pub fn add_propagator(&mut self, propagator: impl Into<DynPropagator>) {
// TODO: handle validity scopes
let propagator = propagator.into();
Expand Down
13 changes: 13 additions & 0 deletions solver/src/reif/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::core::{IntCst, Lit, SignedVar, VarRef};
use crate::model::lang::alternative::NFAlternative;
use crate::model::lang::linear::NFLinearLeq;
use crate::model::lang::max::NFEqMax;
use crate::model::lang::mul::NFEqVarMulLit;
use crate::model::lang::ValidityScope;
use crate::model::{Label, Model};
use std::fmt::{Debug, Formatter};
Expand Down Expand Up @@ -32,6 +33,7 @@ pub enum ReifExpr {
Linear(NFLinearLeq),
Alternative(NFAlternative),
EqMax(NFEqMax),
EqVarMulLit(NFEqVarMulLit),
}

impl std::fmt::Display for ReifExpr {
Expand All @@ -48,6 +50,7 @@ impl std::fmt::Display for ReifExpr {
ReifExpr::Linear(l) => write!(f, "{l}"),
ReifExpr::EqMax(em) => write!(f, "{em:?}"),
ReifExpr::Alternative(alt) => write!(f, "{alt:?}"),
ReifExpr::EqVarMulLit(em) => write!(f, "{em:?}"),
}
}
}
Expand Down Expand Up @@ -75,6 +78,7 @@ impl ReifExpr {
ReifExpr::Linear(lin) => lin.validity_scope(presence),
ReifExpr::Alternative(alt) => ValidityScope::new([presence(alt.main)], []),
ReifExpr::EqMax(eq_max) => ValidityScope::new([presence(eq_max.lhs.variable())], []),
ReifExpr::EqVarMulLit(em) => ValidityScope::new([presence(em.lhs)], []),
}
}

Expand All @@ -89,6 +93,7 @@ impl ReifExpr {
OptDomain::Present(lb, ub) if lb == ub => lb,
_ => panic!(),
};
let lvalue = |lit: Lit| assignment.value(lit).unwrap();
let sprez = |svar: SignedVar| prez(svar.variable());
let svalue = |svar: SignedVar| {
if svar.is_plus() {
Expand Down Expand Up @@ -202,6 +207,13 @@ impl ReifExpr {
Some(true)
}
}
ReifExpr::EqVarMulLit(NFEqVarMulLit { lhs, rhs, lit }) => {
if prez(*lhs) && prez(*rhs) {
Some(value(*lhs) == (lvalue(*lit) as i32) * value(*rhs))
} else {
None
}
}
}
}
}
Expand Down Expand Up @@ -254,6 +266,7 @@ impl Not for ReifExpr {
ReifExpr::Linear(lin) => ReifExpr::Linear(!lin),
ReifExpr::Alternative(_) => panic!("Alternative is a constraint and cannot be negated"),
ReifExpr::EqMax(_) => panic!("EqMax is a constraint and cannot be negated"),
ReifExpr::EqVarMulLit(_) => panic!("EqVarMulLit is a constraint and cannot be negated"),
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions solver/src/solver/solver_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ impl<Lbl: Label> Solver<Lbl> {

Ok(())
}
ReifExpr::EqVarMulLit(mul) => {
self.reasoners.cp.add_eq_var_mul_lit_constraint(mul);
Ok(())
}
}
}

Expand Down

0 comments on commit 3617a6b

Please sign in to comment.