use crate::lattice::{Coheyting, Heyting, Symmetric, conv_l, conv_r};
pub fn biheyting_coneg_neg_conv_l<T: Symmetric + Eq>(x: &T) -> bool {
x.coneg() == conv_l(&x.not()) && x.neg() == conv_l(x).not()
}
pub fn biheyting_coneg_neg_conv_r<T: Symmetric + Eq>(x: &T) -> bool {
x.coneg() == conv_r(x).not() && x.neg() == conv_r(&x.not())
}
pub fn biheyting_conv_l_join<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
conv_l(&x.join(y)) == conv_l(x).join(&conv_l(y))
}
pub fn biheyting_conv_l_meet<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
conv_l(&x.meet(y)) == conv_l(x).meet(&conv_l(y)).coneg().coneg()
}
pub fn biheyting_conv_r_join<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
conv_r(&x.join(y)) == conv_r(x).join(&conv_r(y)).neg().neg()
}
pub fn biheyting_conv_r_meet<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
conv_r(&x.meet(y)) == conv_r(x).meet(&conv_r(y))
}
pub fn biheyting_double_coneg_eq_conv_lr<T: Symmetric + Eq>(x: &T) -> bool {
x.coneg().coneg() == conv_l(&conv_r(x))
}
pub fn biheyting_double_neg_eq_conv_rl<T: Symmetric + Eq>(x: &T) -> bool {
x.neg().neg() == conv_r(&conv_l(x))
}
pub fn biheyting_double_not_join<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
x.join(y).not().not() == x.not().not().join(&y.not().not())
}
pub fn biheyting_involution<T: Symmetric + Eq>(x: &T) -> bool {
x.not().not() == *x
}
pub fn biheyting_neg_excluded_middle<T: Heyting + Eq>(x: &T) -> bool {
x.neg().join(&x.neg().neg()) == T::top()
}
pub fn biheyting_neg_le_coneg<T: Heyting + Coheyting>(x: &T) -> bool {
x.neg() <= x.coneg()
}
pub fn biheyting_not_de_morgan_join<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
x.join(y).not() == x.not().meet(&y.not())
}
pub fn biheyting_not_de_morgan_meet<T: Symmetric + Eq>(x: &T, y: &T) -> bool {
x.meet(y).not() == x.not().join(&y.not())
}
pub fn boolean_coimp_from_imp<T: Heyting + Coheyting + Eq>(x: &T, y: &T) -> bool {
x.coimp(y) == y.neg().imp(&x.neg()).neg()
}
pub fn boolean_contrapositive<T: Heyting>(x: &T, y: &T) -> bool {
if *x <= *y { y.neg() <= x.neg() } else { true }
}
pub fn boolean_double_neg_id<T: Heyting + Eq>(x: &T) -> bool {
x.neg().neg() == *x
}
pub fn boolean_excluded_middle<T: Heyting + Eq>(x: &T) -> bool {
x.join(&x.neg()) == T::top()
}
pub fn boolean_imp_from_coimp<T: Heyting + Coheyting + Eq>(x: &T, y: &T) -> bool {
x.imp(y) == y.coneg().coimp(&x.coneg()).coneg()
}
pub fn boolean_neg_eq_coneg<T: Heyting + Coheyting + Eq>(x: &T) -> bool {
x.neg() == x.coneg()
}
pub fn boolean_non_contradiction<T: Coheyting + Eq>(x: &T) -> bool {
x.meet(&x.coneg()) == T::bot()
}
pub fn coheyting_adjunction<T: Coheyting + Eq>(x: &T, y: &T, z: &T) -> bool {
(x.coimp(y) <= *z) == (*x <= y.join(z))
}
pub fn coheyting_co_currying<T: Coheyting + Eq>(x: &T, y: &T, z: &T) -> bool {
z.coimp(&x.join(y)) == z.coimp(x).coimp(y)
}
pub fn coheyting_coimp_anti_meet_2nd<T: Coheyting>(x: &T, y: &T, z: &T) -> bool {
x.coimp(y) <= x.coimp(&y.meet(z))
}
pub fn coheyting_coimp_bot_iff_ple<T: Coheyting + Eq>(x: &T, y: &T) -> bool {
(*y <= *x) == (y.coimp(x) == T::bot())
}
pub fn coheyting_coimp_dist_join<T: Coheyting + Eq>(x: &T, y: &T, z: &T) -> bool {
y.join(z).coimp(x) == y.coimp(x).join(&z.coimp(x))
}
pub fn coheyting_coimp_le_self<T: Coheyting>(x: &T, y: &T) -> bool {
x.coimp(y) <= *x
}
pub fn coheyting_coimp_mono_meet_1st<T: Coheyting>(x: &T, y: &T, z: &T) -> bool {
x.meet(z).coimp(y) <= x.coimp(y)
}
pub fn coheyting_coimp_mono_ple_1st<T: Coheyting>(x: &T, y: &T, z: &T) -> bool {
if *y <= *x {
y.coimp(z) <= x.coimp(z)
} else {
true
}
}
pub fn coheyting_comid_additive<T: Coheyting + Eq>(x: &T, y: &T) -> bool {
x.join(y).comid().join(&x.meet(y).comid()) == x.comid().join(&y.comid())
}
pub fn coheyting_comid_decomp<T: Coheyting + Eq>(x: &T) -> bool {
*x == x.comid().join(&x.coneg().coneg())
}
pub fn coheyting_coneg_anti_meet<T: Coheyting>(x: &T, y: &T) -> bool {
x.coneg() <= x.meet(y).coneg()
}
pub fn coheyting_coneg_boundary<T: Coheyting + Eq>(_: &T) -> bool {
T::bot().coneg() == T::top() && T::top().coneg() == T::bot()
}
pub fn coheyting_coneg_coimp_de_morgan<T: Coheyting + Eq>(x: &T, y: &T) -> bool {
y.coimp(x).coneg() == x.coneg().coneg().join(&y.coneg())
}
pub fn coheyting_coneg_meet_de_morgan<T: Coheyting + Eq>(x: &T, y: &T) -> bool {
x.meet(y).coneg() == x.coneg().join(&y.coneg())
}
pub fn coheyting_double_coneg_comid<T: Coheyting + Eq>(x: &T) -> bool {
x.comid().coneg().coneg() == T::bot()
}
pub fn coheyting_double_coneg_comonad<T: Coheyting>(x: &T) -> bool {
x.coneg().coneg() <= *x
}
pub fn coheyting_excluded_middle<T: Coheyting + Eq>(x: &T) -> bool {
x.join(&x.coneg()) == T::top()
}
pub fn coheyting_join_absorption<T: Coheyting + Eq>(x: &T, y: &T) -> bool {
x.join(&y.coimp(x)) == x.join(y)
}
pub fn coheyting_leibniz<T: Coheyting + Eq>(x: &T, y: &T) -> bool {
x.meet(y).comid() == x.comid().meet(y).join(&x.meet(&y.comid()))
}
pub fn coheyting_meet_coneg_ge_coimp<T: Coheyting>(x: &T, y: &T) -> bool {
x.coimp(y) <= x.meet(&y.coneg())
}
pub fn coheyting_triple_coneg<T: Coheyting + Eq>(x: &T) -> bool {
x.coneg().coneg().coneg() == x.coneg()
}
pub fn heyting_adjunction<T: Heyting + Eq>(x: &T, y: &T, z: &T) -> bool {
(x.meet(y) <= *z) == (*x <= y.imp(z))
}
pub fn heyting_currying<T: Heyting + Eq>(x: &T, y: &T, z: &T) -> bool {
x.meet(y).imp(z) == x.imp(&y.imp(z))
}
pub fn heyting_double_neg_mid<T: Heyting + Eq>(x: &T) -> bool {
x.neg().neg().mid() == T::top()
}
pub fn heyting_double_neg_monad<T: Heyting>(x: &T) -> bool {
*x <= x.neg().neg()
}
pub fn heyting_imp_anti_join_1st<T: Heyting>(x: &T, y: &T, z: &T) -> bool {
x.join(z).imp(y) <= x.imp(y)
}
pub fn heyting_imp_dist_meet<T: Heyting + Eq>(x: &T, y: &T, z: &T) -> bool {
x.imp(&y.meet(z)) == x.imp(y).meet(&x.imp(z))
}
pub fn heyting_imp_mono_join_2nd<T: Heyting>(x: &T, y: &T, z: &T) -> bool {
x.imp(y) <= x.imp(&y.join(z))
}
pub fn heyting_imp_mono_ple_2nd<T: Heyting>(x: &T, y: &T, z: &T) -> bool {
if *x <= *y {
z.imp(x) <= z.imp(y)
} else {
true }
}
pub fn heyting_imp_top_iff_ple<T: Heyting + Eq>(x: &T, y: &T) -> bool {
(*x <= *y) == (x.imp(y) == T::top())
}
pub fn heyting_modus_ponens<T: Heyting + Eq>(x: &T, y: &T) -> bool {
x.meet(&x.imp(y)) == x.meet(y)
}
pub fn heyting_neg_anti_join<T: Heyting>(x: &T, y: &T) -> bool {
x.join(y).neg() <= x.neg()
}
pub fn heyting_neg_boundary<T: Heyting + Eq>(_: &T) -> bool {
T::bot().neg() == T::top() && T::top().neg() == T::bot()
}
pub fn heyting_neg_imp_de_morgan<T: Heyting + Eq>(x: &T, y: &T) -> bool {
x.imp(y).neg() == x.neg().neg().meet(&y.neg())
}
pub fn heyting_neg_join_de_morgan<T: Heyting + Eq>(x: &T, y: &T) -> bool {
x.join(y).neg() == x.neg().meet(&y.neg())
}
pub fn heyting_neg_join_le_imp<T: Heyting>(x: &T, y: &T) -> bool {
x.neg().join(y) <= x.imp(y)
}
pub fn heyting_non_contradiction<T: Heyting + Eq>(x: &T) -> bool {
x.meet(&x.neg()) == T::bot()
}
pub fn heyting_triple_neg<T: Heyting + Eq>(x: &T) -> bool {
x.neg().neg().neg() == x.neg()
}
pub fn heyting_weakening<T: Heyting>(x: &T, y: &T) -> bool {
*y <= x.imp(&x.meet(y))
}
pub fn lattice_antisymmetric<T: Eq + PartialOrd>(x: &T, y: &T) -> bool {
if x <= y && y <= x { x == y } else { true }
}
pub fn lattice_bot<T: PartialOrd>(bot: &T, x: &T) -> bool {
bot <= x
}
#[allow(clippy::eq_op)] pub fn lattice_reflexive<T: PartialOrd>(x: &T) -> bool {
x <= x
}
pub fn lattice_top<T: PartialOrd>(top: &T, x: &T) -> bool {
x <= top
}
pub fn lattice_transitive<T: PartialOrd>(x: &T, y: &T, z: &T) -> bool {
if x <= y && y <= z { x <= z } else { true }
}