id typechecks
This commit is contained in:
parent
9dd6779950
commit
f479cf0420
7 changed files with 248 additions and 140 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -78,6 +78,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"contracts",
|
||||
"dashmap",
|
||||
"derivative",
|
||||
"env_logger",
|
||||
"im",
|
||||
"lalrpop",
|
||||
|
@ -198,6 +199,17 @@ dependencies = [
|
|||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
|
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
anyhow = { version = "1.0.75", features = ["backtrace"] }
|
||||
contracts = { version = "0.6.3" }
|
||||
dashmap = "5.5.3"
|
||||
derivative = "2.2.0"
|
||||
env_logger = "0.10.0"
|
||||
im = "15.1.0"
|
||||
lalrpop-util = { version = "0.20.0", features = ["lexer", "regex", "unicode"] }
|
||||
|
|
|
@ -3,7 +3,6 @@ use anyhow::{bail, Result};
|
|||
use crate::data::{Context, ContextEntry, FreeVar, Monotype, Term, Type};
|
||||
use crate::gensym::gensym_existential;
|
||||
|
||||
|
||||
// Figure 8. Applying a context, as a substitution, to a type
|
||||
|
||||
#[cfg_attr(feature = "trace_execution", trace)]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use anyhow::{bail, Result};
|
||||
|
||||
use crate::data_debruijn::{Context, ContextIndex, ContextItem, Term, Type};
|
||||
use crate::data_debruijn::{
|
||||
Context, ContextEntry, ContextIndex, Monotype, Term, Type,
|
||||
};
|
||||
use crate::DEPTH;
|
||||
|
||||
// Figure 8. Applying a context, as a substitution, to a type
|
||||
|
@ -54,7 +56,7 @@ pub fn subtype(ctx: &Context, left: &Type, right: &Type) -> Result<Context> {
|
|||
instantiate_left(ctx, a, ty_a)
|
||||
}
|
||||
|
||||
(Type::Unit, Type::Var(_)) => todo!(),
|
||||
(Type::Unit, Type::Var(_)) => todo!("wtf? {left:?} {right:?}"),
|
||||
(Type::Unit, Type::Existential(_)) => todo!(),
|
||||
(Type::Unit, Type::Polytype(_)) => todo!(),
|
||||
(Type::Unit, Type::Arrow(_, _)) => todo!(),
|
||||
|
@ -96,7 +98,19 @@ pub fn instantiate_left(
|
|||
if ctx.get_existential(a).is_some()
|
||||
&& ctx.get_existential(b).is_some() =>
|
||||
{
|
||||
todo!()
|
||||
let mut new_ctx = ctx.clone();
|
||||
{
|
||||
let b_entry = new_ctx
|
||||
.vector
|
||||
.get_mut(b.debruijn_level)
|
||||
.expect("should exist");
|
||||
|
||||
*b_entry =
|
||||
ContextEntry::ExistentialSolved(Monotype::Existential(a.to_owned()));
|
||||
}
|
||||
|
||||
Ok(new_ctx)
|
||||
// todo!("helloge: a={a:?} , b={b:?} // {ctx:?}")
|
||||
}
|
||||
|
||||
Type::Existential(_b) => todo!(),
|
||||
|
@ -125,7 +139,6 @@ pub fn typecheck(ctx: &Context, term: &Term, ty: &Type) -> Result<Context> {
|
|||
|
||||
// Sub rule
|
||||
(term, ty) => {
|
||||
println!("SUB RULE: {term:?} || {ty:?} ({ctx:?})");
|
||||
let (ty_a, ctx_theta) = synthesize(ctx, term)?;
|
||||
let a = app_ctx(&ctx_theta, &ty_a)?;
|
||||
let b = app_ctx(&ctx_theta, ty)?;
|
||||
|
@ -145,7 +158,7 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
|
|||
Term::Var(index) => {
|
||||
let ty = match ctx.get_type(index) {
|
||||
Some(v) => v,
|
||||
None => bail!("invalid index {index:?}, context: {ctx:?}"),
|
||||
None => bail!("no TermAnnot at index {index:?} of context: {ctx:?}"),
|
||||
};
|
||||
Ok((ty, ctx.clone()))
|
||||
}
|
||||
|
@ -160,23 +173,31 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
|
|||
|
||||
// →I⇒' rule
|
||||
Term::Lam(e) => {
|
||||
let (aug_ctx, marker_idx) = ctx.add(ContextItem::Marker);
|
||||
let (aug_ctx, ex_a_idx) = aug_ctx.add(ContextItem::ExistentialVar);
|
||||
let (aug_ctx, ex_b_idx) = aug_ctx.add(ContextItem::ExistentialVar);
|
||||
let (aug_ctx, marker_idx) = ctx.add(ContextEntry::Marker);
|
||||
let (aug_ctx_at_a, ex_a_idx) = aug_ctx.add(ContextEntry::ExistentialVar);
|
||||
let (aug_ctx_at_b, ex_b_idx) =
|
||||
aug_ctx_at_a.add(ContextEntry::ExistentialVar);
|
||||
|
||||
let ex_a = Type::Existential(ex_a_idx.clone());
|
||||
let ex_b = Type::Existential(ex_b_idx.clone());
|
||||
let (aug_ctx, _annot_idx) =
|
||||
aug_ctx.add(ContextItem::TermAnnot(ex_a.clone()));
|
||||
|
||||
let wtf_ctx = typecheck(&aug_ctx, &e, &ex_b)?;
|
||||
let (aug_ctx, _annot_idx) =
|
||||
aug_ctx_at_b.add(ContextEntry::TermAnnot(ex_a.clone()));
|
||||
|
||||
let ex_a_2 = ex_b.bump_indexes(&aug_ctx_at_a, &aug_ctx, 2);
|
||||
let ex_b_2 = ex_b.bump_indexes(&aug_ctx_at_b, &aug_ctx, 1);
|
||||
|
||||
// TODO: Rewrite all indexes in this term
|
||||
let e_2 = e.bump_indexes(ctx, &aug_ctx, 0);
|
||||
|
||||
let wtf_ctx = typecheck(&aug_ctx, &e_2, &ex_b_2)?;
|
||||
|
||||
let (before_marker, after_marker) = wtf_ctx.split_at(&marker_idx);
|
||||
println!("Splitting: {:?}", wtf_ctx);
|
||||
let mut tau =
|
||||
app_ctx(&after_marker, &Type::Arrow(Box::new(ex_a), Box::new(ex_b)))?;
|
||||
let tau = Type::Arrow(Box::new(ex_a_2), Box::new(ex_b));
|
||||
let mut tau = app_ctx(&after_marker, &tau)?;
|
||||
|
||||
let (final_ctx, gen_idx) = before_marker.add(ContextItem::ExistentialVar);
|
||||
let (final_ctx, gen_idx) =
|
||||
before_marker.add(ContextEntry::ExistentialVar);
|
||||
|
||||
for index in after_marker.unsolved_existentials() {
|
||||
tau = tau.subst(&index, Type::Var(gen_idx.clone()));
|
||||
|
@ -190,11 +211,26 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
|
|||
}
|
||||
|
||||
pub fn app_synthesize(
|
||||
_ctx: &Context,
|
||||
ctx: &Context,
|
||||
fun_ty: &Type,
|
||||
term: &Term,
|
||||
) -> Result<(Type, Context)> {
|
||||
match (fun_ty, term) {
|
||||
// →App rule
|
||||
(Type::Arrow(ty_a, ty_c), e) => {
|
||||
let out_ctx = typecheck(ctx, e, ty_a)?;
|
||||
Ok((*ty_c.clone(), out_ctx))
|
||||
}
|
||||
|
||||
// ∀App rule
|
||||
(Type::Polytype(ty_a), e) => {
|
||||
let (aug_ctx, a_idx) = ctx.add(ContextEntry::ExistentialVar);
|
||||
let aug_ty = ty_a.subst(&a_idx, Type::Existential(a_idx.clone()));
|
||||
let (ty, ctx_delta) = app_synthesize(&aug_ctx, &aug_ty, e)?;
|
||||
|
||||
Ok((ty, ctx_delta))
|
||||
}
|
||||
|
||||
(Type::Unit, Term::Unit) => todo!(),
|
||||
(Type::Unit, Term::Var(_)) => todo!(),
|
||||
(Type::Unit, Term::Lam(_)) => todo!(),
|
||||
|
@ -210,16 +246,6 @@ pub fn app_synthesize(
|
|||
(Type::Existential(_), Term::Lam(_)) => todo!(),
|
||||
(Type::Existential(_), Term::App(_, _)) => todo!(),
|
||||
(Type::Existential(_), Term::Annot(_, _)) => todo!(),
|
||||
(Type::Polytype(_), Term::Unit) => todo!(),
|
||||
(Type::Polytype(_), Term::Var(_)) => todo!(),
|
||||
(Type::Polytype(_), Term::Lam(_)) => todo!(),
|
||||
(Type::Polytype(_), Term::App(_, _)) => todo!(),
|
||||
(Type::Polytype(_), Term::Annot(_, _)) => todo!(),
|
||||
(Type::Arrow(_, _), Term::Unit) => todo!(),
|
||||
(Type::Arrow(_, _), Term::Var(_)) => todo!(),
|
||||
(Type::Arrow(_, _), Term::Lam(_)) => todo!(),
|
||||
(Type::Arrow(_, _), Term::App(_, _)) => todo!(),
|
||||
(Type::Arrow(_, _), Term::Annot(_, _)) => todo!(),
|
||||
|
||||
_ => bail!("trying to appSynthesize with a non-function type"),
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
fmt::{self},
|
||||
rc::Rc,
|
||||
};
|
||||
use std::fmt::{self};
|
||||
|
||||
use im::Vector;
|
||||
|
||||
|
@ -40,6 +36,40 @@ impl fmt::Debug for Term {
|
|||
}
|
||||
}
|
||||
|
||||
impl Term {
|
||||
pub fn bump_indexes(
|
||||
&self,
|
||||
old_ctx: &Context,
|
||||
new_ctx: &Context,
|
||||
by: usize,
|
||||
) -> Term {
|
||||
match self {
|
||||
Term::Unit => Term::Unit,
|
||||
Term::Var(index) => {
|
||||
let debruijn_index = index.debruijn_index + by;
|
||||
let debruijn_level = new_ctx.vector.len() - 1 - debruijn_index;
|
||||
let new_index = ContextIndex {
|
||||
debruijn_index,
|
||||
debruijn_level,
|
||||
};
|
||||
Term::Var(new_index)
|
||||
}
|
||||
Term::Lam(body) => {
|
||||
Term::Lam(Box::new(body.bump_indexes(old_ctx, new_ctx, by)))
|
||||
}
|
||||
Term::App(e1, e2) => Term::App(
|
||||
Box::new(e1.bump_indexes(old_ctx, new_ctx, by)),
|
||||
Box::new(e2.bump_indexes(old_ctx, new_ctx, by)),
|
||||
),
|
||||
Term::Annot(e, ty) =>
|
||||
// TODO: Should i bump indexes in the type too (PROBABLY)
|
||||
{
|
||||
Term::Annot(Box::new(e.bump_indexes(old_ctx, new_ctx, by)), ty.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Type {
|
||||
Unit,
|
||||
|
@ -85,6 +115,29 @@ impl Type {
|
|||
pub fn is_mono(&self) -> bool {
|
||||
self.try_into_mono().is_some()
|
||||
}
|
||||
|
||||
pub fn bump_indexes(
|
||||
&self,
|
||||
old_ctx: &Context,
|
||||
new_ctx: &Context,
|
||||
by: usize,
|
||||
) -> Type {
|
||||
match self {
|
||||
Type::Unit => Type::Unit,
|
||||
Type::Var(_) => todo!(),
|
||||
Type::Existential(index) => {
|
||||
let debruijn_index = index.debruijn_index + by;
|
||||
let debruijn_level = new_ctx.vector.len() - 1 - debruijn_index;
|
||||
let new_index = ContextIndex {
|
||||
debruijn_index,
|
||||
debruijn_level,
|
||||
};
|
||||
Type::Existential(new_index)
|
||||
}
|
||||
Type::Polytype(_) => todo!(),
|
||||
Type::Arrow(_, _) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
@ -130,18 +183,29 @@ impl Type {
|
|||
// }
|
||||
// }
|
||||
|
||||
pub fn subst(&self, _before: &ContextIndex, _after: Type) -> Type {
|
||||
pub fn subst(&self, before: &ContextIndex, after: Type) -> Type {
|
||||
match self {
|
||||
Type::Unit => Type::Unit,
|
||||
Type::Var(_) => todo!(),
|
||||
Type::Existential(_) => todo!(),
|
||||
Type::Var(index) if index.debruijn_level == before.debruijn_level => {
|
||||
after
|
||||
}
|
||||
Type::Var(index) => Type::Var(index.clone()),
|
||||
Type::Existential(index)
|
||||
if index.debruijn_level == before.debruijn_level =>
|
||||
{
|
||||
after
|
||||
}
|
||||
Type::Existential(index) => Type::Existential(index.clone()),
|
||||
Type::Polytype(_) => todo!(),
|
||||
Type::Arrow(_, _) => todo!(),
|
||||
Type::Arrow(a, b) => Type::Arrow(
|
||||
Box::new(a.subst(before, after.clone())),
|
||||
Box::new(b.subst(before, after.clone())),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Monotype {
|
||||
Unit,
|
||||
Var(ContextIndex),
|
||||
|
@ -149,17 +213,6 @@ pub enum Monotype {
|
|||
Arrow(Box<Monotype>, Box<Monotype>),
|
||||
}
|
||||
|
||||
impl fmt::Debug for Monotype {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Unit => write!(f, "𝟙"),
|
||||
Self::Var(arg0) => write!(f, "{:?}", arg0),
|
||||
Self::Existential(arg0) => write!(f, "{:?}", arg0),
|
||||
Self::Arrow(arg0, arg1) => write!(f, "({arg0:?} -> {arg1:?})"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Monotype {
|
||||
pub fn into_poly(&self) -> Type {
|
||||
match self {
|
||||
|
@ -174,7 +227,7 @@ impl Monotype {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ContextItem {
|
||||
pub enum ContextEntry {
|
||||
TypeVar,
|
||||
TermAnnot(Type),
|
||||
ExistentialVar,
|
||||
|
@ -182,19 +235,6 @@ pub enum ContextItem {
|
|||
Marker,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ContextEntry {
|
||||
item: ContextItem,
|
||||
index_from_start: usize,
|
||||
index_from_end: usize,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ContextEntry {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self.item)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CompleteContextEntry {
|
||||
TypeVar(String),
|
||||
|
@ -205,10 +245,8 @@ pub enum CompleteContextEntry {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Context {
|
||||
vector: Vector<Rc<RefCell<ContextEntry>>>,
|
||||
len: Rc<RefCell<usize>>,
|
||||
// len: ReadSignal<usize>,
|
||||
// set_len: WriteSignal<usize>,
|
||||
// TODO: Make this not pub(crate)
|
||||
pub(crate) vector: Vector<ContextEntry>,
|
||||
}
|
||||
|
||||
// impl fmt::Debug for Context {
|
||||
|
@ -225,48 +263,27 @@ pub struct Context {
|
|||
impl Default for Context {
|
||||
fn default() -> Self {
|
||||
let vector = Vector::default();
|
||||
// let (len, set_len) = create_signal(0);
|
||||
let len = Rc::new(RefCell::new(0));
|
||||
|
||||
Context {
|
||||
vector,
|
||||
len,
|
||||
// len,
|
||||
// set_len,
|
||||
}
|
||||
Context { vector }
|
||||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn add(&self, item: ContextItem) -> (Context, ContextIndex) {
|
||||
let context_level = self.vector.len();
|
||||
let mut new_ctx = self.clone();
|
||||
new_ctx.vector.push_back(Rc::new(RefCell::new(ContextEntry {
|
||||
item,
|
||||
index_from_end: 0,
|
||||
index_from_start: self.vector.len(),
|
||||
})));
|
||||
pub fn add(&self, item: ContextEntry) -> (Context, ContextIndex) {
|
||||
let idx = self.vector.len();
|
||||
let mut new_ctx = self.bump_indexes(1);
|
||||
new_ctx.vector.push_back(item);
|
||||
|
||||
let context_length = Rc::new(RefCell::new(new_ctx.vector.len()));
|
||||
// let context_length = self.len.clone();
|
||||
// {
|
||||
// *context_length.borrow_mut() += 1;
|
||||
// }
|
||||
|
||||
// let context_index =
|
||||
// create_memo(move |_| context_length.get() - context_level);
|
||||
let idx = ContextIndex {
|
||||
context_level,
|
||||
context_length,
|
||||
// context_index,
|
||||
debruijn_index: 0,
|
||||
debruijn_level: idx,
|
||||
};
|
||||
(new_ctx, idx)
|
||||
}
|
||||
|
||||
pub fn get<'a>(&'a self, index: &ContextIndex) -> Option<ContextItem> {
|
||||
let entry = self.vector.get(index.context_level)?;
|
||||
let entry = entry.borrow();
|
||||
Some(entry.item.clone())
|
||||
pub fn get<'a>(&'a self, index: &ContextIndex) -> Option<&ContextEntry> {
|
||||
let item = self.vector.get(index.debruijn_level)?;
|
||||
Some(item)
|
||||
}
|
||||
|
||||
pub fn get_existential(
|
||||
|
@ -276,8 +293,8 @@ impl Context {
|
|||
let item = self.get(index)?;
|
||||
|
||||
match item {
|
||||
ContextItem::ExistentialSolved(t) => Some(Some(t.clone())),
|
||||
ContextItem::ExistentialVar => Some(None),
|
||||
ContextEntry::ExistentialSolved(t) => Some(Some(t.clone())),
|
||||
ContextEntry::ExistentialVar => Some(None),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -286,20 +303,19 @@ impl Context {
|
|||
let item = self.get(index)?;
|
||||
|
||||
match item {
|
||||
ContextItem::TermAnnot(t) => Some(t.clone()),
|
||||
ContextEntry::TermAnnot(t) => Some(t.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unsolved_existentials(&self) -> Vec<ContextIndex> {
|
||||
let mut unsolved = Vec::new();
|
||||
let context_length = self.len.clone();
|
||||
for (context_level, entry) in self.vector.iter().enumerate() {
|
||||
match entry.borrow().item {
|
||||
ContextItem::ExistentialVar => {
|
||||
for (idx, item) in self.vector.iter().enumerate() {
|
||||
match item {
|
||||
ContextEntry::ExistentialVar => {
|
||||
let index = ContextIndex {
|
||||
context_length: context_length.clone(),
|
||||
context_level,
|
||||
debruijn_level: idx,
|
||||
debruijn_index: self.vector.len() - idx,
|
||||
};
|
||||
unsolved.push(index)
|
||||
}
|
||||
|
@ -313,43 +329,95 @@ impl Context {
|
|||
pub fn split_at(&self, index: &ContextIndex) -> (Context, Context) {
|
||||
let (before, after) = {
|
||||
// let idx = self.vector.iter().position(p)?;
|
||||
self.vector.clone().split_at(index.context_level)
|
||||
self.vector.clone().split_at(index.debruijn_level)
|
||||
};
|
||||
|
||||
let before_len = Rc::new(RefCell::new(before.len()));
|
||||
let after_len = Rc::new(RefCell::new(after.len()));
|
||||
(Context { vector: before }, Context { vector: after })
|
||||
}
|
||||
|
||||
(
|
||||
Context {
|
||||
vector: before,
|
||||
len: before_len,
|
||||
},
|
||||
Context {
|
||||
vector: after,
|
||||
len: after_len,
|
||||
},
|
||||
)
|
||||
pub fn is_valid(&self) -> bool {
|
||||
for item in self.vector.iter() {
|
||||
match item {
|
||||
ContextEntry::TermAnnot(_) => todo!(),
|
||||
ContextEntry::ExistentialSolved(_) => todo!(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn ensure_validity(&self) -> bool {
|
||||
fn ensure_item_validity(ctx: &Context, item: &ContextEntry) -> bool {
|
||||
match item {
|
||||
ContextEntry::TermAnnot(ty) => ensure_type_validity(ctx, ty),
|
||||
ContextEntry::ExistentialSolved(ty) => {
|
||||
ensure_monotype_validity(ctx, ty)
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_type_validity(ctx: &Context, ty: &Type) -> bool {
|
||||
match ty {
|
||||
Type::Var(idx) => ensure_index_validity(ctx, idx),
|
||||
Type::Existential(idx) => ensure_index_validity(ctx, idx),
|
||||
Type::Polytype(ty) => ensure_type_validity(ctx, ty),
|
||||
Type::Arrow(ty1, ty2) => {
|
||||
ensure_type_validity(ctx, ty1) && ensure_type_validity(ctx, ty2)
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_monotype_validity(ctx: &Context, ty: &Monotype) -> bool {
|
||||
match ty {
|
||||
Monotype::Var(idx) => ensure_index_validity(ctx, idx),
|
||||
Monotype::Existential(idx) => ensure_index_validity(ctx, idx),
|
||||
Monotype::Arrow(ty1, ty2) => {
|
||||
ensure_monotype_validity(ctx, ty1)
|
||||
&& ensure_monotype_validity(ctx, ty2)
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_index_validity(ctx: &Context, idx: &ContextIndex) -> bool {
|
||||
idx.debruijn_index + idx.debruijn_level == ctx.vector.len()
|
||||
}
|
||||
|
||||
self
|
||||
.vector
|
||||
.iter()
|
||||
.all(|item| ensure_item_validity(self, item))
|
||||
}
|
||||
|
||||
pub fn bump_indexes(&self, by: usize) -> Context {
|
||||
Context {
|
||||
vector: self
|
||||
.vector
|
||||
.iter()
|
||||
.map(|entry| match entry {
|
||||
ContextEntry::TypeVar => ContextEntry::TypeVar,
|
||||
ContextEntry::TermAnnot(_) => todo!(),
|
||||
ContextEntry::ExistentialVar => ContextEntry::ExistentialVar,
|
||||
ContextEntry::ExistentialSolved(_) => todo!(),
|
||||
ContextEntry::Marker => ContextEntry::Marker,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An index into the context.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct ContextIndex {
|
||||
context_length: Rc<RefCell<usize>>,
|
||||
// context_length: ReadSignal<usize>,
|
||||
// context_index: Memo<usize>,
|
||||
context_level: usize,
|
||||
pub(crate) debruijn_index: usize,
|
||||
pub(crate) debruijn_level: usize,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ContextIndex {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "#{}", self.context_index())
|
||||
}
|
||||
}
|
||||
|
||||
impl ContextIndex {
|
||||
pub fn context_index(&self) -> usize {
|
||||
*self.context_length.borrow() - self.context_level
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "#{}/{}", self.debruijn_level, self.debruijn_index)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,12 +435,9 @@ pub fn convert_term(term: &data::Term) -> Term {
|
|||
data::Term::Var(name) => {
|
||||
let (idx, _) = ctx.lookup_type(name).unwrap();
|
||||
|
||||
let _len = ctx2.len.clone();
|
||||
// let context_index = create_memo(move |_| len.get() - idx);
|
||||
let index = ContextIndex {
|
||||
context_length: ctx2.len.clone(),
|
||||
context_level: idx,
|
||||
// context_index,
|
||||
debruijn_index: 0,
|
||||
debruijn_level: ctx.0.len(),
|
||||
};
|
||||
Term::Var(index)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
#[macro_use]
|
||||
extern crate contracts;
|
||||
#[macro_use]
|
||||
extern crate derivative;
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
#[macro_use]
|
||||
extern crate trace;
|
||||
|
||||
use lalrpop_util::lalrpop_mod;
|
||||
|
||||
// #[macro_export]
|
||||
// pub mod fmt;
|
||||
|
||||
pub mod abstract_data;
|
||||
pub mod bidir;
|
||||
pub mod data;
|
||||
|
|
|
@ -19,7 +19,7 @@ fn test_id_only() -> Result<()> {
|
|||
let id = term_of(r"\x.x")?;
|
||||
let ctx = Context::default();
|
||||
let (ty, out_ctx) = synthesize(&ctx, &id)?;
|
||||
bail!("Synthesized: {:?} (context = {:?})", ty, out_ctx);
|
||||
bail!("[test] Synthesized: {:?} (context = {:?})", ty, out_ctx);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,8 @@ fn test_id_of_unit() -> Result<()> {
|
|||
let ctx = Context::default();
|
||||
|
||||
let (ty, out_ctx) = synthesize(&ctx, &id_of_unit)?;
|
||||
let wtf = app_ctx(&out_ctx, &ty);
|
||||
println!("WTF: {wtf:?}");
|
||||
bail!("Synthesized: {:?} (context = {:?})", ty, out_ctx);
|
||||
// let wtf = app_ctx(&out_ctx, &ty);
|
||||
// println!("WTF: {wtf:?}");
|
||||
bail!("[test] Synthesized: {:?} (context = {:?})", ty, out_ctx);
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue