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