use super::*;
use qubit::Qubit;
use univalence::HomEq3;
pub type IsContr<A> = IsHProp<Z, A>;
pub type IsProp<A> = Tauto<Eq<Qu<A>, A>>;
pub type IsSet<A> = IsProp<Qu<A>>;
pub type IsGroupoid<A> = IsSet<Qu<A>>;
pub type IsHProp<N, A> = Tauto<Eq<<S<N> as QuHLev>::Out<A>, <N as QuHLev>::Out<A>>>;
pub type IsNGroupoid<N, A> = IsHProp<S<S<N>>, A>;
pub trait QuHLev {
type Out<A: Prop>: Prop;
}
impl QuHLev for Z {type Out<A: Prop> = True;}
impl<N: Nat> QuHLev for S<N> {type Out<A: Prop> = Qubit<N, A>;}
pub fn is_contr_true() -> IsContr<True> {
tauto!((True.map_any(), Qubit::<Z, True>::from(True).map_any()))
}
pub fn is_prop_true() -> IsProp<True> {tauto!(eq_qu_true_true())}
pub fn is_prop_false() -> IsProp<False> {tauto!(eq_qu_false_false())}
pub fn pow_to_is_prop<A: Prop, B: Prop>(x: Pow<A, B>) -> IsProp<Pow<A, B>> {
x.lift().trans(pow_to_eq_qu)
}
pub fn is_set_id<A: Prop>() -> IsSet<App<FId, A>> {collapse_to_set_right(tauto!(id_q()))}
pub fn is_set_not() -> IsSet<bool_alg::FNot> {collapse_to_set_right(tauto!(bool_alg::not_q()))}
pub fn is_contr_to_tauto_eq_true<A: Prop>(x: IsContr<A>) -> Tauto<Eq<A, True>> {
fn f<A: Prop>(x: Eq<Qubit<Z, A>, True>) -> Eq<A, True> {
(True.map_any(), Qubit::<Z, A>::to(x.1(True)).map_any())
}
x.trans(f)
}
pub fn tauto_eq_true_to_is_contr<A: Prop>(x: Tauto<Eq<A, True>>) -> IsContr<A> {
fn f<A: Prop>(x: Eq<A, True>) -> Eq<Qubit<Z, A>, True> {
(True.map_any(), Qubit::<Z, A>::from(x.1(True)).map_any())
}
x.trans(f)
}
pub fn is_contr_to_is_prop<A: Prop>(x: IsContr<A>) -> IsProp<A> {
use hooo::{tauto_qu_eq, tauto_eq_symmetry, tauto_eq_transitivity as trans};
let y = is_contr_to_tauto_eq_true(x);
trans(trans(tauto_qu_eq(y), is_prop_true()), tauto_eq_symmetry(y))
}
pub fn is_prop_to_is_set<A: Prop>(x: IsProp<A>) -> IsSet<A> {
fn f<A: Prop>(x: IsProp<A>) -> Eq<Qu<Qu<A>>, Qu<A>> {
let x2 = hooo::tauto_eq_symmetry(x);
(Rc::new(move |y| qubit::in_arg(y, x)), Rc::new(move |y| qubit::in_arg(y, x2)))
}
x.lift().trans(f)
}
pub fn is_set_to_is_groupoid<A: Prop>(x: IsSet<A>) -> IsGroupoid<A> {is_prop_to_is_set(x)}
pub fn is_prop_to_is_groupoid<A: Prop>(x: IsProp<A>) -> IsGroupoid<A> {
is_set_to_is_groupoid(is_prop_to_is_set(x))
}
pub fn tauto_to_is_contr<A: Prop>(tauto_a: Tauto<A>) -> IsContr<A> {
tauto_eq_true_to_is_contr(hooo::tauto_to_eq_true(tauto_a))
}
pub fn is_contr_to_tauto<A: Prop>(is_contr_a: IsContr<A>) -> Tauto<A> {
hooo::tauto_from_eq_true(is_contr_to_tauto_eq_true(is_contr_a))
}
pub fn eq_tauto_is_contr<A: Prop>() -> Eq<Tauto<A>, IsContr<A>> {
hooo::pow_eq_to_tauto_eq((tauto_to_is_contr, is_contr_to_tauto))(True)
}
pub fn tauto_to_is_prop<A: Prop>(tauto_a: Tauto<A>) -> IsProp<A> {
tauto_a.lift().trans(tauto_to_eq_qu)
}
pub fn para_to_is_prop<A: Prop>(para_a: Para<A>) -> IsProp<A> {para_a.lift().trans(para_to_eq_qu)}
pub fn collapse_to_set_left<F: Prop, G: Prop>(x: Tauto<Q<F, G>>) -> IsSet<F> {
x.trans(quality::left).trans(Qu::from_q).lift().trans(tauto_to_eq_qu)
}
pub fn collapse_to_set_right<F: Prop, G: Prop>(x: Tauto<Q<F, G>>) -> IsSet<G> {
collapse_to_set_left(x.trans(quality::symmetry))
}
pub fn collapse_to_eq_qu_2<F: Prop, G: Prop>(
x: Tauto<Q<F, G>>
) -> Tauto<Eq<Qu<Qu<F>>, Qu<Qu<G>>>> {
fn h<F: Prop, G: Prop>(q: Q<F, G>) -> Eq<Qu<F>, Qu<G>> {and::to_eq_pos(q.1)}
hooo::tauto_eq_transitivity(
hooo::tauto_eq_transitivity(collapse_to_set_left(x), x.trans(h)),
hooo::tauto_eq_symmetry(collapse_to_set_right(x)))
}
pub fn collapse_to_hom_eq_3<F: Prop, G: Prop>(x: Tauto<Q<F, G>>) -> Tauto<HomEq3<F, G>> {
use qubit::{normalize, rev_normalize};
use nat::Two;
fn h<F: Prop, G: Prop>((a, b): Eq<Qu<Qu<F>>, Qu<Qu<G>>>) -> Eq<Qubit<Two, F>, Qubit<Two, G>> {
(Rc::new(move |x| normalize(a(rev_normalize(x)))),
Rc::new(move |x| normalize(b(rev_normalize(x)))))
}
hooo::hooo_rev_and((collapse_to_eq_qu_2(x).trans(h), x.trans(univalence::q_to_hom_eq_2)))
}