- 
                Notifications
    You must be signed in to change notification settings 
- Fork 38
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 69 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; | ||
| 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 | ||
| 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. 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. 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
    
   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; | ||
| 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.