use crate::{
constraints::props::{Propagate, Prune},
variables::{VarId, Val},
variables::views::{Context, View},
};
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct IntEqReif {
x: VarId,
y: VarId,
b: VarId, }
impl IntEqReif {
pub fn new(x: VarId, y: VarId, b: VarId) -> Self {
Self { x, y, b }
}
}
impl Prune for IntEqReif {
fn prune(&self, ctx: &mut Context) -> Option<()> {
let x_min = self.x.min(ctx);
let x_max = self.x.max(ctx);
let y_min = self.y.min(ctx);
let y_max = self.y.max(ctx);
let b_min = self.b.min(ctx);
let b_max = self.b.max(ctx);
if x_max < y_min || y_max < x_min {
self.b.try_set_max(Val::ValI(0), ctx)?;
}
else if x_min == x_max && y_min == y_max && x_min == y_min {
self.b.try_set_min(Val::ValI(1), ctx)?;
}
if b_min >= Val::ValI(1) {
let new_min = if x_min > y_min { x_min } else { y_min };
let new_max = if x_max < y_max { x_max } else { y_max };
if new_min > new_max {
return None;
}
self.x.try_set_min(new_min, ctx)?;
self.x.try_set_max(new_max, ctx)?;
self.y.try_set_min(new_min, ctx)?;
self.y.try_set_max(new_max, ctx)?;
}
if b_max <= Val::ValI(0) {
if x_min == x_max {
if y_min == x_min && y_min < y_max {
self.y.try_set_min(y_min + Val::ValI(1), ctx)?;
} else if y_max == x_min && y_min < y_max {
self.y.try_set_max(y_max - Val::ValI(1), ctx)?;
}
} else if y_min == y_max {
if x_min == y_min && x_min < x_max {
self.x.try_set_min(x_min + Val::ValI(1), ctx)?;
} else if x_max == y_min && x_min < x_max {
self.x.try_set_max(x_max - Val::ValI(1), ctx)?;
}
}
}
Some(())
}
}
impl Propagate for IntEqReif {
fn list_trigger_vars(&self) -> impl Iterator<Item = VarId> {
[self.x, self.y, self.b].into_iter()
}
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct IntNeReif {
x: VarId,
y: VarId,
b: VarId, }
impl IntNeReif {
pub fn new(x: VarId, y: VarId, b: VarId) -> Self {
Self { x, y, b }
}
}
impl Prune for IntNeReif {
fn prune(&self, ctx: &mut Context) -> Option<()> {
let x_min = self.x.min(ctx);
let x_max = self.x.max(ctx);
let y_min = self.y.min(ctx);
let y_max = self.y.max(ctx);
let b_min = self.b.min(ctx);
let b_max = self.b.max(ctx);
if x_max < y_min || y_max < x_min {
self.b.try_set_min(Val::ValI(1), ctx)?;
}
else if x_min == x_max && y_min == y_max && x_min == y_min {
self.b.try_set_max(Val::ValI(0), ctx)?;
}
if b_min >= Val::ValI(1) {
if x_min == x_max {
if y_min == x_min && y_min < y_max {
self.y.try_set_min(y_min + Val::ValI(1), ctx)?;
} else if y_max == x_min && y_min < y_max {
self.y.try_set_max(y_max - Val::ValI(1), ctx)?;
}
} else if y_min == y_max {
if x_min == y_min && x_min < x_max {
self.x.try_set_min(x_min + Val::ValI(1), ctx)?;
} else if x_max == y_min && x_min < x_max {
self.x.try_set_max(x_max - Val::ValI(1), ctx)?;
}
}
}
if b_max <= Val::ValI(0) {
let new_min = if x_min > y_min { x_min } else { y_min };
let new_max = if x_max < y_max { x_max } else { y_max };
if new_min > new_max {
return None;
}
self.x.try_set_min(new_min, ctx)?;
self.x.try_set_max(new_max, ctx)?;
self.y.try_set_min(new_min, ctx)?;
self.y.try_set_max(new_max, ctx)?;
}
Some(())
}
}
impl Propagate for IntNeReif {
fn list_trigger_vars(&self) -> impl Iterator<Item = VarId> {
[self.x, self.y, self.b].into_iter()
}
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct IntLtReif {
x: VarId,
y: VarId,
b: VarId,
}
impl IntLtReif {
pub fn new(x: VarId, y: VarId, b: VarId) -> Self {
Self { x, y, b }
}
}
impl Prune for IntLtReif {
fn prune(&self, ctx: &mut Context) -> Option<()> {
let x_min = self.x.min(ctx);
let x_max = self.x.max(ctx);
let y_min = self.y.min(ctx);
let y_max = self.y.max(ctx);
let b_min = self.b.min(ctx);
let b_max = self.b.max(ctx);
if x_max < y_min {
self.b.try_set_min(Val::ValI(1), ctx)?;
}
else if x_min >= y_max {
self.b.try_set_max(Val::ValI(0), ctx)?;
}
if b_min >= Val::ValI(1) {
self.x.try_set_max(y_max - Val::ValI(1), ctx)?;
self.y.try_set_min(x_min + Val::ValI(1), ctx)?;
}
if b_max <= Val::ValI(0) {
self.x.try_set_min(y_min, ctx)?;
self.y.try_set_max(x_max, ctx)?;
}
Some(())
}
}
impl Propagate for IntLtReif {
fn list_trigger_vars(&self) -> impl Iterator<Item = VarId> {
[self.x, self.y, self.b].into_iter()
}
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct IntLeReif {
x: VarId,
y: VarId,
b: VarId,
}
impl IntLeReif {
pub fn new(x: VarId, y: VarId, b: VarId) -> Self {
Self { x, y, b }
}
}
impl Prune for IntLeReif {
fn prune(&self, ctx: &mut Context) -> Option<()> {
let x_min = self.x.min(ctx);
let x_max = self.x.max(ctx);
let y_min = self.y.min(ctx);
let y_max = self.y.max(ctx);
let b_min = self.b.min(ctx);
let b_max = self.b.max(ctx);
if x_max <= y_min {
self.b.try_set_min(Val::ValI(1), ctx)?;
}
else if x_min > y_max {
self.b.try_set_max(Val::ValI(0), ctx)?;
}
if b_min >= Val::ValI(1) {
self.x.try_set_max(y_max, ctx)?;
self.y.try_set_min(x_min, ctx)?;
}
if b_max <= Val::ValI(0) {
self.x.try_set_min(y_min + Val::ValI(1), ctx)?;
self.y.try_set_max(x_max - Val::ValI(1), ctx)?;
}
Some(())
}
}
impl Propagate for IntLeReif {
fn list_trigger_vars(&self) -> impl Iterator<Item = VarId> {
[self.x, self.y, self.b].into_iter()
}
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct IntGtReif {
x: VarId,
y: VarId,
b: VarId,
}
impl IntGtReif {
pub fn new(x: VarId, y: VarId, b: VarId) -> Self {
Self { x, y, b }
}
}
impl Prune for IntGtReif {
fn prune(&self, ctx: &mut Context) -> Option<()> {
let x_min = self.x.min(ctx);
let x_max = self.x.max(ctx);
let y_min = self.y.min(ctx);
let y_max = self.y.max(ctx);
let b_min = self.b.min(ctx);
let b_max = self.b.max(ctx);
if x_min > y_max {
self.b.try_set_min(Val::ValI(1), ctx)?;
}
else if x_max <= y_min {
self.b.try_set_max(Val::ValI(0), ctx)?;
}
if b_min >= Val::ValI(1) {
self.x.try_set_min(y_min + Val::ValI(1), ctx)?;
self.y.try_set_max(x_max - Val::ValI(1), ctx)?;
}
if b_max <= Val::ValI(0) {
self.x.try_set_max(y_max, ctx)?;
self.y.try_set_min(x_min, ctx)?;
}
Some(())
}
}
impl Propagate for IntGtReif {
fn list_trigger_vars(&self) -> impl Iterator<Item = VarId> {
[self.x, self.y, self.b].into_iter()
}
}
#[derive(Clone, Debug)]
#[doc(hidden)]
pub struct IntGeReif {
x: VarId,
y: VarId,
b: VarId,
}
impl IntGeReif {
pub fn new(x: VarId, y: VarId, b: VarId) -> Self {
Self { x, y, b }
}
}
impl Prune for IntGeReif {
fn prune(&self, ctx: &mut Context) -> Option<()> {
let x_min = self.x.min(ctx);
let x_max = self.x.max(ctx);
let y_min = self.y.min(ctx);
let y_max = self.y.max(ctx);
let b_min = self.b.min(ctx);
let b_max = self.b.max(ctx);
if x_min >= y_max {
self.b.try_set_min(Val::ValI(1), ctx)?;
}
else if x_max < y_min {
self.b.try_set_max(Val::ValI(0), ctx)?;
}
if b_min >= Val::ValI(1) {
self.x.try_set_min(y_min, ctx)?;
self.y.try_set_max(x_max, ctx)?;
}
if b_max <= Val::ValI(0) {
self.x.try_set_max(y_max - Val::ValI(1), ctx)?;
self.y.try_set_min(x_min + Val::ValI(1), ctx)?;
}
Some(())
}
}
impl Propagate for IntGeReif {
fn list_trigger_vars(&self) -> impl Iterator<Item = VarId> {
[self.x, self.y, self.b].into_iter()
}
}