use crate::*;
use hooo::*;
pub type Pos<A> = Or<Tauto<A>, Theory<A>>;
pub type NNPos<A> = Not<Not<Pos<A>>>;
pub type Nec<A> = Tauto<A>;
pub type StrongPos<A> = Or<Tauto<A>, Para<Uniform<A>>>;
pub fn nec_consistency() -> Nec<Not<Nec<False>>> {
fn f(_: True) -> Not<Nec<False>> {consistency()}
f
}
pub fn lob_triv<P: Prop>() -> Nec<Imply<Nec<P>, P>> {
pow_to_tauto_imply(pow_to_pow_tauto(pow_refl))
}
pub fn para_lob(x: Imply<Nec<Imply<Nec<False>, False>>, Nec<False>>) -> False {x(lob_triv())(True)}
pub fn nec_not_lob() -> Nec<Not<Imply<Nec<Imply<Nec<False>, False>>, Nec<False>>>> {
para_to_tauto_not(para_lob)
}
pub fn para_godel(x: Imply<Not<Nec<False>>, Not<Nec<Not<Nec<False>>>>>) -> False {
x(nec_consistency()(True))(nec_consistency())
}
pub fn nec_not_godel() -> Nec<Not<Imply<Not<Nec<False>>, Not<Nec<Not<Nec<False>>>>>>> {
para_to_tauto_not(para_godel)
}
pub fn npara_to_pos<A: DProp>(npara: Not<Para<A>>) -> Pos<A> {
match uniform::<A>() {
Left(tauto_a) => Left(tauto_a),
Right(para_a) => not::absurd(npara, para_a),
}
}
pub fn pos_to_npara<A: Prop>(pos: Pos<A>) -> Not<Para<A>> {
Rc::new(move |para_a| {
match pos.clone() {
Left(tauto_a) => para_a(tauto_a(True)),
Right(theory_a) => theory_a(Right(para_a)),
}
})
}
pub fn para_para_to_pos<A: DProp>(para_para_a: Para<Para<A>>) -> Pos<A> {
npara_to_pos(para_para_to_not_para(para_para_a))
}
pub fn pos_to_para_para<A: DProp>(pos: Pos<A>) -> Para<Para<A>> {
not_para_to_para_para(pos_to_npara(pos))
}
pub fn npos_to_para<A: DProp>(npos: Not<Pos<A>>) -> Para<A> {
match para_decide::<A>() {
Left(para_a) => para_a,
Right(npara_a) => not::absurd(npos, npara_to_pos(npara_a)),
}
}
pub fn para_to_npos<A: Prop>(para_a: Para<A>) -> Not<Pos<A>> {
Rc::new(move |pos| match pos {
Left(tauto_a) => para_a(tauto_a(True)),
Right(theory_a) => theory_a(Right(para_a))
})
}
pub fn npos_to_posn<A: DProp>(npos_a: Not<Pos<A>>) -> Pos<Not<A>> {
let para_a = npos_to_para(npos_a);
Left(para_to_tauto_not(para_a))
}
pub fn posn_to_npos<A: DProp>(pos_na: Pos<Not<A>>) -> Not<Pos<A>> {
Rc::new(move |pos_a| {
match (pos_a, pos_na.clone()) {
(Left(tauto_a), Left(tauto_na)) => tauto_not_to_para(tauto_na)(tauto_a(True)),
(Left(tauto_a), Right(theory_na)) => theory_na(Right(tauto_to_para_not(tauto_a))),
(Right(theory_a), Left(tauto_na)) => theory_a(Right(tauto_not_to_para(tauto_na))),
(Right(theory_a), Right(theory_na)) => {
let (ntauto_a, _) = and::from_de_morgan(theory_a);
theory_na(Left(hooo_rev_not(ntauto_a)))
}
}
})
}
pub fn nec_to_nposn<A: DProp>(tauto_a: Nec<A>) -> Not<Pos<Not<A>>> {
Rc::new(move |pos_na| posn_to_npos(pos_na)(Left(tauto_a)))
}
pub fn nposn_to_nec<A: DProp>(npos_na: Not<Pos<Not<A>>>) -> Nec<A> {
match uniform::<A>() {
Left(tauto_a) => tauto_a,
Right(para_a) => not::absurd(npos_na, npos_to_posn(para_to_npos(para_a))),
}
}
pub fn pos_to_nnecn<A: Prop>(pos_a: Pos<A>) -> Not<Nec<Not<A>>> {
Rc::new(move |tauto_na| match pos_a.clone() {
Left(tauto_a) => tauto_na(True)(tauto_a(True)),
Right(theory_a) => theory_a(Right(tauto_not_to_para(tauto_na))),
})
}
pub fn nnpos_to_nnecn<A: Prop>(x: Not<Not<Pos<A>>>) -> Not<Nec<Not<A>>> {
not::rev_triple(imply::modus_tollens(imply::modus_tollens(Rc::new(pos_to_nnecn)))(x))
}
pub fn nnecn_to_pos<A: DProp>(ntauto_na: Not<Nec<Not<A>>>) -> Pos<A> {
match uniform::<A>() {
Left(tauto_a) => Left(tauto_a),
Right(para_a) => {
not::absurd(imply::in_left(ntauto_na, |x| para_to_tauto_not(x)), para_a)
}
}
}
pub fn nnecn_to_nnpos<A: Prop>(x: Not<Nec<Not<A>>>) -> NNPos<A> {
Rc::new(move |npos_a| {
let y = and::from_de_morgan(npos_a);
y.1(and::to_de_morgan((y.0, exists_to_not_para(x.clone()))))
})
}
pub fn eq_nnpos_nnecn<A: Prop>() -> Eq<NNPos<A>, Not<Nec<Not<A>>>> {
(Rc::new(nnpos_to_nnecn), Rc::new(nnecn_to_nnpos))
}
pub fn to_nnpos<A: Prop>(a: A) -> NNPos<A> {
Rc::new(move |npos_a| {
let x = and::from_de_morgan(npos_a);
imply::in_left(x.1, and::to_de_morgan)((x.0,
exists_to_not_para(exists_true(a.clone()))))
})
}
pub fn n<A: Prop>(_: fn() -> A) -> fn() -> Nec<A> {
unimplemented!()
}
pub fn k<A: Prop, B: Prop>(x: Nec<Imply<A, B>>) -> Imply<Nec<A>, Nec<B>> {
hooo_imply(x)
}
pub fn t<A: Prop>(x: Nec<A>) -> A {x(True)}
pub fn b<A: DProp>(a: A) -> Nec<Pos<A>> {
match uniform::<Pos<A>>() {
Left(tauto_pos_a) => tauto_pos_a,
Right(para_pos_a) => {
let x: Not<Pos<A>> = Rc::new(para_pos_a);
imply::absurd()(npos_to_para(x)(a))
}
}
}
pub fn four<A: Prop>(nec_a: Nec<A>) -> Nec<Nec<A>> {pow_lift(nec_a)}
pub fn five<A: DProp>(pos_a: Pos<A>) -> Nec<Pos<A>> {
match uniform::<Pos<A>>() {
Left(tauto_pos_a) => tauto_pos_a,
Right(para_pos_a) => imply::absurd()(para_pos_a(pos_a)),
}
}
pub fn nec_to_pos<A: Prop>(nec_a: Nec<A>) -> Pos<A> {Left(nec_a)}
pub fn nec_pos_to_strong_pos<A: Prop>(x: Nec<Pos<A>>) -> StrongPos<A> {
match hooo_or(x) {
Left(tauto_tauto_a) => Left(tauto_tauto_a(True)),
Right(tauto_theory_a) => Right(tauto_not_to_para(tauto_theory_a)),
}
}
pub fn strong_pos_to_nec_pos<A: Prop>(x: StrongPos<A>) -> Nec<Pos<A>> {
use hooo::pow::PowExt;
match x {
Left(tauto_a) => tauto_a.lift().trans(Left),
Right(para_uni_a) => para_to_tauto_not(para_uni_a).trans(Right),
}
}
pub fn eq_nec_pos_strong_pos<A: Prop>() -> Eq<Nec<Pos<A>>, StrongPos<A>> {
(Rc::new(nec_pos_to_strong_pos), Rc::new(strong_pos_to_nec_pos))
}