-
Notifications
You must be signed in to change notification settings - Fork 40
Work on inference, unification and subject-reduction #328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f2bd761
8f068a0
a8b9916
50069df
17a6a50
465215c
9865cc8
ce199bc
d82b019
db583e2
e91ee90
588eddc
d369293
2706e78
212e1cc
7790644
b2b7d03
28e84a0
05996f8
0b8037a
e7b7bc7
e285838
e0d283d
05710a7
c051cef
542660b
f798b2a
27ceb83
5a3040c
a94a34b
95057aa
d5dd1ee
105d47d
036b8b5
f440308
4aa951e
f86ad7b
f727612
fccfd7c
b0e1bb9
d1e0561
cd798e5
759131a
6245738
d1f39eb
91a1452
f76704b
935bff8
a5c3611
abe7462
a188591
ee234b9
9c9ce7c
f1a94f1
6b532da
445be54
f6a3405
057d6a0
2d7742b
8277830
17c2d41
264dd66
81557c2
e5dd8a6
8a784d1
2af80c3
5eb7eda
07a3f39
d367273
0cc857f
a0e1f3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ type stack = term list | |
|
|
||
| (** [whnf_beta t] computes a weak head beta normal form of the term [t]. *) | ||
| let rec whnf_beta : term -> term = fun t -> | ||
| if !log_enabled then log_eval "evaluating [%a]" pp t; | ||
| if !log_enabled then log_eval "evaluating %a" pp t; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I would keep the brackets for readability. |
||
| let s = Stdlib.(!steps) in | ||
| let (u, stk) = whnf_beta_stk t [] in | ||
| if Stdlib.(!steps) <> s then add_args u stk else unfold t | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,7 @@ let constraints = Stdlib.ref [] | |
|
|
||
| (** Function adding a constraint. *) | ||
| let conv ctx a b = | ||
| if not (Basics.eq ctx a b) then | ||
| if not (Eval.eq_modulo ctx a b) then | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using equality here had a significant positive impact on performances if I remember well. Conversion on the other end can be very costly, and if it fails it is gonna be tested again partially by unification.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not clear. We should compare the performances.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't compare anymore because |
||
| begin | ||
| if !log_enabled then log_infr (yel "add %a") pp_constr (ctx,a,b); | ||
| let open Stdlib in constraints := (ctx,a,b) :: !constraints | ||
|
|
@@ -37,7 +37,7 @@ let make_meta_codomain : ctxt -> term -> tbinder = fun ctx a -> | |
| constraints are satisfied. [ctx] must be well-formed. This function | ||
| never fails (but constraints may be unsatisfiable). *) | ||
| let rec infer : ctxt -> term -> term = fun ctx t -> | ||
| if !log_enabled then log_infr "infer [%a]" pp t; | ||
| if !log_enabled then log_infr "infer %a%a" pp_ctxt ctx pp t; | ||
| match unfold t with | ||
| | Patt(_,_,_) -> assert false (* Forbidden case. *) | ||
| | TEnv(_,_) -> assert false (* Forbidden case. *) | ||
|
|
@@ -51,11 +51,19 @@ let rec infer : ctxt -> term -> term = fun ctx t -> | |
|
|
||
| (* --------------------------------- | ||
| ctx ⊢ Vari(x) ⇒ Ctxt.find x ctx *) | ||
| | Vari(x) -> (try Ctxt.type_of x ctx with Not_found -> assert false) | ||
| | Vari(x) -> | ||
| let a = try Ctxt.type_of x ctx with Not_found -> assert false in | ||
| if !log_enabled then | ||
| log_infr (blu "%a : %a") pp_term t pp_term a; | ||
| a | ||
|
|
||
| (* ------------------------------- | ||
| ctx ⊢ Symb(s) ⇒ !(s.sym_type) *) | ||
| | Symb(s,_) -> !(s.sym_type) | ||
| | Symb(s,_) -> | ||
| let a = !(s.sym_type) in | ||
| if !log_enabled then | ||
| log_infr (blu "%a : %a") pp_term t pp_term a; | ||
| a | ||
|
|
||
| (* ctx ⊢ a ⇐ Type ctx, x : a ⊢ b<x> ⇒ s | ||
| ----------------------------------------- | ||
|
|
@@ -127,54 +135,16 @@ let rec infer : ctxt -> term -> term = fun ctx t -> | |
| (* ctx ⊢ term_of_meta m e ⇒ a | ||
| ---------------------------- | ||
| ctx ⊢ Meta(m,e) ⇒ a *) | ||
| | Meta(m,e) -> | ||
| if !log_enabled then | ||
| log_infr (yel "%s is of type [%a]") (meta_name m) pp !(m.meta_type); | ||
| infer ctx (term_of_meta m e) | ||
| | Meta(m,ts) -> | ||
| infer ctx (term_of_meta m ts) | ||
|
|
||
| (** [check ctx t c] checks that the term [t] has type [c] in context | ||
| [ctx], possibly under some constraints recorded in [constraints] | ||
| using [conv]. [ctx] must be well-formed and [c] well-sorted. This | ||
| function never fails (but constraints may be unsatisfiable). *) | ||
|
|
||
| (* [check ctx t c] could be reduced to the default case [conv | ||
| (infer ctx t) c]. We however provide some more efficient | ||
| code when [t] is an abstraction, as witnessed by 'make holide': | ||
|
|
||
| Finished in 3:56.61 at 99% with 3180096Kb of RAM | ||
|
|
||
| Finished in 3:46.13 at 99% with 2724844Kb of RAM | ||
|
|
||
| This avoids to build a product to destructure it just after. *) | ||
| and check : ctxt -> term -> term -> unit = fun ctx t c -> | ||
| if !log_enabled then log_infr "check [%a] [%a]" pp t pp c; | ||
| match unfold t with | ||
| (* c → Prod(d,b) a ~ d ctx, x : A ⊢ t<x> ⇐ b<x> | ||
| ---------------------------------------------------- | ||
| ctx ⊢ Abst(a,t) ⇐ c *) | ||
| | Abst(a,t) -> | ||
| (* We ensure that [a] is of type [Type]. *) | ||
| check ctx a Type; | ||
| (* We (hopefully) evaluate [c] to a product, and get its body. *) | ||
| let b = | ||
| let c = Eval.whnf ctx c in | ||
| match c with | ||
| | Prod(d,b) -> conv ctx d a; b (* Domains must be convertible. *) | ||
| | Meta(m,ts) -> | ||
| let mxs, p, _bp1, bp2 = Env.extend_meta_type m in | ||
| conv ctx mxs p; Bindlib.msubst bp2 ts | ||
| | _ -> | ||
| let b = make_meta_codomain ctx a in | ||
| conv ctx c (Prod(a,b)); b | ||
| in | ||
| (* We type-check the body with the codomain. *) | ||
| let (x,t,ctx') = Ctxt.unbind ctx a None t in | ||
| check ctx' t (Bindlib.subst b (Vari(x))) | ||
| | t -> | ||
| (* ctx ⊢ t ⇒ a | ||
| ------------- | ||
| ctx ⊢ t ⇐ a *) | ||
| conv ctx (infer ctx t) c | ||
| if !log_enabled then log_infr "check %a : %a" pp t pp c; | ||
| conv ctx (infer ctx t) c | ||
|
Comment on lines
+146
to
+147
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I remember well, this had a significant performance impact. Did you run benchmarks? |
||
|
|
||
| (** [infer ctx t] returns a pair [(a,cs)] where [a] is a type for the | ||
| term [t] in the context [ctx], under unification constraints [cs]. | ||
|
|
@@ -187,8 +157,8 @@ let infer : ctxt -> term -> term * unif_constrs = fun ctx t -> | |
| let constrs = Stdlib.(!constraints) in | ||
| if !log_enabled then | ||
| begin | ||
| log_infr (gre "infer [%a] yields [%a]") pp t pp a; | ||
| List.iter (log_infr " assuming %a" pp_constr) constrs; | ||
| log_infr (gre "infer %a : %a") pp t pp a; | ||
fblanqui marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| List.iter (log_infr " if %a" pp_constr) constrs; | ||
| end; | ||
| Stdlib.(constraints := []); | ||
| (a, constrs) | ||
|
|
@@ -204,8 +174,8 @@ let check : ctxt -> term -> term -> unif_constrs = fun ctx t c -> | |
| let constrs = Stdlib.(!constraints) in | ||
| if !log_enabled then | ||
| begin | ||
| log_infr (gre "check [%a] [%a]") pp t pp c; | ||
| List.iter (log_infr " assuming %a" pp_constr) constrs; | ||
| log_infr (gre "check %a : %a") pp t pp c; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel that brackets were useful for readability here. |
||
| List.iter (log_infr " if %a" pp_constr) constrs; | ||
| end; | ||
| Stdlib.(constraints := []); | ||
| constrs | ||
Uh oh!
There was an error while loading. Please reload this page.