it FUCKING typechecks

This commit is contained in:
Michael Zhang 2023-11-07 01:53:05 -06:00
parent d20044501b
commit 47c8fc62f6
4 changed files with 26 additions and 16 deletions

View file

@ -2,10 +2,10 @@ use anyhow::{bail, Result};
use crate::data::{Context, ContextEntry, FreeVar, Monotype, Term, Type}; use crate::data::{Context, ContextEntry, FreeVar, Monotype, Term, Type};
use crate::gensym::gensym_existential; use crate::gensym::gensym_existential;
use crate::DEPTH;
// Figure 8. Applying a context, as a substitution, to a type // Figure 8. Applying a context, as a substitution, to a type
#[instrument]
pub fn app_ctx(ctx: &Context, ty: &Type) -> Result<Type> { pub fn app_ctx(ctx: &Context, ty: &Type) -> Result<Type> {
match ty { match ty {
Type::Unit => Ok(Type::Unit), Type::Unit => Ok(Type::Unit),
@ -145,7 +145,6 @@ pub fn instantiate_right(ctx: &Context, ty_a: &Type, a: &str) -> Result<Context>
// Figure 11. Algorithmic typing // Figure 11. Algorithmic typing
#[instrument]
pub fn typecheck(ctx: &Context, term: &Term, ty: &Type) -> Result<Context> { pub fn typecheck(ctx: &Context, term: &Term, ty: &Type) -> Result<Context> {
match (term, ty) { match (term, ty) {
// 1I rule // 1I rule
@ -171,7 +170,6 @@ pub fn typecheck(ctx: &Context, term: &Term, ty: &Type) -> Result<Context> {
} }
} }
#[instrument]
pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> { pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
match term { match term {
// Var rule // Var rule
@ -227,7 +225,6 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
warn!("substituting {tau:?} looking for {name}"); warn!("substituting {tau:?} looking for {name}");
tau = tau.subst(&name, &Type::Var(ex_gen.clone())); tau = tau.subst(&name, &Type::Var(ex_gen.clone()));
} }
info!("ex_gen = {ex_gen}, tau = {tau:?}");
Ok((Type::Polytype(ex_gen, Box::new(tau)), before_marker)) Ok((Type::Polytype(ex_gen, Box::new(tau)), before_marker))
} }
@ -250,7 +247,6 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
// ]); // ]);
// let wtf_ctx = typecheck(&aug_ctx, &e, &ex_b)?; // let wtf_ctx = typecheck(&aug_ctx, &e, &ex_b)?;
// println!("the wtf ctx is {wtf_ctx:?}");
// Ok((Type::Arrow(Box::new(ex_a), Box::new(ex_b)), ctx.clone())) // Ok((Type::Arrow(Box::new(ex_a), Box::new(ex_b)), ctx.clone()))
// } // }
@ -264,14 +260,12 @@ pub fn synthesize(ctx: &Context, term: &Term) -> Result<(Type, Context)> {
} }
} }
#[instrument]
pub fn app_synthesize(ctx: &Context, fun_ty: &Type, term: &Term) -> Result<(Type, Context)> { pub fn app_synthesize(ctx: &Context, fun_ty: &Type, term: &Term) -> Result<(Type, Context)> {
match (fun_ty, term) { match (fun_ty, term) {
// →App rule // →App rule
(Type::Arrow(ty_a, ty_c), e) => { (Type::Arrow(ty_a, ty_c), e) => {
info!("→App rule"); let out_ctx = typecheck(ctx, e, ty_a)?;
typecheck(ctx, e, ty_a)?; Ok((*ty_c.clone(), out_ctx))
Ok((*ty_c.clone(), ctx.clone()))
} }
// ∀App rule // ∀App rule
@ -281,7 +275,9 @@ pub fn app_synthesize(ctx: &Context, fun_ty: &Type, term: &Term) -> Result<(Type
let aug_ctx = ctx.add(vec![ex.clone()]); let aug_ctx = ctx.add(vec![ex.clone()]);
let aug_ty = ty_a.subst(&a, &Type::Existential(ex_s)); let aug_ty = ty_a.subst(&a, &Type::Existential(ex_s));
app_synthesize(&aug_ctx, &aug_ty, e) let (ty, ctx_delta) = app_synthesize(&aug_ctx, &aug_ty, e)?;
Ok((ty, ctx_delta))
} }
// âApp rule // âApp rule

View file

@ -1,7 +1,7 @@
#[macro_use] #[macro_use]
extern crate trace;
#[macro_use]
extern crate tracing; extern crate tracing;
#[macro_use]
extern crate trace;
use lalrpop_util::lalrpop_mod; use lalrpop_util::lalrpop_mod;

View file

@ -1,5 +1,9 @@
use anyhow::Result; use anyhow::Result;
use bidir::{bidir::synthesize, data::Context, parser::TermParser}; use bidir::{
bidir::{app_ctx, synthesize},
data::Context,
parser::TermParser,
};
use rustyline::{Config, DefaultEditor}; use rustyline::{Config, DefaultEditor};
fn main() -> Result<()> { fn main() -> Result<()> {
@ -13,7 +17,6 @@ fn main() -> Result<()> {
Ok(line) => line, Ok(line) => line,
Err(_) => break, Err(_) => break,
}; };
println!("line: {}", line);
let parsed_term = match term_parser.parse(&line) { let parsed_term = match term_parser.parse(&line) {
Ok(term) => term, Ok(term) => term,
@ -25,8 +28,17 @@ fn main() -> Result<()> {
println!("parsed: {:?}", parsed_term); println!("parsed: {:?}", parsed_term);
let ctx = Context::default(); let ctx = Context::default();
let synthesized_type = synthesize(&ctx, &parsed_term); let (ty, out_ctx) = match synthesize(&ctx, &parsed_term) {
println!("synthesized: {:?}", synthesized_type); Ok(v) => v,
Err(err) => {
eprintln!("typecheck error: {err}");
continue;
}
};
let ty = app_ctx(&out_ctx, &ty);
println!("synthesized: {:?}", ty);
} }
Ok(()) Ok(())

View file

@ -28,6 +28,8 @@ fn test_id_of_unit() -> Result<()> {
let ctx = Context::default(); let ctx = Context::default();
let (ty, out_ctx) = synthesize(&ctx, &id_of_unit)?; 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); bail!("Synthesized: {:?} (context = {:?})", ty, out_ctx);
Ok(()) Ok(())
} }