use std::collections::BTreeMap;
use std::rc::Rc;
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum Expression {
Unit,
One,
Type,
Void,
Var(String),
Sum(Branch),
Split(Branch),
Pi(Pattern, Box<Self>, Box<Self>),
Sigma(Pattern, Box<Self>, Box<Self>),
Lambda(Pattern, Box<Self>),
First(Box<Self>),
Second(Box<Self>),
Application(Box<Self>, Box<Self>),
Pair(Box<Self>, Box<Self>),
Constructor(String, Box<Self>),
Declaration(Box<Declaration>, Box<Self>),
}
pub type Branch = BTreeMap<String, Box<Expression>>;
#[derive(Debug, Clone)]
pub enum Value {
Lambda(Closure),
Unit,
One,
Type,
Pi(Box<Self>, Closure),
Sigma(Box<Self>, Closure),
Pair(Box<Self>, Box<Self>),
Constructor(String, Box<Self>),
Split(CaseTree),
Sum(CaseTree),
Neutral(Neutral),
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum GenericNeutral<Value: Clone> {
Generated(u32),
Application(Box<Self>, Box<Value>),
First(Box<Self>),
Second(Box<Self>),
Split(GenericCaseTree<Value>, Box<Self>),
}
pub type Neutral = GenericNeutral<Value>;
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum Pattern {
Pair(Box<Pattern>, Box<Pattern>),
Unit,
Var(String),
}
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum Declaration {
Simple(Pattern, Expression, Expression),
Recursive(Pattern, Expression, Expression),
}
impl Declaration {
pub fn pattern(&self) -> &Pattern {
use Declaration::*;
match self {
Simple(pattern, _, _) => pattern,
Recursive(pattern, _, _) => pattern,
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum GenericTelescope<Value: Clone> {
Nil,
UpDec(Rc<Self>, Declaration),
UpVar(Rc<Self>, Pattern, Value),
}
pub type TelescopeRaw = GenericTelescope<Value>;
pub type TelescopeRc<Value> = Rc<GenericTelescope<Value>>;
pub type Telescope = Rc<TelescopeRaw>;
pub fn up_var_rc<Value: Clone>(
me: TelescopeRc<Value>,
pattern: Pattern,
value: Value,
) -> TelescopeRc<Value> {
Rc::new(GenericTelescope::UpVar(me, pattern, value))
}
pub fn up_dec_rc<Value: Clone>(
me: TelescopeRc<Value>,
declaration: Declaration,
) -> TelescopeRc<Value> {
Rc::new(GenericTelescope::UpDec(me, declaration))
}
pub fn nil_rc<Value: Clone>() -> TelescopeRc<Value> {
Rc::new(GenericTelescope::Nil)
}
#[derive(Debug, Clone)]
pub enum Closure {
Abstraction(Pattern, Expression, Box<Telescope>),
Value(Box<Value>),
Choice(Box<Self>, String),
}
pub type GenericCaseTree<Value> = (Box<Branch>, Box<Rc<GenericTelescope<Value>>>);
pub type CaseTree = GenericCaseTree<Value>;