]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_unification/cicRefine.ml
added coercions to Prod
[helm.git] / helm / ocaml / cic_unification / cicRefine.ml
index b450d25021d35ab496f4bc87a7831c343d833411..e3392bf05ff949b9778aa96eccbe43d56b598aa7 100644 (file)
@@ -51,7 +51,7 @@ in profiler.HExtlib.profile foo ()
       (CicUnification.UnificationFailure msg) -> raise (RefineFailure (UnificationFailure msg))
     | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
 ;;
-
+                       
 let rec split l n =
  match (l,n) with
     (l,0) -> ([], l)
@@ -259,11 +259,61 @@ and type_of_aux' metasenv context t ugraph =
               type_of_aux subst' metasenv' 
                 ((Some (name,(C.Decl s')))::context) t ugraph1
            in
-            let sop,subst''',metasenv''',ugraph3 =
-              sort_of_prod subst'' metasenv'' 
-                context (name,s') (sort1,sort2) ugraph2
-            in
-              C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
+            (try
+              let sop,subst''',metasenv''',ugraph3 =
+                sort_of_prod subst'' metasenv'' 
+                  context (name,s') (sort1,sort2) ugraph2
+              in
+                C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
+            with
+            | RefineFailure _ as exn ->
+                (* given [t] of type [type_to_coerce] returns
+                 * a term that has type [tgt_sort] eventually 
+                 * derived from (coercion [t]) *)
+                let refined_target = t' in
+                let sort_of_refined_target = sort2 in
+                let carr t subst context = CicMetaSubst.apply_subst subst t in
+                let coerce_to_sort tgt_sort t type_to_coerce subst ctx =
+                  match type_to_coerce with
+                  | Cic.Sort _ -> t
+                  | term -> 
+                      let coercion_src = carr type_to_coerce subst ctx in
+                      let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
+                      let search = CoercGraph.look_for_coercion in
+                      (match search coercion_src coercion_tgt with
+                      | CoercGraph.NoCoercion 
+                      | CoercGraph.NotHandled _ -> raise exn
+                      | CoercGraph.NotMetaClosed -> 
+                          raise (Uncertain "Coercions on metas")
+                      | CoercGraph.SomeCoercion c -> Cic.Appl [c;t])
+                in
+                (* this is probably not the best... *)
+                let tgt_sort_for_pi_source = Cic.Type(CicUniv.fresh()) in
+                let tgt_sort_for_pi_target = Cic.Type(CicUniv.fresh()) in
+                let new_src = 
+                  coerce_to_sort tgt_sort_for_pi_source s sort1 subst context 
+                in
+                let context_with_new_src = 
+                  ((Some (name,(C.Decl new_src)))::context) 
+                in
+                let new_tgt = 
+                  coerce_to_sort 
+                    tgt_sort_for_pi_target 
+                    refined_target sort_of_refined_target
+                    subst context_with_new_src
+                in
+                let newprod = C.Prod (name,new_src,new_tgt) in
+                let _,sort_of_refined_prod,subst,metasenv,ugraph3 =
+                  type_of_aux subst metasenv context newprod ugraph2
+                in
+                (* this if for a coercion on the tail of the arrow *)
+                let new_target = 
+                  match sort_of_refined_target with
+                  | Cic.Sort _ -> refined_target
+                  | _ -> new_tgt
+                in
+                C.Prod(name,new_src,new_target),
+                sort_of_refined_prod,subst,metasenv,ugraph3) 
        | C.Lambda (n,s,t) ->
            let s',sort1,subst',metasenv',ugraph1 = 
              type_of_aux subst metasenv context s ugraph
@@ -800,35 +850,39 @@ and type_of_aux' metasenv context t ugraph =
     let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
       match (t1'', t2'') with
          (C.Sort s1, C.Sort s2)
-            when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) -> (* different than Coq manual!!! *)
+            when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) -> 
+              (* different than Coq manual!!! *)
               C.Sort s2,subst,metasenv,ugraph
        | (C.Sort (C.Type t1), C.Sort (C.Type t2)) -> 
-           (* TASSI: CONSRTAINTS: the same in cictypechecker, doubletypeinference *)
            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
        | (C.Sort _,C.Sort (C.Type t1)) -> 
-           (* TASSI: CONSRTAINTS: the same in cictypechecker, doubletypeinference *)
            C.Sort (C.Type t1),subst,metasenv,ugraph
        | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
        | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
             (* TODO how can we force the meta to become a sort? If we don't we
              * brake the invariant that refine produce only well typed terms *)
-            (* TODO if we check the non meta term and if it is a sort then we are
-             * likely to know the exact value of the result e.g. if the rhs is a
-             * Sort (Prop | Set | CProp) then the result is the rhs *)
+            (* TODO if we check the non meta term and if it is a sort then we
+             * are likely to know the exact value of the result e.g. if the rhs
+             * is a Sort (Prop | Set | CProp) then the result is the rhs *)
             let (metasenv,idx) =
               CicMkImplicit.mk_implicit_sort metasenv subst in
             let (subst, metasenv,ugraph1) =
-              fo_unif_subst subst context_for_t2 metasenv (C.Meta (idx,[])) t2'' ugraph
+              fo_unif_subst subst context_for_t2 metasenv 
+                (C.Meta (idx,[])) t2'' ugraph
             in
               t2'',subst,metasenv,ugraph1
-       | (_,_) ->
-            raise (RefineFailure (Reason (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''))))
+        | _,_ -> 
+            raise 
+              (RefineFailure 
+                (Reason 
+                  (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''))))
 
   and eat_prods subst metasenv context hetype tlbody_and_type ugraph =
     let rec mk_prod metasenv context =
@@ -899,13 +953,20 @@ and type_of_aux' metasenv context t ugraph =
                          hete,subst,metasenv,ugraph1
                     with exn ->
                        (* we search a coercion from hety to s *)
-                       let coer = CoercGraph.look_for_coercion 
-                         (CicMetaSubst.apply_subst subst hety) 
-                         (CicMetaSubst.apply_subst subst s) 
+                       let coer = 
+                         let carr t subst context = 
+                           CicMetaSubst.apply_subst subst t 
+                         in
+                         let c_hety = carr hety subst context in
+                         let c_s = carr s subst context in 
+                         CoercGraph.look_for_coercion c_hety c_s
                        in
                        match coer with
-                       | None -> raise exn
-                       | Some c -> 
+                       | CoercGraph.NoCoercion 
+                       | CoercGraph.NotHandled _ -> raise exn
+                       | CoercGraph.NotMetaClosed -> 
+                           raise (Uncertain "Coercions on meta")
+                       | CoercGraph.SomeCoercion c -> 
                            (Cic.Appl [ c ; hete ]), subst, metasenv, ugraph
                   in
                    let coerced_args,metasenv',subst',t',ugraph2 =