diff options
author | Josh Chen | 2020-07-27 14:31:35 +0200 |
---|---|---|
committer | Josh Chen | 2020-07-27 14:31:35 +0200 |
commit | 223a253732ced7d89dcea506ab56d92d1cfe8281 (patch) | |
tree | 08d9f4debaa2d00ada2db5d82afb3b5f1885714b /spartan/core/elaboration.ML | |
parent | 2a78ddc733340a72351df09a12ce4fc695b93de7 (diff) | |
parent | 0f84aa06384d827bd5f5f137c218197ab7217762 (diff) |
Merge branch 'dev'
Diffstat (limited to '')
-rw-r--r-- | spartan/core/elaboration.ML | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/spartan/core/elaboration.ML b/spartan/core/elaboration.ML new file mode 100644 index 0000000..27b6bb0 --- /dev/null +++ b/spartan/core/elaboration.ML @@ -0,0 +1,76 @@ +(* Title: elaboration.ML + Author: Joshua Chen + +Basic elaboration. +*) + +structure Elab: sig + +val elab: Proof.context -> cterm list -> term -> Envir.env +val elab_stmt: Proof.context -> cterm list -> term -> Envir.env * term + +end = struct + +(*Elaborate `tm` by solving the inference problem `tm: {}`, knowing `assums`, + which are fully elaborated, in `ctxt`. Return a substitution.*) +fun elab ctxt assums tm = + if Lib.no_vars tm + then Envir.init + else + let + val inf = Goal.init (Thm.cterm_of ctxt (Lib.typing_of_term tm)) + val res = Types.check_infer (map Thm.assume assums) 1 (ctxt, inf) + val tm' = + Thm.prop_of (#2 (Seq.hd (Seq.filter_results res))) + |> Lib.dest_prop |> Lib.term_of_typing + handle TERM ("dest_typing", [t]) => + let val typ = Logic.unprotect (Logic.strip_assums_concl t) + |> Lib.term_of_typing + in + error ("Elaboration of " ^ Syntax.string_of_term ctxt typ ^ " failed") + end + in + Seq.hd (Unify.matchers (Context.Proof ctxt) [(tm, tm')]) + end + handle Option => error + ("Elaboration of " ^ Syntax.string_of_term ctxt tm ^ " failed") + +(*Recursively elaborate a statement \<And>x ... y. \<lbrakk>...\<rbrakk> \<Longrightarrow> P x ... y by elaborating + only the types of typing judgments (in particular, does not look at judgmental + equality statements). Could also elaborate the terms of typing judgments, but + for now we assume that these are always free variables in all the cases we're + interested in.*) +fun elab_stmt ctxt assums stmt = + let + val stmt = Lib.dest_prop stmt + fun subst_term env = Envir.subst_term (Envir.type_env env, Envir.term_env env) + in + if Lib.no_vars stmt orelse Lib.is_eq stmt then + (Envir.init, stmt) + else if Lib.is_typing stmt then + let + val typ = Lib.type_of_typing stmt + val subst = elab ctxt assums typ + in (subst, subst_term subst stmt) end + else + let + fun elab' assums (x :: xs) = + let + val (env, x') = elab_stmt ctxt assums x + val assums' = + if Lib.no_vars x' then Thm.cterm_of ctxt x' :: assums else assums + in env :: elab' assums' xs end + | elab' _ [] = [] + val (prems, concl) = Lib.decompose_goal ctxt stmt + val subst = fold (curry Envir.merge) (elab' assums prems) Envir.init + val prems' = map (Thm.cterm_of ctxt o subst_term subst) prems + val subst' = + if Lib.is_typing concl then + let val typ = Lib.type_of_typing concl + in Envir.merge (subst, elab ctxt (assums @ prems') typ) end + else subst + in (subst', subst_term subst' stmt) end + end + + +end |