use super::*;
#[derive(Copy, Clone)]
pub struct FInv(());
pub fn finv_is_const() -> IsConst<FInv> {unimplemented!()}
pub type Inv<F> = App<FInv, F>;
pub type Injective<F, A, B> = Imply<Eq<App<F, A>, App<F, B>>, Eq<A, B>>;
pub type Surjective<F, X, Y, B, A> = Imply<
And<Ty<F, Pow<X, Y>>, Ty<B, Y>>,
Exists<Ty<A, X>, Eq<App<F, A>, B>>
>;
pub type SplitEpic<F> = Qu<Comp<F, Inv<F>>>;
pub type SplitMonic<F> = Qu<Comp<Inv<F>, F>>;
pub fn inv_ty<F: Prop, X: Prop, Y: Prop>(
_ty_f: Ty<F, Pow<Y, X>>
) -> Ty<Inv<F>, Pow<X, Y>> {unimplemented!()}
pub fn inv_val_qu<F: Prop, A: Prop, B: Prop>(
_: Qu<Inv<F>>,
_: Eq<App<F, A>, B>
) -> Eq<App<Inv<F>, B>, A> {unimplemented!()}
pub fn inv_involve<F: Prop>(_: Inv<Inv<F>>) -> F {unimplemented!()}
pub fn involve_inv<F: Prop>(_: F) -> Inv<Inv<F>> {unimplemented!()}
pub fn self_inv_to_q<F: Prop>(_: Eq<Inv<F>, F>) -> Q<Inv<F>, F> {unimplemented!()}
pub fn path<F: Prop, X: Prop, Y: Prop>(
_: Theory<F>,
_: Qu<Inv<F>>,
_: Ty<F, Pow<Y, X>>,
_: Pow<Y, X>
) -> And<F, Inv<F>> {unimplemented!()}
pub fn id_inv<X: Prop>() -> Eq<Inv<App<FId, X>>, App<FId, X>> {unimplemented!()}
pub fn comp_right_inv_to_id<F: Prop, A: Prop, B: Prop>(
_: SplitEpic<F>,
_: Ty<F, Pow<B, A>>,
_: Comp<F, Inv<F>>
) -> App<FId, B> {unimplemented!()}
pub fn id_to_comp_right_inv<F: Prop, A: Prop, B: Prop>(
_: SplitEpic<F>,
_: Ty<F, Pow<B, A>>,
_: App<FId, B>
) -> Comp<F, Inv<F>> {unimplemented!()}
pub fn comp_left_inv_to_id<F: Prop, A: Prop, B: Prop>(
_: SplitMonic<F>,
_: Ty<F, Pow<B, A>>,
_: Comp<Inv<F>, F>
) -> App<FId, A> {unimplemented!()}
pub fn id_to_comp_left_inv<F: Prop, A: Prop, B: Prop>(
_: SplitMonic<F>,
_: Ty<F, Pow<B, A>>,
_: App<FId, A>
) -> Comp<Inv<F>, F> {unimplemented!()}
pub fn comp_rev_inv<F: Prop, G: Prop>(_: Inv<Comp<G, F>>) -> Comp<Inv<F>, Inv<G>> {
unimplemented!()
}
pub fn comp_inv<F: Prop, G: Prop>(_: Comp<Inv<F>, Inv<G>>) -> Inv<Comp<G, F>> {
unimplemented!()
}
pub fn inv_is_const<F: Prop>(a: IsConst<F>) -> IsConst<Inv<F>> {app_is_const(finv_is_const(), a)}
pub fn inv_val<F: Prop, G: Prop, A: Prop, B: Prop>(
x: Q<Inv<F>, G>,
y: Eq<App<F, A>, B>
) -> Eq<App<Inv<F>, B>, A> {inv_val_qu(Qu::<Inv<F>>::from_q(quality::left(x)), y)}
pub fn inv_val_other<F: Prop, G: Prop, A: Prop, B: Prop>(
x: Q<Inv<F>, G>,
y: Eq<App<F, A>, B>
) -> Eq<App<G, B>, A> {eq::in_left_arg(inv_val(x.clone(), y), app_map_eq(quality::to_eq(x)))}
pub fn involve_eq<F: Prop>() -> Eq<Inv<Inv<F>>, F> {
hooo::pow_eq_to_tauto_eq((inv_involve, involve_inv))(True)
}
pub fn path_inv<F: Prop, X: Prop, Y: Prop>(
theory_f: Theory<F>,
qu_inv_f: Qu<Inv<F>>,
ty_f: Ty<F, Pow<Y, X>>,
x: Pow<Y, X>
) -> Pow<X, Y> {ty::ty_true(ty::triv(inv_ty(ty_f.clone()), path(theory_f, qu_inv_f, ty_f, x).1))}
pub fn qu_tauto_eq_to_q<F: Prop, G: Prop>(x: Qu<F>, tauto_eq: Tauto<Eq<F, G>>) -> Q<F, G> {
(tauto_eq(True), (x.clone(), hooo::qu_in_arg(x, tauto_eq)))
}
pub fn qu_double<F: Prop>(x: Qu<F>) -> Qu<Inv<Inv<F>>> {
qu_tauto_eq_to_q(x, hooo::pow_eq_to_tauto_eq((involve_inv, inv_involve))).1.1
}
pub fn qu_rev_double<F: Prop>(x: Qu<Inv<Inv<F>>>) -> Qu<F> {
qu_tauto_eq_to_q(x, hooo::pow_eq_to_tauto_eq((inv_involve, involve_inv))).1.1
}
pub fn eq_qu_double<F: Prop>() -> Eq<Qu<F>, Qu<Inv<Inv<F>>>> {
(Rc::new(qu_double), Rc::new(qu_rev_double))
}
pub fn inv_eq<F: Prop, G: Prop>(x: Eq<F, G>) -> Eq<Inv<F>, Inv<G>> {app_eq(x)}
pub fn qu_inv_tauto_eq_to_qu_inv<F: Prop, G: Prop>(
x: Qu<Inv<F>>,
tauto_eq: Tauto<Eq<F, G>>
) -> Qu<Inv<G>> {qu_tauto_eq_to_q(x, hooo::pow_transitivity(tauto_eq, inv_eq)).1.1}
pub fn inv_double_val<F: Prop, X: Prop>() -> Eq<App<Inv<Inv<F>>, X>, App<F, X>> {
app_map_eq(involve_eq())
}
pub fn inv_rev_val_qu<F: Prop, A: Prop, B: Prop>(
qu_f: Qu<F>,
x: Eq<App<Inv<F>, A>, B>
) -> Eq<App<F, B>, A> {
eq::in_left_arg(inv_val_qu(qu_double(qu_f.clone()), x), app_map_eq(involve_eq()))
}
pub fn qu_to_app_eq<A: Prop, B: Prop, F: Prop>(
qu_f: Qu<F>, qu_inv_f: Qu<Inv<F>>
) -> Eq<Eq<App<F, A>, B>, Eq<App<Inv<F>, B>, A>> {
(Rc::new(move |y| inv_val_qu(qu_inv_f.clone(), y)),
Rc::new(move |y| inv_rev_val_qu(qu_f.clone(), y)))
}
pub fn inv_swap_eq<F: Prop, G: Prop>(x: Eq<Inv<F>, G>) -> Eq<Inv<G>, F> {
eq::symmetry(eq::in_left_arg(inv_eq(x), involve_eq()))
}
pub fn inv_rev_eq<F: Prop, G: Prop>(x: Eq<Inv<F>, Inv<G>>) -> Eq<F, G> {
eq::in_right_arg(eq::in_left_arg(inv_eq(x), involve_eq()), involve_eq())
}
pub fn id_q<A: Prop>() -> Q<Inv<App<FId, A>>, App<FId, A>> {self_inv_to_q(id_inv())}
pub fn self_inv_ty<F: Prop, A: Prop, B: Prop>(
ty_f: Ty<F, Pow<B, A>>
) -> Ty<Q<F, Inv<F>>, Q<Pow<B, A>, Pow<A, B>>> {ty::q_formation(ty_f.clone(), inv_ty(ty_f))}
pub fn self_inv_to_eq_id<F: Prop, A: Prop>(
ty_f: Ty<F, Pow<A, A>>,
eq_f: Eq<Inv<F>, F>
) -> Eq<Comp<F, F>, App<FId, A>> {
let x = inv::self_inv_to_q(eq_f.clone());
let qu_f = qubit::Qubit::from_q(quality::right(x.clone()));
let qu_inv_f = qubit::Qubit::from_q(quality::left(x));
let qu_comp_f_inv_f = comp::comp_qu(qu_inv_f, qu_f);
let qu_comp_f_inv_f_2 = qu_comp_f_inv_f.clone();
let ty_f_2 = ty_f.clone();
let eq_f_2 = eq_f.clone();
(
Rc::new(move |x| comp_right_inv_to_id(qu_comp_f_inv_f.clone(), ty_f_2.clone(),
comp_in_right_arg(x, eq::symmetry(eq_f_2.clone())))),
Rc::new(move |x| comp_in_right_arg(id_to_comp_right_inv(qu_comp_f_inv_f_2.clone(),
ty_f.clone(), x), eq_f.clone())),
)
}
pub fn split_epic<F: Prop, G: Prop, H: Prop, X: Prop, Y: Prop, A: Prop>(
qu_comp_f_inv_f: SplitEpic<F>,
x: Eq<Comp<G, F>, Comp<H, F>>,
ty_f: Ty<F, Pow<X, A>>,
ty_g: Ty<G, Pow<Y, X>>,
ty_h: Ty<H, Pow<Y, X>>,
) -> Eq<G, H> {
let x: Eq<Comp<Comp<G, F>, Inv<F>>, Comp<Comp<H, F>, Inv<F>>> = comp_eq_left(x);
let x: Eq<Comp<G, Comp<F, Inv<F>>>, _> = eq::in_left_arg(x, eq::symmetry(comp_assoc()));
let x: Eq<_, Comp<H, Comp<F, Inv<F>>>> = eq::in_right_arg(x, eq::symmetry(comp_assoc()));
let y: Eq<Comp<F, Inv<F>>, Id<X>> = eq_comp_right_inv_id(qu_comp_f_inv_f, ty_f);
let x: Eq<Comp<G, Id<X>>, _> = eq::in_left_arg(x, comp_eq_right(y.clone()));
let x: Eq<_, Comp<H, Id<X>>> = eq::in_right_arg(x, comp_eq_right(y));
let x: Eq<G, _> = eq::in_left_arg(x, comp_id_right(ty_g));
let x: Eq<_, H> = eq::in_right_arg(x, comp_id_right(ty_h));
x
}
pub fn split_monic<F: Prop, G: Prop, H: Prop, X: Prop, Y: Prop, A: Prop>(
qu_comp_inv_f_f: SplitMonic<F>,
x: Eq<Comp<F, G>, Comp<F, H>>,
ty_f: Ty<F, Pow<Y, X>>,
ty_g: Ty<G, Pow<X, A>>,
ty_h: Ty<H, Pow<X, A>>,
) -> Eq<G, H> {
let x: Eq<Comp<Inv<F>, Comp<F, G>>, Comp<Inv<F>, Comp<F, H>>> = comp_eq_right(x);
let x: Eq<Comp<Comp<Inv<F>, F>, G>, _> = eq::in_left_arg(x, comp_assoc());
let x: Eq<_, Comp<Comp<Inv<F>, F>, H>> = eq::in_right_arg(x, comp_assoc());
let y: Eq<Comp<Inv<F>, F>, Id<X>> = eq_comp_left_inv_id(qu_comp_inv_f_f, ty_f);
let x: Eq<Comp<Id<X>, G>, _> = eq::in_left_arg(x, comp_eq_left(y.clone()));
let x: Eq<_, Comp<Id<X>, H>> = eq::in_right_arg(x, comp_eq_left(y));
let x: Eq<G, _> = eq::in_left_arg(x, comp_id_left(ty_g));
let x: Eq<_, H> = eq::in_right_arg(x, comp_id_left(ty_h));
x
}
pub fn eq_comp_left_inv_id<F: Prop, A: Prop, B: Prop>(
qu_comp_inv_f_f: SplitMonic<F>,
ty_f: Ty<F, Pow<B, A>>
) -> Eq<Comp<Inv<F>, F>, Id<A>> {
let ty_f2 = ty_f.clone();
let qu_comp_inv_f_f_2 = qu_comp_inv_f_f.clone();
(Rc::new(move |x| comp_left_inv_to_id(qu_comp_inv_f_f.clone(), ty_f.clone(), x)),
Rc::new(move |x| id_to_comp_left_inv(qu_comp_inv_f_f_2.clone(), ty_f2.clone(), x)))
}
pub fn eq_comp_right_inv_id<F: Prop, A: Prop, B: Prop>(
qu_comp_f_inv_f: SplitEpic<F>,
ty_f: Ty<F, Pow<B, A>>
) -> Eq<Comp<F, Inv<F>>, Id<B>> {
let ty_f2 = ty_f.clone();
let qu_comp_f_inv_f_2 = qu_comp_f_inv_f.clone();
(Rc::new(move |x| comp_right_inv_to_id(qu_comp_f_inv_f.clone(), ty_f.clone(), x)),
Rc::new(move |x| id_to_comp_right_inv(qu_comp_f_inv_f_2.clone(), ty_f2.clone(), x)))
}
pub fn comp_inv_qu<F: Prop, G: Prop>(x: Qu<Inv<F>>, y: Qu<Inv<G>>) -> Qu<Inv<Comp<G, F>>> {
qubit::in_arg(comp_qu(y, x), tauto!(eq_comp_inv()))
}
pub fn eq_comp_inv<F: Prop, G: Prop>() -> Eq<Comp<Inv<F>, Inv<G>>, Inv<Comp<G, F>>> {
(Rc::new(comp_inv), Rc::new(comp_rev_inv))
}