it FUCKING typechecks
This commit is contained in:
parent
d20044501b
commit
47c8fc62f6
4 changed files with 26 additions and 16 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue