use crate::*;
use fun::{App, Type};
use hooo::Pow;
use path_semantics::Ty;
use nat::{Nat, S, Z};
#[derive(Copy, Clone)]
pub struct IsHType<N: Nat, A: Prop>(N, A);
#[derive(Copy, Clone)]
pub struct Id<T: Prop, PathP: Prop, PathQ: Prop>(T, PathP, PathQ);
#[derive(Copy, Clone)]
pub struct Refl<X: Prop, A: Prop>(X, A);
pub type IsContr<A> = IsHType<Z, A>;
pub type IsProp<A> = IsHType<S<Z>, A>;
pub type IsSet<A> = IsHType<S<S<Z>>, A>;
pub type IsNGroupoid<N, A> = IsHType<S<S<N>>, A>;
pub type IsGroupoid<A> = IsNGroupoid<S<Z>, A>;
pub fn id_ty<X: Prop, A: Prop, B: Prop, N: Nat>(
_ty_x: Ty<X, Type<N>>,
_ty_a: Ty<A, X>,
_ty_b: Ty<B, X>
) -> Ty<Id<X, A, B>, Type<N>> {unimplemented!()}
pub fn refl<A: Prop, X: Prop, PathP: Prop>(_ty_a: Ty<A, X>) -> Ty<Refl<X, A>, Id<X, A, A>>{
unimplemented!()
}
pub fn id_to_eq<A: Prop, B: Prop, X: Prop>(_: Id<X, A, B>) -> Eq<A, B> {unimplemented!()}
pub fn id_in_left_arg<A: Prop, B: Prop, C: Prop, X: Prop>(
p: Id<X, A, B>,
q: Id<X, A, C>
) -> Id<X, C, B> {Id(p.0, q.2, p.2)}
pub fn id_in_right_arg<A: Prop, B: Prop, C: Prop, X: Prop>(
p: Id<X, A, B>,
q: Id<X, B, C>
) -> Id<X, A, C> {Id(p.0, p.1, q.2)}
pub fn ap_fun<F: Prop, X: Prop, Y: Prop, A: Prop, B: Prop>(
_f: Ty<F, Pow<Y, X>>,
_p: Id<X, A, B>,
) -> Id<Y, App<F, A>, App<F, B>> {unimplemented!()}
pub fn ap_lam<F: Prop, X: Prop, Y: Prop, A: Prop, B: Prop>(
_f: Ty<F, Imply<X, Y>>,
_p: Id<X, A, B>,
) -> Id<Y, App<F, A>, App<F, B>> {unimplemented!()}
pub fn from_is_contr<A: Prop>(x: IsContr<A>) -> A {x.1}
pub fn to_is_contr<A: Prop>(x: A) -> IsContr<A> {IsHType(Z, x)}
pub fn is_htype_to_id<A: Prop, B: Prop, X: Prop, N: Nat>(
_: IsHType<S<N>, X>,
_: Ty<A, X>,
_: Ty<B, X>
) -> IsHType<N, Id<X, A, B>> {unimplemented!()}
pub fn is_prop_to_id<A: Prop, B: Prop, X: Prop>(
is_prop: IsProp<X>,
ty_a: Ty<A, X>,
ty_b: Ty<B, X>
) -> Id<X, A, B> {
from_is_contr(is_htype_to_id(is_prop, ty_a, ty_b))
}
pub fn is_set_to_is_prop<A: Prop, B: Prop, X: Prop>(
is_set: IsSet<X>,
ty_a: Ty<A, X>,
ty_b: Ty<B, X>
) -> IsProp<Id<X, A, B>> {
is_htype_to_id(is_set, ty_a, ty_b)
}
pub fn is_groupoid_to_is_set<A: Prop, B: Prop, X: Prop>(
is_groupoid: IsGroupoid<X>,
ty_a: Ty<A, X>,
ty_b: Ty<B, X>
) -> IsSet<Id<X, A, B>> {
is_htype_to_id(is_groupoid, ty_a, ty_b)
}
pub fn is_set_to_id<A: Prop, B: Prop, X: Prop, PathP: Prop, PathQ: Prop>(
is_set: IsSet<X>,
ty_a: Ty<A, X>,
ty_b: Ty<B, X>,
path_p: Ty<PathP, Id<X, A, B>>,
path_q: Ty<PathQ, Id<X, A, B>>
) -> Id<Id<X, A, B>, PathP, PathQ> {
let is_prop_eq: IsProp<Id<X, A, B>> = is_set_to_is_prop(is_set, ty_a, ty_b);
is_prop_to_id(is_prop_eq, path_p, path_q)
}
pub fn is_groupoid_to_id<
A: Prop, B: Prop, X: Prop,
PathP: Prop, PathQ: Prop, HomP: Prop, HomQ: Prop,
>(
is_groupoid: IsGroupoid<X>,
ty_a: Ty<A, X>,
ty_b: Ty<B, X>,
path_p: Ty<PathP, Id<X, A, B>>,
path_q: Ty<PathQ, Id<X, A, B>>,
hom_p: Ty<HomP, Id<Id<X, A, B>, PathP, PathQ>>,
hom_q: Ty<HomQ, Id<Id<X, A, B>, PathP, PathQ>>
) -> Id<Id<Id<X, A, B>, PathP, PathQ>, HomP, HomQ> {
let is_set_eq = is_groupoid_to_is_set(is_groupoid, ty_a, ty_b);
let is_prop_eq = is_set_to_is_prop(is_set_eq, path_p, path_q);
is_prop_to_id(is_prop_eq, hom_p, hom_q)
}
pub fn true_is_contr() -> IsContr<True> {to_is_contr(True)}