wip: not sure

This commit is contained in:
Michael Zhang 2023-11-30 00:14:10 -06:00
parent 6012067fa5
commit 4ff88c0ca9
2 changed files with 275 additions and 87 deletions

View file

@ -1,7 +1,7 @@
use anyhow::{bail, Result}; use anyhow::{bail, ensure, Result};
use crate::data_debruijn::{ use crate::data_debruijn::{
Context, ContextEntry, ContextIndex, Monotype, Term, Type, Context, ContextEntry, ContextIndex, Monotype, Term, Type, Visitor,
}; };
use crate::DEPTH; use crate::DEPTH;
@ -105,6 +105,11 @@ pub fn instantiate_left(
.get_mut(b.debruijn_level) .get_mut(b.debruijn_level)
.expect("should exist"); .expect("should exist");
ensure!(
matches!(b_entry, ContextEntry::ExistentialVar),
"not an existential variable"
);
*b_entry = *b_entry =
ContextEntry::ExistentialSolved(Monotype::Existential(a.to_owned())); ContextEntry::ExistentialSolved(Monotype::Existential(a.to_owned()));
} }
@ -173,37 +178,59 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
// →I⇒' rule // →I⇒' rule
Term::Lam(e) => { Term::Lam(e) => {
let (aug_ctx, marker_idx) = ctx.add(ContextEntry::Marker); 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_a, ex_a_idx) =
aug_ctx.add(ContextEntry::ExistentialVar)?;
let (aug_ctx_at_b, ex_b_idx) = let (aug_ctx_at_b, ex_b_idx) =
aug_ctx_at_a.add(ContextEntry::ExistentialVar); aug_ctx_at_a.add(ContextEntry::ExistentialVar)?;
let ex_a = Type::Existential(ex_a_idx.clone()); let ex_a = Type::Existential(ex_a_idx.clone());
let ex_b = Type::Existential(ex_b_idx.clone()); let ex_b = Type::Existential(ex_b_idx.clone());
let (aug_ctx, _annot_idx) = let (aug_ctx, _annot_idx) =
aug_ctx_at_b.add(ContextEntry::TermAnnot(ex_a.clone())); 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); struct V(usize, usize);
let ex_b_2 = ex_b.bump_indexes(&aug_ctx_at_b, &aug_ctx, 1); impl Visitor for V {
fn visit_index(&self, index: &mut ContextIndex) -> Result<()> {
index.debruijn_index += self.0;
index.debruijn_level = self.1 - 1 - index.debruijn_index;
Ok(())
}
}
// TODO: Rewrite all indexes in this term let ex_a_2 = ex_b.transform_with_visitor(&V(2, aug_ctx.size()))?;
let e_2 = e.bump_indexes(ctx, &aug_ctx, 0); let ex_b_2 = ex_b.transform_with_visitor(&V(1, aug_ctx.size()))?;
let e_2 = e.transform_with_visitor(&V(0, aug_ctx.size()))?;
println!("---");
let wtf_ctx = typecheck(&aug_ctx, &e_2, &ex_b_2)?; let wtf_ctx = typecheck(&aug_ctx, &e_2, &ex_b_2)?;
let (before_marker, after_marker) = wtf_ctx.split_at(&marker_idx); let (before_marker, after_marker) = wtf_ctx.split_at(&marker_idx);
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) = // Bump the levels down since we're splitting teh array
before_marker.add(ContextEntry::ExistentialVar); struct V2(usize);
impl Visitor for V2 {
for index in after_marker.unsolved_existentials() { fn visit_index(&self, index: &mut ContextIndex) -> Result<()> {
tau = tau.subst(&index, Type::Var(gen_idx.clone())); index.debruijn_level -= 1;
index.debruijn_index = self.0 - 1 - index.debruijn_level;
Ok(())
} }
}
let after_marker =
after_marker.transform_with_visitor(&V2(after_marker.size()))?;
Ok((Type::Polytype(Box::new(tau)), final_ctx)) let tau = Type::Arrow(Box::new(ex_a_2), Box::new(ex_b));
println!("pre-tau: {tau:?} (in {after_marker:?})");
let tau = app_ctx(&after_marker, &tau)?;
// 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()));
// }
Ok((Type::Polytype(Box::new(tau)), before_marker))
} }
Term::Annot(_, _) => todo!(), Term::Annot(_, _) => todo!(),
@ -224,7 +251,7 @@ pub fn app_synthesize(
// ∀App rule // ∀App rule
(Type::Polytype(ty_a), e) => { (Type::Polytype(ty_a), e) => {
let (aug_ctx, a_idx) = ctx.add(ContextEntry::ExistentialVar); let (aug_ctx, a_idx) = ctx.add(ContextEntry::ExistentialVar)?;
let aug_ty = ty_a.subst(&a_idx, Type::Existential(a_idx.clone())); let aug_ty = ty_a.subst(&a_idx, Type::Existential(a_idx.clone()));
let (ty, ctx_delta) = app_synthesize(&aug_ctx, &aug_ty, e)?; let (ty, ctx_delta) = app_synthesize(&aug_ctx, &aug_ty, e)?;

View file

@ -1,5 +1,6 @@
use std::fmt::{self}; use std::fmt::{self};
use anyhow::Result;
use im::Vector; use im::Vector;
use crate::{data, gensym::gensym_type}; use crate::{data, gensym::gensym_type};
@ -37,36 +38,57 @@ impl fmt::Debug for Term {
} }
impl Term { impl Term {
pub fn bump_indexes( // 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())
// }
// }
// }
pub fn transform_with_visitor<V: Visitor>(
&self, &self,
old_ctx: &Context, visitor: &V,
new_ctx: &Context, ) -> Result<Term> {
by: usize, let mut expr = self.clone();
) -> Term { visitor.visit_term_before(&mut expr)?;
match self { let mut expr = match expr {
Term::Unit => Term::Unit,
Term::Var(index) => { Term::Var(index) => {
let debruijn_index = index.debruijn_index + by; let mut index = index.clone();
let debruijn_level = new_ctx.vector.len() - 1 - debruijn_index; visitor.visit_index(&mut index)?;
let new_index = ContextIndex { Term::Var(index)
debruijn_index, }
debruijn_level, Term::Lam(_) => todo!(),
Term::App(_, _) => todo!(),
Term::Annot(_, _) => todo!(),
_ => expr,
}; };
Term::Var(new_index) visitor.visit_term_after(&mut expr)?;
} Ok(expr)
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())
}
}
} }
} }
@ -116,31 +138,23 @@ impl Type {
self.try_into_mono().is_some() self.try_into_mono().is_some()
} }
pub fn bump_indexes( // pub fn bump_indexes(&self, by: usize) -> Type {
&self, // match self {
old_ctx: &Context, // Type::Unit => Type::Unit,
new_ctx: &Context, // Type::Var(_) => todo!(),
by: usize, // Type::Existential(index) => {
) -> Type { // let debruijn_index = index.debruijn_index + by;
match self { // let new_index = ContextIndex {
Type::Unit => Type::Unit, // debruijn_index,
Type::Var(_) => todo!(), // debruijn_level: index.debruijn_level,
Type::Existential(index) => { // };
let debruijn_index = index.debruijn_index + by; // Type::Existential(new_index)
let debruijn_level = new_ctx.vector.len() - 1 - debruijn_index; // }
let new_index = ContextIndex { // Type::Polytype(_) => todo!(),
debruijn_index, // Type::Arrow(_, _) => todo!(),
debruijn_level, // }
}; // }
Type::Existential(new_index)
}
Type::Polytype(_) => todo!(),
Type::Arrow(_, _) => todo!(),
}
}
}
impl Type {
// pub fn free_vars(&self) -> HashSet<FreeVar> { // pub fn free_vars(&self) -> HashSet<FreeVar> {
// fn free_vars_with_context(ctx: &Context, ty: &Type) -> HashSet<FreeVar> { // fn free_vars_with_context(ctx: &Context, ty: &Type) -> HashSet<FreeVar> {
// match ty { // match ty {
@ -203,6 +217,27 @@ impl Type {
), ),
} }
} }
pub fn transform_with_visitor<V: Visitor>(
&self,
visitor: &V,
) -> Result<Type> {
let mut ty = self.clone();
visitor.visit_type_before(&mut ty)?;
let mut ty = match ty {
Type::Var(_) => todo!(),
Type::Existential(index) => {
let mut index = index.clone();
visitor.visit_index(&mut index)?;
Type::Existential(index)
}
Type::Polytype(_) => todo!(),
Type::Arrow(_, _) => todo!(),
_ => ty,
};
visitor.visit_type_after(&mut ty)?;
Ok(ty)
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -224,6 +259,54 @@ impl Monotype {
} }
} }
} }
// pub fn bump_indexes(&self, by: isize) -> Monotype {
// match self {
// Monotype::Unit => Monotype::Unit,
// Monotype::Var(index) => {
// let debruijn_index = (index.debruijn_index as isize + by) as usize;
// // let debruijn_level = new_ctx.vector.len() - 1 - debruijn_index;
// let new_index = ContextIndex {
// debruijn_index,
// debruijn_level: index.debruijn_level,
// };
// Monotype::Var(new_index)
// }
// Monotype::Existential(index) => {
// let debruijn_index = (index.debruijn_index as isize + by) as usize;
// // let debruijn_level = new_ctx.vector.len() - 1 - debruijn_index;
// let new_index = ContextIndex {
// debruijn_index,
// debruijn_level: index.debruijn_level,
// };
// Monotype::Var(new_index)
// }
// Monotype::Arrow(a, b) => Monotype::Arrow(
// Box::new(a.bump_indexes(by)),
// Box::new(b.bump_indexes(by)),
// ),
// }
// }
pub fn transform_with_visitor<V: Visitor>(
&self,
visitor: &V,
) -> Result<Monotype> {
let mut ty = self.clone();
visitor.visit_monotype_before(&mut ty)?;
let mut ty = match ty {
Monotype::Var(_) => todo!(),
Monotype::Existential(index) => {
let mut index = index.clone();
visitor.visit_index(&mut index)?;
Monotype::Existential(index)
}
Monotype::Arrow(_, _) => todo!(),
_ => ty,
};
visitor.visit_monotype_after(&mut ty)?;
Ok(ty)
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -289,18 +372,34 @@ impl Default for Context {
} }
impl Context { impl Context {
pub fn add(&self, item: ContextEntry) -> (Context, ContextIndex) { #[inline]
pub fn size(&self) -> usize {
self.vector.len()
}
pub fn add(&self, item: ContextEntry) -> Result<(Context, ContextIndex)> {
let idx = self.vector.len(); let idx = self.vector.len();
let mut new_ctx = self.bump_indexes(1); struct V;
impl Visitor for V {
fn visit_index(&self, index: &mut ContextIndex) -> Result<()> {
index.debruijn_index += 1;
Ok(())
}
}
let mut new_ctx = self.transform_with_visitor(&V)?;
new_ctx.vector.push_back(item); new_ctx.vector.push_back(item);
let idx = ContextIndex { let idx = ContextIndex {
debruijn_index: 0, debruijn_index: 0,
debruijn_level: idx, debruijn_level: idx,
}; };
(new_ctx, idx) Ok((new_ctx, idx))
} }
// /// Pops items from the end of the context, changing all of the indexes in the
// /// process
// pub fn pop(&self) -> Context {}
pub fn get<'a>(&'a self, index: &ContextIndex) -> Option<&ContextEntry> { pub fn get<'a>(&'a self, index: &ContextIndex) -> Option<&ContextEntry> {
let item = self.vector.get(index.debruijn_level)?; let item = self.vector.get(index.debruijn_level)?;
Some(item) Some(item)
@ -347,10 +446,7 @@ impl Context {
/// Splits the context /// Splits the context
pub fn split_at(&self, index: &ContextIndex) -> (Context, Context) { pub fn split_at(&self, index: &ContextIndex) -> (Context, Context) {
let (before, after) = { let (before, after) = self.vector.clone().split_at(index.debruijn_level);
// let idx = self.vector.iter().position(p)?;
self.vector.clone().split_at(index.debruijn_level)
};
(Context { vector: before }, Context { vector: after }) (Context { vector: before }, Context { vector: after })
} }
@ -411,21 +507,56 @@ impl Context {
.all(|item| ensure_item_validity(self, item)) .all(|item| ensure_item_validity(self, item))
} }
pub fn bump_indexes(&self, by: usize) -> Context { pub fn transform_with_visitor<V: Visitor>(
Context { &self,
visitor: &V,
) -> Result<Context> {
Ok(Context {
vector: self vector: self
.vector .vector
.iter() .iter()
.map(|entry| match entry { .map(|entry| {
ContextEntry::TypeVar => ContextEntry::TypeVar, let mut entry = entry.clone();
ContextEntry::TermAnnot(_) => todo!(), visitor.visit_context_entry_before(&mut entry)?;
ContextEntry::ExistentialVar => ContextEntry::ExistentialVar, let mut entry = match entry {
ContextEntry::ExistentialSolved(_) => todo!(), ContextEntry::TermAnnot(ty) => {
ContextEntry::Marker => ContextEntry::Marker, ContextEntry::TermAnnot(ty.transform_with_visitor(visitor)?)
}
ContextEntry::ExistentialSolved(ty) => {
ContextEntry::ExistentialSolved(
ty.transform_with_visitor(visitor)?,
)
}
_ => entry,
};
visitor.visit_context_entry_after(&mut entry)?;
Ok(entry)
})
.collect::<Result<_>>()?,
}) })
.collect(),
}
} }
// pub fn bump_indexes(&self, by: isize) -> Context {
// Context {
// vector: self
// .vector
// .iter()
// .map(|entry| match entry {
// ContextEntry::TypeVar => ContextEntry::TypeVar,
// ContextEntry::TermAnnot(ty) => {
// todo!()
// // ContextEntry::TermAnnot(ty.bump_indexes(by))
// }
// ContextEntry::ExistentialVar => ContextEntry::ExistentialVar,
// ContextEntry::ExistentialSolved(ty) => {
// todo!()
// // ContextEntry::ExistentialSolved(ty.bump_indexes(-1))
// }
// ContextEntry::Marker => ContextEntry::Marker,
// })
// .collect(),
// }
// }
} }
/// An index into the context. /// An index into the context.
@ -507,3 +638,33 @@ pub fn convert_term(term: &data::Term) -> Term {
term, term,
) )
} }
pub trait Visitor {
fn visit_context_entry_before(&self, expr: &mut ContextEntry) -> Result<()> {
Ok(())
}
fn visit_context_entry_after(&self, expr: &mut ContextEntry) -> Result<()> {
Ok(())
}
fn visit_type_before(&self, expr: &mut Type) -> Result<()> {
Ok(())
}
fn visit_type_after(&self, expr: &mut Type) -> Result<()> {
Ok(())
}
fn visit_monotype_before(&self, expr: &mut Monotype) -> Result<()> {
Ok(())
}
fn visit_monotype_after(&self, expr: &mut Monotype) -> Result<()> {
Ok(())
}
fn visit_term_before(&self, expr: &mut Term) -> Result<()> {
Ok(())
}
fn visit_term_after(&self, expr: &mut Term) -> Result<()> {
Ok(())
}
fn visit_index(&self, index: &mut ContextIndex) -> Result<()> {
Ok(())
}
}