/* Demonstrates a bit Boolean algebra formalised with Path Semantics. */ use prop::*; use path_semantics::*; use nat::*; use std::rc::Rc; use Either::*; // bool : type // false : bool // true : bool pub trait DeclBool>>, N: Nat> { type Bool: LProp>; type False: LProp + POrd + POrd; type True: LProp + POrd + POrd; fn ty_bool() -> Imply; fn ty_false() -> Imply; fn ty_true() -> Imply; unsafe fn const_false() -> Self::False; unsafe fn const_true() -> Self::True; fn decide() -> Or, Q>; } /// Links two memory slots. pub struct Mem(Imply>); impl Mem { /// Accesses memory. pub fn read(self) -> Imply> {self.0} } /// Function type. #[derive(Clone)] pub struct FnTy(pub Imply); // (T -> U) : type pub trait DeclFn { fn ty_fn() -> Imply, Type>; } // idb : bool -> bool // not : bool -> bool // false1 : bool -> bool // true1 : bool -> bool pub trait DeclBool1>>, N: Nat>: DeclBool + DeclFn { type Idb: LProp; type Not: LProp; type False1: LProp; type True1: LProp; fn ty_idb() -> Imply>; fn ty_not() -> Imply>; fn ty_false1() -> Imply>; fn ty_true1() -> Imply>; fn def_idb(_idb: Self::Idb, f: Mem) -> And< Imply, Q, Self::False>>, Imply, Q, Self::True>>, > where X: POrd> { let f1 = f.0.clone(); let f2 = f.0.clone(); (Rc::new(move |eq_x_false| { let p = assume_naive(); p((eq_x_false, (f1.clone(), imply::id()))) }), Rc::new(move |eq_x_true| { let p = assume_naive(); p((eq_x_true, (f2.clone(), imply::id()))) }) ) } fn def_not(_not: Self::Not, f: Mem) -> And< Imply, Q, Self::True>>, Imply, Q, Self::False>>, > where X: POrd> { let f = f.read(); let f1 = f.clone(); let f2 = f.clone(); (Rc::new(move |eq_x_false| { let p = assume_naive(); p((eq_x_false, (f1.clone(), unsafe {Self::const_true().map_any()}))) }), Rc::new(move |eq_x_true| { let p = assume_naive(); p((eq_x_true, (f2.clone(), unsafe {Self::const_false().map_any()}))) }) ) } fn def_false1(_false1: Self::False1, f: Imply>) -> And< Imply, Q, Self::False>>, Imply, Q, Self::False>>, > where X: POrd> { let f1 = f.clone(); let f2 = f.clone(); (Rc::new(move |eq_x_false| { let p = assume_naive(); p((eq_x_false, (f1.clone(), unsafe {Self::const_false().map_any()}))) }), Rc::new(move |eq_x_true| { let p = assume_naive(); p((eq_x_true, (f2.clone(), unsafe {Self::const_false().map_any()}))) }) ) } fn def_true1(_true1: Self::True1, f: Imply>) -> And< Imply, Q, Self::True>>, Imply, Q, Self::True>>, > where X: POrd> { let f1 = f.clone(); let f2 = f.clone(); (Rc::new(move |eq_x_false| { let p = assume_naive(); p((eq_x_false, (f1.clone(), unsafe {Self::const_true().map_any()}))) }), Rc::new(move |eq_x_true| { let p = assume_naive(); p((eq_x_true, (f2.clone(), unsafe {Self::const_true().map_any()}))) }) ) } } pub fn proof, X: LProp, Type: LProp>( f1: Mem, f2: Mem, idb: T::Idb, not: T::Not, eq_x_true: Q, ) -> And, T::True>, Q, T::False>> where X: POrd> { let idb_expr = T::def_idb(idb, f1); let not_expr = T::def_not(not, f2); (idb_expr.1(eq_x_true.clone()), not_expr.1(eq_x_true.clone())) } pub fn proof2, X: LProp, Type: LProp>( f1: Mem, f2: Mem>, idb: T::Idb, not: T::Not, eq_x_true: Q, ) -> Q>, T::False> where X: POrd>, Inc: POrd>> { let idb_expr = T::def_idb(idb, f1); let not_expr = T::def_not(not, f2); let x2 = idb_expr.1(eq_x_true.clone()); not_expr.1(x2) } pub fn proof3< T: DeclBool1, X: LProp, Type: LProp >( f1: Mem, f2: Mem>, not: T::Not, ) where X: POrd>, Inc: POrd>> { let not_expr = T::def_not(not.clone(), f1); let not_expr2 = T::def_not(not, f2); match T::decide() { Left(eq_x_false) => { let x1 = not_expr.0(eq_x_false); let x2 = not_expr2.1(x1); check_q::(x2) } Right(eq_x_true) => { let x1 = not_expr.1(eq_x_true); let x2 = not_expr2.0(x1); check_q::(x2) } } } fn main() {}