use super::*;
#[derive(Clone, Copy)]
pub struct FId(());
pub type Id<T> = App<FId, T>;
pub fn id_ty<A: Prop, N: Nat>(_ty_a: Ty<A, Type<N>>) -> Ty<App<FId, A>, Pow<A, A>> {
unimplemented!()
}
pub fn implicit_id_is_const() -> IsConst<FId> {unimplemented!()}
pub fn id_def<A: Prop, X: Prop, N: Nat>(
_ty_x: Ty<X, Type<N>>,
_ty_a: Ty<A, X>
) -> Eq<App<Id<X>, A>, A> {unimplemented!()}
pub fn id_is_const<A: Prop>(a_is_const: IsConst<A>) -> IsConst<App<FId, A>> {
app_is_const(implicit_id_is_const(), a_is_const)
}
pub fn id_def_type<A: Prop, N: Nat>(ty_a: Ty<A, Type<N>>) -> Eq<App<Id<Type<N>>, A>, A> {
id_def(type_ty(), ty_a)
}
pub fn theory<A: Prop, N: Nat>(ty_a: Tauto<Ty<A, Type<N>>>) -> Theory<A> {
hooo::theory_in_arg(app_theory(), ty_a.trans(id_def_type))
}
pub fn type_eq_to_q<A: Prop, B: Prop, N: Nat>(
eq_ab: Eq<A, B>,
ty_eq_ab: Tauto<Ty<Eq<A, B>, Type<N>>>,
) -> Q<A, B> {hooo::lift_q(eq_ab, theory(ty_eq_ab))}
pub fn id_qu_ty<A: Prop, N: Nat>(
ty_a: Ty<A, Type<N>>
) -> Ty<Qu<App<FId, A>>, Qu<Pow<A, A>>> {ty::qu_formation(id_ty(ty_a))}
pub fn id_qu<A: Prop>() -> Qu<App<FId, A>> {Qu::from_q(quality::right(id_q()))}
pub fn true_qu() -> Qu<True> {
use bool_alg::Bool;
let x: Ty<App<FId, Bool>, Pow<Bool, Bool>> = id_ty(bool_alg::bool_ty());
let x = ty::qu_formation(x);
let x: Qu<Pow<Bool, Bool>> = x.0(id_qu());
let y: Tauto<Eq<Pow<Bool, Bool>, True>> =
tauto!((True.map_any(), Rc::new(|_| hooo::pow_refl)));
qubit::in_arg(x, y)
}
pub fn eq_qu_true_true() -> Eq<Qu<True>, True> {(True.map_any(), true_qu().map_any())}
#[deny(unsafe_op_in_unsafe_fn)]
pub unsafe fn to_qu<A: Prop>(a: A) -> Qu<A> {
use path_semantics::ty::{ty_rev_true, qu_formation, in_left_arg, ty_true};
ty_true(in_left_arg(qu_formation(unsafe {ty_rev_true(a)}), eq_qu_true_true()))
}
pub fn tauto_to_qu<A: Prop>(tauto_a: Tauto<A>) -> Qu<A> {
qubit::in_arg(true_qu(), hooo::pow_eq_to_tauto_eq((tauto_a, hooo::tr())))
}
pub fn pow_qu<A: Prop, B: Prop>(
x: Pow<A, B>
) -> Qu<Pow<A, B>> {tauto_to_qu(hooo::pow_lift(x))}
pub fn not_qu_false() -> Not<Qu<False>> {
imply::in_left(quality::q_inv_to_sesh(Qu::to_q(qubit::in_arg(true_qu(),
tauto!((imply::id().map_any(), True.map_any()))))), Qu::to_q)
}
pub fn eq_qu_false_false() -> Eq<Qu<False>, False> {and::to_eq_neg((not_qu_false(), imply::id()))}
pub fn para_to_not_qu<A: Prop>(para_a: Para<A>) -> Not<Qu<A>> {
imply::in_left(not_qu_false(),
move |y| qubit::in_arg(y, hooo::pow_eq_to_tauto_eq((para_a, hooo::fa()))))
}
pub fn tauto_to_eq_qu<A: Prop>(tauto_a: Tauto<A>) -> Eq<Qu<A>, A> {
(tauto_a(True).map_any(), tauto_to_qu(tauto_a).map_any())
}
pub fn para_to_eq_qu<A: Prop>(para_a: Para<A>) -> Eq<Qu<A>, A> {
(Rc::new(move |qu_a| imply::absurd()(para_to_not_qu(para_a)(qu_a))),
Rc::new(move |a| imply::absurd()(para_a(a))))
}
pub fn pow_to_eq_qu<A: Prop, B: Prop>(x: Pow<A, B>) -> Eq<Qu<Pow<A, B>>, Pow<A, B>> {
tauto_to_eq_qu(x.lift())
}