use crate::ast::*;
use crate::check::normal::*;
use std::fmt::Display;
use std::rc::Rc;
pub fn generate_value(id: u32) -> Value {
use crate::ast::GenericNeutral as Neutral;
Value::Neutral(Neutral::Generated(id))
}
pub trait ReadBack: Sized {
type NormalForm: Eq + Display;
fn read_back(self, index: u32) -> Self::NormalForm;
fn read_back_please(self) -> Self::NormalForm {
self.read_back(0)
}
fn normal(index: u32, me: Self, other: Self) -> (Self::NormalForm, Self::NormalForm) {
let me_read_back = me.read_back(index);
let other_read_back = other.read_back(index);
(me_read_back, other_read_back)
}
}
impl ReadBack for Value {
type NormalForm = NormalExpression;
fn read_back(self, index: u32) -> Self::NormalForm {
use crate::check::normal::NormalExpression::*;
match self {
Value::Lambda(closure) => Lambda(
index,
Box::new(
closure
.instantiate(generate_value(index))
.read_back(index + 1),
),
),
Value::Unit => Unit,
Value::One => One,
Value::Type => Type,
Value::Pi(input, output) => Pi(
Box::new(input.read_back(index)),
index,
Box::new(
output
.instantiate(generate_value(index))
.read_back(index + 1),
),
),
Value::Sigma(first, second) => Sigma(
Box::new(first.read_back(index)),
index,
Box::new(
second
.instantiate(generate_value(index))
.read_back(index + 1),
),
),
Value::Pair(first, second) => Pair(
Box::new(first.read_back(index)),
Box::new(second.read_back(index)),
),
Value::Constructor(name, body) => Constructor(name, Box::new(body.read_back(index))),
Value::Split((case_tree, context)) => {
Split((case_tree, Box::new(context.read_back(index))))
}
Value::Sum((constructors, context)) => {
Sum((constructors, Box::new(context.read_back(index))))
}
Value::Neutral(neutral) => Neutral(neutral.read_back(index)),
}
}
}
impl ReadBack for &TelescopeRaw {
type NormalForm = NormalTelescope;
fn read_back(self, index: u32) -> Self::NormalForm {
use crate::ast::GenericTelescope::*;
match self {
Nil => Rc::new(Nil),
UpDec(context, declaration) => {
Rc::new(UpDec(context.read_back(index), declaration.clone()))
}
UpVar(context, pattern, val) => Rc::new(UpVar(
context.read_back(index),
pattern.clone(),
val.clone().read_back(index),
)),
}
}
}
impl ReadBack for Neutral {
type NormalForm = NormalNeutral;
fn read_back(self, index: u32) -> Self::NormalForm {
use crate::ast::GenericNeutral::*;
match self {
Generated(index) => Generated(index),
Application(function, argument) => Application(
Box::new(function.read_back(index)),
Box::new(argument.read_back(index)),
),
First(neutral) => First(Box::new(neutral.read_back(index))),
Second(neutral) => Second(Box::new(neutral.read_back(index))),
Split((case_tree, context), body) => Split(
(case_tree, Box::new(context.read_back(index))),
Box::new(body.read_back(index)),
),
}
}
}