use std::{fmt::Debug, hash::Hash, ops::Not};
use crate::{
actions::{PropagationActions, ReasoningContext},
constraints::ReasonBuilder,
model::view::View,
};
pub trait BoolInspectionActions<Context: ?Sized>: BoolOperations {
fn val(&self, ctx: &Context) -> Option<bool>;
}
pub trait BoolOperations: Clone + Debug + Eq + Hash + Not + 'static {}
pub trait BoolPropagationActions<Context>: BoolInspectionActions<Context>
where
Context: ReasoningContext + ?Sized,
{
fn fix(
&self,
ctx: &mut Context,
val: bool,
reason: impl ReasonBuilder<Context>,
) -> Result<(), Context::Conflict>;
fn require(
&self,
ctx: &mut Context,
reason: impl ReasonBuilder<Context>,
) -> Result<(), Context::Conflict> {
self.fix(ctx, true, reason)
}
}
pub trait BoolSimplificationActions<Context>:
BoolPropagationActions<Context> + Into<View<bool>>
where
Context: ReasoningContext + ?Sized,
{
fn unify(
&self,
ctx: &mut Context,
other: impl Into<View<bool>>,
) -> Result<(), Context::Conflict>;
}
impl<T> BoolOperations for T where T: Clone + Debug + Eq + Hash + Not + 'static {}
impl<Ctx> BoolInspectionActions<Ctx> for bool {
fn val(&self, _: &Ctx) -> Option<bool> {
Some(*self)
}
}
impl<Ctx> BoolPropagationActions<Ctx> for bool
where
Ctx: ReasoningContext + PropagationActions,
{
fn fix(
&self,
ctx: &mut Ctx,
val: bool,
reason: impl ReasonBuilder<Ctx>,
) -> Result<(), <Ctx as ReasoningContext>::Conflict> {
if *self != val {
return Err(ctx.declare_conflict(reason));
}
Ok(())
}
}