]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/cic_unification/cicRefine.ml
1. is_meta_closed should be applied only to terms on which a substitution
[helm.git] / helm / software / components / cic_unification / cicRefine.ml
index 0ef14696c5d46c68075698cde0f36070629f072c..8ae5964c9cf209a8ba43ea65a1c9efcbd0329b40 100644 (file)
@@ -78,6 +78,7 @@ let enrich localization_tbl t ?(f = fun msg -> msg) exn =
   match exn with
      RefineFailure msg -> RefineFailure (f msg)
    | Uncertain msg -> Uncertain (f msg)
+   | Sys.Break -> raise exn
    | _ -> assert false in
  let loc =
   try
@@ -140,7 +141,7 @@ let is_a_double_coercion t =
       | sib1,Cic.Appl (c2::tl2) when CoercGraph.is_a_coercion c2 ->
           let sib2,head = last_of tl2 in
           true, c1, c2, head,Cic.Appl (c1::sib1@[Cic.Appl
-            (c2::sib2@[Cic.Implicit None])]) 
+            (c2::sib2@[imp])]) 
       | _ -> dummyres)
   | _ -> dummyres
 
@@ -320,8 +321,11 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
      ugraph
 =
   let rec type_of_aux subst metasenv context t ugraph =
+    let module C = Cic in
+    let module S = CicSubstitution in
+    let module U = UriManager in
     let try_coercion t subst metasenv context ugraph coercion_tgt c =
-      let coerced = Cic.Appl[c;t] in
+      let coerced = C.Appl[c;t] in
       try
         let newt,_,subst,metasenv,ugraph = 
           type_of_aux subst metasenv context coerced ugraph 
@@ -333,9 +337,6 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
       with 
       | RefineFailure _ | Uncertain _ -> None
     in
-    let module C = Cic in
-    let module S = CicSubstitution in
-    let module U = UriManager in
      let (t',_,_,_,_) as res =
       match t with
           (*    function *)
@@ -357,9 +358,9 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                     enrich localization_tbl t
                      (RefineFailure (lazy "Rel to hidden hypothesis"))
              with
-              _ ->
+              Failure _ ->
                enrich localization_tbl t
-                (RefineFailure (lazy "Not a close term")))
+                (RefineFailure (lazy "Not a closed term")))
         | C.Var (uri,exp_named_subst) ->
             let exp_named_subst',subst',metasenv',ugraph1 =
               check_exp_named_subst 
@@ -394,8 +395,11 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                    subst', metasenv',ugraph1)
         | C.Sort (C.Type tno) -> 
             let tno' = CicUniv.fresh() in 
-            let ugraph1 = CicUniv.add_gt tno' tno ugraph in
-              t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
+             (try
+               let ugraph1 = CicUniv.add_gt tno' tno ugraph in
+                 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
+              with
+               CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
         | C.Sort _ -> 
             t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
         | C.Implicit infos ->
@@ -501,8 +505,8 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
               t' sort2 subst'' context_for_t metasenv'' ugraph2
             in
               let sop,subst''',metasenv''',ugraph3 =
-                sort_of_prod subst'' metasenv'' 
-                  context (name,s') (sort1,sort2) ugraph2
+                sort_of_prod localization_tbl subst'' metasenv'' 
+                  context (name,s') t' (sort1,sort2) ugraph2
               in
                 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
         | C.Lambda (n,s,t) ->
@@ -578,8 +582,9 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                * Even faster than the previous solution.
                * Moreover the inferred type is closer to the expected one. 
                *)
-              C.LetIn (n,s',t'),CicSubstitution.subst s' inferredty,
-                subst'',metasenv'',ugraph2
+              C.LetIn (n,s',t'),
+               CicSubstitution.subst ~avoid_beta_redexes:true s' inferredty,
+               subst'',metasenv'',ugraph2
         | C.Appl (he::((_::_) as tl)) ->
             let he',hetype,subst',metasenv',ugraph1 = 
               type_of_aux subst metasenv context he ugraph 
@@ -1059,6 +1064,7 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                | Some t,Some (_,C.Def (ct,_)) ->
                    let subst',metasenv',ugraph' = 
                    (try
+prerr_endline ("poco geniale: nel caso di IRL basterebbe sapere che questo e' il Rel corrispondente. Si puo' ottimizzare il caso t = rel.");
                       fo_unif_subst subst context metasenv t ct ugraph
                     with e -> raise (RefineFailure (lazy (sprintf "The local context is not consistent with the canonical context, since %s cannot be unified with %s. Reason: %s" (CicMetaSubst.ppterm subst t) (CicMetaSubst.ppterm subst ct) (match e with AssertFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
                    in
@@ -1130,7 +1136,9 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
       check_exp_named_subst_aux metasubst metasenv [] tl ugraph
 
 
-  and sort_of_prod subst metasenv context (name,s) (t1, t2) ugraph =
+  and sort_of_prod localization_tbl subst metasenv context (name,s) t (t1, t2)
+   ugraph
+  =
     let module C = Cic in
     let context_for_t2 = (Some (name,C.Decl s))::context in
     let t1'' = CicReduction.whd ~subst context t1 in
@@ -1142,9 +1150,12 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
               C.Sort s2,subst,metasenv,ugraph
         | (C.Sort (C.Type t1), C.Sort (C.Type t2)) -> 
             let t' = CicUniv.fresh() in 
-            let ugraph1 = CicUniv.add_ge t' t1 ugraph in
-            let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
-              C.Sort (C.Type t'),subst,metasenv,ugraph2
+             (try
+              let ugraph1 = CicUniv.add_ge t' t1 ugraph in
+              let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
+                C.Sort (C.Type t'),subst,metasenv,ugraph2
+              with
+               CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
         | (C.Sort _,C.Sort (C.Type t1)) -> 
             C.Sort (C.Type t1),subst,metasenv,ugraph
         | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
@@ -1163,17 +1174,28 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
              with _ -> assert false (* unification against a metavariable *)
             in
               t2'',subst,metasenv,ugraph1
+        | (C.Sort _,_)
+        | (C.Meta _,_) -> 
+            enrich localization_tbl s
+             (RefineFailure 
+               (lazy 
+                 (sprintf
+                   "%s is supposed to be a type, but its type is %s"
+               (CicMetaSubst.ppterm_in_context subst t context)
+               (CicMetaSubst.ppterm_in_context subst t2 context))))
         | _,_ -> 
-            raise 
-              (RefineFailure 
-                (lazy 
-                  (sprintf
-                    ("Two sorts were expected, found %s " ^^ 
-                     "(that reduces to %s) and %s (that reduces to %s)")
-                (CicPp.ppterm t1) (CicPp.ppterm t1'') (CicPp.ppterm t2)
-                (CicPp.ppterm t2''))))
+            enrich localization_tbl t
+             (RefineFailure 
+               (lazy 
+                 (sprintf
+                   "%s is supposed to be a type, but its type is %s"
+               (CicMetaSubst.ppterm_in_context subst s context)
+               (CicMetaSubst.ppterm_in_context subst t1 context))))
 
   and avoid_double_coercion context subst metasenv ugraph t ty = 
+   if not !pack_coercions then
+    t,ty,subst,metasenv,ugraph
+   else
     let b, c1, c2, head, c1_c2_implicit = is_a_double_coercion t in
     if b then
       let source_carr = CoercGraph.source_of c2 in
@@ -1214,11 +1236,12 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                | RefineFailure s | Uncertain s -> 
                    debug_print s;debug_print (lazy "goon\n");
                    try 
+                     let old_pack_coercions = !pack_coercions in
                      pack_coercions := false; (* to avoid diverging *)
                      let refined_c1_c2_implicit,ty,subst,metasenv,ugraph =
                        type_of_aux subst metasenv context c1_c2_implicit ugraph 
                      in
-                     pack_coercions := true;
+                     pack_coercions := old_pack_coercions;
                      let b, _, _, _, _ = 
                        is_a_double_coercion refined_c1_c2_implicit 
                      in 
@@ -1402,8 +1425,8 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                     (match coer with
                     | CoercGraph.NoCoercion 
                     | CoercGraph.NotHandled _ ->
-                        enrich localization_tbl hete
-                         (RefineFailure
+                        enrich localization_tbl hete exn
+                         ~f:(fun _ ->
                            (lazy ("The term " ^
                              CicMetaSubst.ppterm_in_context subst hete
                               context ^ " has type " ^
@@ -1412,8 +1435,8 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                              CicMetaSubst.ppterm_in_context subst s context
                               (* "\nReason: " ^ Lazy.force e*))))
                     | CoercGraph.NotMetaClosed -> 
-                        enrich localization_tbl hete
-                         (Uncertain
+                        enrich localization_tbl hete exn
+                         ~f:(fun _ ->
                            (lazy ("The term " ^
                              CicMetaSubst.ppterm_in_context subst hete
                               context ^ " has type " ^
@@ -1463,8 +1486,8 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
                            context ^ " has type " ^
                           CicMetaSubst.ppterm_in_context subst hety
                            context ^ " but is here used with type " ^
-                          CicMetaSubst.ppterm_in_context subst s context ^
-                           "\nReason: " ^ Printexc.to_string exn))) exn
+                          CicMetaSubst.ppterm_in_context subst s context
+                           (* "\nReason: " ^ Printexc.to_string exn*)))) exn
                   (* }}} end coercion stuff *)
                 in
                   eat_prods_and_args pristinemenv metasenv subst context pristinehe he
@@ -1487,12 +1510,17 @@ and type_of_aux' ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
     in
     (* first we check if we are in the simple case of a meta closed term *)
     let subst,metasenv,ugraph1,hetype',he,args_bo_and_ty =
-     if CicUtil.is_meta_closed hetype then
+     if CicUtil.is_meta_closed (CicMetaSubst.apply_subst subst hetype) then
       (* this optimization is to postpone fix_arity (the most common case)*)
       subst,metasenv,ugraph,hetype,he,args_bo_and_ty
      else
        (* this (says CSC) is also useful to infer dependent types *)
-       fix_arity metasenv context subst he hetype args_bo_and_ty ugraph
+       try
+        fix_arity metasenv context subst he hetype args_bo_and_ty ugraph
+       with RefineFailure _ | Uncertain _ as exn ->
+         (* unable to fix arity *)
+          more_args_than_expected localization_tbl 
+            subst he context hetype args_bo_and_ty exn
     in
     let coerced_args,subst,metasenv,he,t,ugraph =
       eat_prods_and_args 
@@ -1724,7 +1752,11 @@ let pack_coercion metasenv ctx t =
        let ctx' = (Some (name,C.Decl so))::ctx in
        C.Lambda (name, merge_coercions ctx so, merge_coercions ctx' dest)
    | C.LetIn (name,so,dest) -> 
-       let ctx' = Some (name,(C.Def (so,None)))::ctx in
+       let _,ty,metasenv,ugraph =
+        pack_coercions := false;
+        type_of_aux' metasenv ctx so CicUniv.empty_ugraph in
+        pack_coercions := true;
+       let ctx' = Some (name,(C.Def (so,Some ty)))::ctx in
        C.LetIn (name, merge_coercions ctx so, merge_coercions ctx' dest)
    | C.Appl l -> 
       let l = List.map (merge_coercions ctx) l in
@@ -1739,7 +1771,6 @@ let pack_coercion metasenv ctx t =
            try 
              type_of_aux' metasenv ctx t ugraph 
            with RefineFailure _ | Uncertain _ -> 
-             prerr_endline (CicPp.ppterm t);
              t, t, [], ugraph 
          in
          insert_coercions := old_insert_coercions;
@@ -1794,6 +1825,31 @@ let pack_coercion metasenv ctx t =
   merge_coercions ctx t
 ;;
 
+let pack_coercion_metasenv conjectures =
+  let module C = Cic in
+  List.map 
+    (fun (i, ctx, ty) -> 
+       let ctx = 
+         List.fold_right 
+           (fun item ctx ->
+              let item' =
+                match item with
+                    Some (name, C.Decl t) -> 
+                      Some (name, C.Decl (pack_coercion conjectures ctx t))
+                  | Some (name, C.Def (t,None)) -> 
+                      Some (name,C.Def (pack_coercion conjectures ctx t,None))
+                  | Some (name, C.Def (t,Some ty)) -> 
+                      Some (name, C.Def (pack_coercion conjectures ctx t, 
+                                        Some (pack_coercion conjectures ctx ty)))
+                  | None -> None
+              in
+                item'::ctx
+           ) ctx []
+       in
+         ((i,ctx,pack_coercion conjectures ctx ty))
+    ) conjectures
+;;
+
 let pack_coercion_obj obj =
   let module C = Cic in
   match obj with
@@ -1814,29 +1870,7 @@ let pack_coercion_obj obj =
       let ty = pack_coercion [] [] ty in
         C.Variable (name, body, ty, params, attrs)
   | C.CurrentProof (name, conjectures, body, ty, params, attrs) ->
-      let conjectures = 
-        List.map 
-          (fun (i, ctx, ty) -> 
-            let ctx = 
-              List.fold_right 
-                (fun item ctx ->
-                  let item' =
-                   match item with
-                      Some (name, C.Decl t) -> 
-                        Some (name, C.Decl (pack_coercion conjectures ctx t))
-                    | Some (name, C.Def (t,None)) -> 
-                        Some (name,C.Def (pack_coercion conjectures ctx t,None))
-                    | Some (name, C.Def (t,Some ty)) -> 
-                        Some (name, C.Def (pack_coercion conjectures ctx t, 
-                                       Some (pack_coercion conjectures ctx ty)))
-                    | None -> None
-                  in
-                   item'::ctx
-                ) ctx []
-            in
-             ((i,ctx,pack_coercion conjectures ctx ty))
-          ) conjectures
-      in
+      let conjectures = pack_coercion_metasenv conjectures in
       let body = pack_coercion conjectures [] body in
       let ty = pack_coercion conjectures [] ty in
       C.CurrentProof (name, conjectures, body, ty, params, attrs)