pub type Level = u64;
pub type CtorIdx = u64;
pub type IndId = u64;
pub type Idx = u64;
pub type MetaId = u64;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Term {
Var(Idx),
Sort(Level),
Pi(Box<Term>, Box<Term>),
Lam(Box<Term>, Box<Term>),
App(Box<Term>, Box<Term>),
Let(Box<Term>, Box<Term>, Box<Term>),
Ind(IndId, Vec<Term>),
Ctor(IndId, CtorIdx, Vec<Term>),
Elim(IndId, Box<Term>, Vec<Term>, Box<Term>),
EqSubst(Box<Term>, Box<Term>, Box<Term>),
Const(u64),
Meta(MetaId),
}
impl Term {
pub fn prop() -> Self { Term::Sort(0) }
pub fn type0() -> Self { Term::Sort(1) }
pub fn prop_max(u: Level, v: Level) -> Level {
if u == 0 || v == 0 { 0 } else { u.max(v) }
}
pub fn is_kernel_term(&self) -> bool {
match self {
Term::Meta(_) => false,
Term::Var(_) | Term::Sort(_) | Term::Const(_) => true,
Term::Pi(a, b) | Term::Lam(a, b) | Term::App(a, b) =>
a.is_kernel_term() && b.is_kernel_term(),
Term::Let(a, v, b) =>
a.is_kernel_term() && v.is_kernel_term() && b.is_kernel_term(),
Term::Ind(_, ps) => ps.iter().all(|p| p.is_kernel_term()),
Term::Ctor(_, _, args) => args.iter().all(|a| a.is_kernel_term()),
Term::Elim(_, m, cs, tg) =>
m.is_kernel_term()
&& cs.iter().all(|c| c.is_kernel_term())
&& tg.is_kernel_term(),
Term::EqSubst(p, h, pf) =>
p.is_kernel_term() && h.is_kernel_term() && pf.is_kernel_term(),
}
}
}