]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/ng_refiner/nCicRefiner.ml
Refinement of inductive type implemented.
[helm.git] / helm / software / components / ng_refiner / nCicRefiner.ml
index d73b4fddb5345db76a5663bf717a63bff111ba47..4807e5271938291a8e63e3b921ea7f220029caef 100644 (file)
@@ -536,21 +536,21 @@ let undebruijnate inductive ref t rev_fl =
 
 let typeof_obj hdb 
   ?(localise=fun _ -> Stdpp.dummy_loc) 
-  ~look_for_coercion (uri,height,metasenv,subst, obj)
+  ~look_for_coercion (uri,height,metasenv,subst,obj)
 = 
   let check_type metasenv subst (ty as orig_ty) =  (* XXX fattorizza *)
     let metasenv, subst, ty, sort = 
       typeof hdb ~localise ~look_for_coercion metasenv subst [] ty None
     in
-    let metasenv, subst, ty, _ = 
+    let metasenv, subst, ty, sort = 
       force_to_sort hdb ~look_for_coercion 
         metasenv subst [] ty orig_ty localise sort
     in
-      metasenv, subst, ty
+      metasenv, subst, ty, sort
   in
   match obj with 
   | C.Constant (relevance, name, bo, ty , attr) ->
-       let metasenv, subst, ty = check_type metasenv subst ty in
+       let metasenv, subst, ty, _ = check_type metasenv subst ty in
        let metasenv, subst, bo, ty, height = 
          match bo with
          | Some bo ->
@@ -569,7 +569,7 @@ let typeof_obj hdb
       let types, metasenv, subst, rev_fl =
         List.fold_left
          (fun (types, metasenv, subst, fl) (relevance,name,k,ty,bo) ->
-           let metasenv, subst, ty = check_type metasenv subst ty in
+           let metasenv, subst, ty, _ = check_type metasenv subst ty in
            let dbo = NCicTypeChecker.debruijn uri len [] bo in
            let localise = relocalise localise dbo bo in
             (name,C.Decl ty)::types,
@@ -601,85 +601,110 @@ let typeof_obj hdb
       in
        uri, height, metasenv, subst, 
          C.Fixpoint (inductive, fl, attr)
-
-  | C.Inductive (_ind, _leftno, _itl, _attr) ->  assert false
-(*
-  (* let's check if the arity of the inductive types are well formed *)
-  List.iter (fun (_,_,x,_) -> ignore (typeof ~subst ~metasenv [] x)) tyl;
-  (* let's check if the types of the inductive constructors are well formed. *)
-  let len = List.length tyl in
-  let tys = List.rev_map (fun (_,n,ty,_) -> (n,(C.Decl ty))) tyl in
-  ignore
-   (List.fold_right
-    (fun (it_relev,_,ty,cl) i ->
-       let context,ty_sort = split_prods ~subst [] ~-1 ty in
-       let sx_context_ty_rev,_ = HExtlib.split_nth leftno (List.rev context) in
-       List.iter
-         (fun (k_relev,_,te) ->
-          let _,k_relev = HExtlib.split_nth leftno k_relev in
-           let te = debruijn uri len [] te in
-           let context,te = split_prods ~subst tys leftno te in
-           let _,chopped_context_rev =
-            HExtlib.split_nth (List.length tys) (List.rev context) in
-           let sx_context_te_rev,_ =
-            HExtlib.split_nth leftno chopped_context_rev in
-           (try
-             ignore (List.fold_left2
-              (fun context item1 item2 ->
-                let convertible =
-                 match item1,item2 with
-                   (n1,C.Decl ty1),(n2,C.Decl ty2) ->
-                     n1 = n2 && 
-                     R.are_convertible ~metasenv ~subst context ty1 ty2
-                 | (n1,C.Def (bo1,ty1)),(n2,C.Def (bo2,ty2)) ->
-                     n1 = n2
-                     && R.are_convertible ~metasenv ~subst context ty1 ty2
-                     && R.are_convertible ~metasenv ~subst context bo1 bo2
-                 | _,_ -> false
-                in
-                 if not convertible then
-                  raise (TypeCheckerFailure (lazy
-                   ("Mismatch between the left parameters of the constructor " ^
-                    "and those of its inductive type")))
-                 else
-                  item1::context
-              ) [] sx_context_ty_rev sx_context_te_rev)
-            with Invalid_argument "List.fold_left2" -> assert false);
-           let con_sort = typeof ~subst ~metasenv context te in
-           (match R.whd ~subst context con_sort, R.whd ~subst [] ty_sort with
-               (C.Sort (C.Type u1) as s1), (C.Sort (C.Type u2) as s2) ->
-                if not (E.universe_leq u1 u2) then
-                 raise
-                  (TypeCheckerFailure
-                    (lazy ("The type " ^ PP.ppterm ~metasenv ~subst ~context s1^
-                      " of the constructor is not included in the inductive" ^
-                      " type sort " ^ PP.ppterm ~metasenv ~subst ~context s2)))
-             | C.Sort _, C.Sort C.Prop
-             | C.Sort _, C.Sort C.Type _ -> ()
-             | _, _ ->
+  | C.Inductive (ind, leftno, itl, attr) ->
+     let len = List.length itl in
+     let metasenv,subst,rev_itl,tys =
+      List.fold_left
+       (fun (metasenv,subst,res,ctx) (relevance,n,ty,cl) ->
+         let metasenv, subst, ty, _ = check_type metasenv subst ty in
+          metasenv,subst,(relevance,n,ty,cl)::res,(n,NCic.Decl ty)::ctx
+       ) (metasenv,subst,[],[]) itl in
+     let metasenv,subst,itl,_ =
+      List.fold_left
+       (fun (metasenv,subst,res,i) (it_relev,n,ty,cl) ->
+         let context,ty_sort = NCicReduction.split_prods ~subst [] ~-1 ty in
+         let sx_context_ty_rev,_= HExtlib.split_nth leftno (List.rev context) in
+         let metasenv,subst,cl =
+          List.fold_right
+           (fun (k_relev,n,te) (metasenv,subst,res) ->
+            let _,k_relev = HExtlib.split_nth leftno k_relev in
+             let te = NCicTypeChecker.debruijn uri len [] te in
+             let context,te = NCicReduction.split_prods ~subst tys leftno te in
+             let _,chopped_context_rev =
+              HExtlib.split_nth (List.length tys) (List.rev context) in
+             let sx_context_te_rev,_ =
+              HExtlib.split_nth leftno chopped_context_rev in
+             let metasenv,subst,_ =
+              try
+               List.fold_left2
+                (fun (metasenv,subst,context) item1 item2 ->
+                  let (metasenv,subst),convertible =
+                   try
+                    match item1,item2 with
+                      (n1,C.Decl ty1),(n2,C.Decl ty2) ->
+                        if n1 = n2 then
+                         NCicUnification.unify hdb ~test_eq_only:true metasenv
+                          subst context ty1 ty2,true
+                        else
+                         (metasenv,subst),false
+                    | (n1,C.Def (bo1,ty1)),(n2,C.Def (bo2,ty2)) ->
+                        if n1 = n2 then
+                         let metasenv,subst =
+                          NCicUnification.unify hdb ~test_eq_only:true metasenv
+                           subst context ty1 ty2
+                         in
+                          NCicUnification.unify hdb ~test_eq_only:true metasenv
+                           subst context bo1 bo2,true
+                        else
+                         (metasenv,subst),false
+                    | _,_ -> (metasenv,subst),false
+                   with
+                   | NCicUnification.Uncertain _
+                   | NCicUnification.UnificationFailure _ ->
+                      (metasenv,subst),false
+                  in
+                   let term2 =
+                    match item2 with
+                       _,C.Decl t -> t
+                     | _,C.Def (b,_) -> b in
+                   if not convertible then
+                    raise (RefineFailure (lazy (localise term2,
+                     ("Mismatch between the left parameters of the constructor " ^
+                      "and those of its inductive type"))))
+                   else
+                    metasenv,subst,item1::context
+                ) (metasenv,subst,[]) sx_context_ty_rev sx_context_te_rev
+              with Invalid_argument "List.fold_left2" -> assert false
+             in
+             let metasenv, subst, te, con_sort = check_type metasenv subst te in
+              (match
+                NCicReduction.whd ~subst context con_sort,
+                NCicReduction.whd ~subst [] ty_sort
+               with
+                  (C.Sort (C.Type u1) as s1), (C.Sort (C.Type u2) as s2) ->
+                   if not (NCicEnvironment.universe_leq u1 u2) then
+                    raise
+                     (RefineFailure
+                       (lazy(localise te, "The type " ^
+                         NCicPp.ppterm ~metasenv ~subst ~context s1 ^
+                         " of the constructor is not included in the inductive"^
+                         " type sort " ^
+                         NCicPp.ppterm ~metasenv ~subst ~context s2)))
+                | C.Sort _, C.Sort C.Prop
+                | C.Sort _, C.Sort C.Type _ -> ()
+                | _, _ ->
+                   raise
+                    (RefineFailure
+                      (lazy (localise te,
+                        "Wrong constructor or inductive arity shape"))));
+              (* let's check also the positivity conditions *)
+              if 
+               not
+               (NCicTypeChecker.are_all_occurrences_positive
+                 ~subst context uri leftno (i+leftno) leftno (len+leftno) te) 
+              then
                 raise
-                 (TypeCheckerFailure
-                   (lazy ("Wrong constructor or inductive arity shape"))));
-           (* let's check also the positivity conditions *)
-           if 
-             not
-               (are_all_occurrences_positive ~subst context uri leftno
-                 (i+leftno) leftno (len+leftno) te) 
-           then
-             raise
-               (TypeCheckerFailure
-                 (lazy ("Non positive occurence in "^NUri.string_of_uri
-                uri)))
-           else check_relevance ~subst ~metasenv context k_relev te) 
-         cl;
-        check_relevance ~subst ~metasenv [] it_relev ty;
-       i+1)
-    tyl 1)
-*)
-
-
+                  (RefineFailure
+                    (lazy (localise te,
+                      "Non positive occurence in " ^ NUri.string_of_uri uri)))
+              else
+               metasenv,subst,(k_relev,n,te)::res
+              ) cl (metasenv,subst,[])
+         in
+          metasenv,subst,(it_relev,n,ty,cl)::res,i-1
+       ) (metasenv,subst,[],List.length rev_itl) rev_itl
+     in
+      uri, height, metasenv, subst, C.Inductive (ind, leftno, itl, attr)
 ;;
 
-
-
 (* vim:set foldmethod=marker: *)