]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/components/ng_kernel/nCicTypeChecker.ml
Cooking implemented (not tested yet).
[helm.git] / helm / software / components / ng_kernel / nCicTypeChecker.ml
index f96a6f31782d3eb44f1743e9120bf02daff2fb83..b9a585f97e0eeaa10d776e166d97c4392afc4ff2 100644 (file)
@@ -239,70 +239,6 @@ and are_all_occurrences_positive context uri indparamsno i n nn te =
       (TypeCheckerFailure (lazy ("Malformed inductive constructor type " ^
         (UriManager.string_of_uri uri))))
 
-(* Main function to checks the correctness of a mutual *)
-(* inductive block definition. This is the function    *)
-(* exported to the proof-engine.                       *)
-and typecheck_mutual_inductive_defs ~logger uri (itl,_,indparamsno) ugraph =
- let module U = UriManager in
-  (* let's check if the arity of the inductive types are well *)
-  (* formed                                                   *)
-  let ugrap1 = List.fold_left 
-   (fun ugraph (_,_,x,_) -> let _,ugraph' = 
-      type_of ~logger x ugraph in ugraph') 
-   ugraph itl in
-
-  (* let's check if the types of the inductive constructors  *)
-  (* are well formed.                                        *)
-  (* In order not to use type_of_aux we put the types of the *)
-  (* mutual inductive types at the head of the types of the  *)
-  (* constructors using Prods                                *)
-  let len = List.length itl in
-  let tys =
-    List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl in
-  let _,ugraph2 =
-    List.fold_right
-      (fun (_,_,_,cl) (i,ugraph) ->
-        let ugraph'' = 
-          List.fold_left
-            (fun ugraph (name,te) -> 
-              let debruijnedte = debruijn uri len te in
-              let augmented_term =
-                List.fold_right
-                  (fun (name,_,ty,_) i -> Cic.Prod (Cic.Name name, ty, i))
-                  itl debruijnedte
-              in
-              let _,ugraph' = type_of ~logger augmented_term ugraph in
-              (* let's check also the positivity conditions *)
-              if
-                not
-                  (are_all_occurrences_positive tys uri indparamsno i 0 len
-                     debruijnedte)
-              then
-                begin
-                prerr_endline (UriManager.string_of_uri uri);
-                prerr_endline (string_of_int (List.length tys));
-                raise
-                  (TypeCheckerFailure
-                    (lazy ("Non positive occurence in " ^ U.string_of_uri uri)))                end 
-              else
-                ugraph'
-            ) ugraph cl in
-        (i + 1),ugraph''
-      ) itl (1,ugrap1)
-  in
-  ugraph2
-
-(* Main function to checks the correctness of a mutual *)
-(* inductive block definition.                         *)
-and check_mutual_inductive_defs uri obj ugraph =
-  match obj with
-      Cic.InductiveDefinition (itl, params, indparamsno, _) ->
-        typecheck_mutual_inductive_defs uri (itl,params,indparamsno) ugraph 
-    | _ ->
-        raise (TypeCheckerFailure (
-                lazy ("Unknown mutual inductive definition:" ^
-                 UriManager.string_of_uri uri)))
-
 (* the boolean h means already protected *)
 (* args is the list of arguments the type of the constructor that may be *)
 (* found in head position must be applied to.                            *)
@@ -610,9 +546,10 @@ let eat_prods ~subst ~metasenv context ty_he args_with_ty =
       (match R.whd ~subst context ty_he with 
       | C.Prod (n,s,t) ->
 (*
-          prerr_endline (NCicPp.ppterm ~context s ^ " - Vs - " ^ NCicPp.ppterm
+          prerr_endline (NCicPp.ppterm ~subst ~metasenv ~context s ^ " - Vs - "
+          ^ NCicPp.ppterm ~subst ~metasenv
           ~context ty_arg);
-          prerr_endline (NCicPp.ppterm ~context (S.subst ~avoid_beta_redexes:true arg t));
+          prerr_endline (NCicPp.ppterm ~subst ~metasenv ~context (S.subst ~avoid_beta_redexes:true arg t));
 *)
           if R.are_convertible ~subst ~metasenv context ty_arg s then
             aux (S.subst ~avoid_beta_redexes:true arg t) tl
@@ -621,8 +558,8 @@ let eat_prods ~subst ~metasenv context ty_he args_with_ty =
               (TypeCheckerFailure 
                 (lazy (Printf.sprintf
                   ("Appl: wrong parameter-type, expected %s, found %s")
-                  (NCicPp.ppterm ~subst ~metasenv ~context ty_arg) 
-                  (NCicPp.ppterm ~subst ~metasenv ~context s))))
+                  (NCicPp.ppterm ~subst ~metasenv ~context s)
+                  (NCicPp.ppterm ~subst ~metasenv ~context ty_arg))))
        | _ ->
           raise 
             (TypeCheckerFailure
@@ -644,7 +581,7 @@ let fix_lefts_in_constrs ~subst uri paramsno tyl i =
     cl 
   in
   let lefts = fst (split_prods ~subst [] paramsno arity) in
-  tys@lefts, len, cl'
+  lefts@tys, len, cl'
 ;;
 
 exception DoesOccur;;
@@ -718,6 +655,7 @@ let rec typeof ~subst ~metasenv context term =
          C.Prod (n,s,ty)
     | C.LetIn (n,ty,t,bo) ->
        let ty_t = typeof_aux context t in
+       let _ = typeof_aux context ty in
        if not (R.are_convertible ~subst ~metasenv context ty ty_t) then
          raise 
           (TypeCheckerFailure 
@@ -986,7 +924,31 @@ let rec typeof ~subst ~metasenv context term =
  in 
    typeof_aux context term
 
-and check_mutual_inductive_defs _ = ()
+and check_mutual_inductive_defs uri ~metasenv ~subst is_ind leftno tyl = 
+  (* 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.map (fun (_,n,ty,_) -> (n,(C.Decl ty))) tyl in
+  ignore
+   (List.fold_right
+    (fun (_,_,_,cl) i ->
+       List.iter
+         (fun (_,name,te) -> 
+           let debruijnedte = debruijn uri len te in
+           ignore (typeof ~subst ~metasenv tys debruijnedte);
+           (* let's check also the positivity conditions *)
+           if false (*
+             not
+               (are_all_occurrences_positive tys uri indparamsno i 0 len
+                  debruijnedte) *)
+           then
+             raise
+               (TypeCheckerFailure
+                 (lazy ("Non positive occurence in "^NUri.string_of_uri uri))))
+         cl;
+        i + 1)
+    tyl 1)
 
 and eat_lambdas ~subst ~metasenv context n te =
   match (n, R.whd ~subst context te) with
@@ -1016,7 +978,7 @@ and guarded_by_destructors ~subst ~metasenv context recfuns t =
          " is a partial application of a fix")))
      else
        let rec_arg = List.nth tl rec_no in
-       if not (is_really_smaller ~subst k rec_arg) then 
+       if not (is_really_smaller ~subst ~metasenv k rec_arg) then 
          raise (NotGuarded (lazy 
            (NCicPp.ppterm ~context ~subst ~metasenv rec_arg ^ " not smaller")));
        List.iter (aux k) tl
@@ -1032,7 +994,7 @@ and guarded_by_destructors ~subst ~metasenv context recfuns t =
          List.iter (aux k) args; 
          List.iter2
            (fun p (_,_,bruijnedc) ->
-             let rl = recursive_args ~subst c_ctx 0 len bruijnedc in
+             let rl = recursive_args ~subst ~metasenv c_ctx 0 len bruijnedc in
              let p, k = get_new_safes ~subst k p rl in
              aux k p) 
            pl cl
@@ -1084,13 +1046,16 @@ and guarded_by_destructors ~subst ~metasenv context recfuns t =
 
 and guarded_by_constructors ~subst _ _ _ _ _ _ _ = assert false
 
-and recursive_args ~subst context n nn te =
+and recursive_args ~subst ~metasenv context n nn te =
   match R.whd context te with
-  | C.Rel _ -> []
+  | C.Rel _ | C.Appl _ -> []
   | C.Prod (name,so,de) ->
      (not (does_not_occur ~subst context n nn so)) ::
-      (recursive_args ~subst ((name,(C.Decl so))::context) (n+1) (nn + 1) de)
-  | _ -> raise (AssertFailure (lazy ("recursive_args")))
+      (recursive_args ~subst ~metasenv 
+        ((name,(C.Decl so))::context) (n+1) (nn + 1) de)
+  | t -> 
+     raise (AssertFailure (lazy ("recursive_args:" ^ NCicPp.ppterm ~subst
+     ~metasenv ~context:[] t)))
 
 and get_new_safes ~subst (context, recfuns, x, safes as k) p rl =
   match R.whd ~subst context p, rl with
@@ -1108,7 +1073,7 @@ and split_prods ~subst context n te =
        split_prods ~subst ((name,(C.Decl so))::context) (n - 1) ta
   | _ -> raise (AssertFailure (lazy "split_prods"))
 
-and is_really_smaller ~subst (context, recfuns, x, safes as k) te =
+and is_really_smaller ~subst ~metasenv (context, recfuns, x, safes as k) te =
  match R.whd ~subst context te with
  | C.Rel m when List.mem m safes -> true
  | C.Rel _ -> false
@@ -1121,7 +1086,7 @@ and is_really_smaller ~subst (context, recfuns, x, safes as k) te =
     (*CSC: sulla coda ci vogliono dei controlli? secondo noi no, ma *)
     (*CSC: solo perche' non abbiamo trovato controesempi            *)
     (*TASSI: da capire soprattutto se he รจ un altro fix che non ha ridotto...*)
-    is_really_smaller ~subst k he
+    is_really_smaller ~subst ~metasenv k he
  | C.Const (Ref.Ref (_,_,Ref.Con _)) -> false
  | C.Const (Ref.Ref (_,_,Ref.Fix _)) -> assert false
    (*| C.Fix (_, fl) ->
@@ -1150,16 +1115,16 @@ and is_really_smaller ~subst (context, recfuns, x, safes as k) te =
     | C.Rel m | C.Appl (C.Rel m :: _ ) when List.mem m safes || m = x ->
         let isinductive, paramsno, tl, _, i = E.get_checked_indtys ref in
         if not isinductive then
-          List.for_all (is_really_smaller ~subst k) pl
+          List.for_all (is_really_smaller ~subst ~metasenv k) pl
         else
           let c_ctx,len,cl = fix_lefts_in_constrs ~subst uri paramsno tl i in
           List.for_all2
            (fun p (_,_,debruijnedte) -> 
-             let rl' = recursive_args ~subst c_ctx 0 len debruijnedte in
+             let rl'=recursive_args ~subst ~metasenv c_ctx 0 len debruijnedte in
              let e, k = get_new_safes ~subst k p rl' in
-             is_really_smaller ~subst k e)
+             is_really_smaller ~subst ~metasenv k e)
            pl cl
-    | _ -> List.for_all (is_really_smaller ~subst k) pl)
+    | _ -> List.for_all (is_really_smaller ~subst ~metasenv k) pl)
 
 and returns_a_coinductive ~subst context ty =
   match R.whd ~subst context ty with
@@ -1202,18 +1167,21 @@ and check_obj_well_typed (uri,height,metasenv,subst,kind) =
  assert (metasenv = [] && subst = []);
  match kind with
    | C.Constant (_,_,Some te,ty,_) ->
+(*
       prerr_endline ("TY: " ^ NCicPp.ppterm ~subst ~metasenv ~context:[] ty);
       prerr_endline ("BO: " ^ NCicPp.ppterm ~subst ~metasenv ~context:[] te);
+*)
       let _ = typeof ~subst ~metasenv [] ty in
       let ty_te = typeof ~subst ~metasenv [] te in
-      prerr_endline "XXXX";
+(*       prerr_endline "XXXX"; *)
       if not (R.are_convertible ~subst ~metasenv [] ty_te ty) then
        raise (TypeCheckerFailure (lazy (Printf.sprintf
         "the type of the body is not the one expected:\n%s\nvs\n%s"
         (NCicPp.ppterm ~subst ~metasenv ~context:[] ty_te) 
         (NCicPp.ppterm ~subst ~metasenv ~context:[] ty))))
    | C.Constant (_,_,None,ty,_) -> ignore (typeof ~subst ~metasenv [] ty)
-   | C.Inductive _ as obj -> check_mutual_inductive_defs obj
+   | C.Inductive (is_ind, leftno, tyl, _) -> 
+       check_mutual_inductive_defs uri ~metasenv ~subst is_ind leftno tyl
    | C.Fixpoint (inductive,fl,_) ->
       let types,kl,len =
         List.fold_left
@@ -1235,7 +1203,7 @@ and check_obj_well_typed (uri,height,metasenv,subst,kind) =
               function [] -> [] | v::tl -> (k,v)::enum_from (k+1) tl 
             in
             guarded_by_destructors 
-             ~subst ~metasenv context (enum_from (x+1) kl) m
+             ~subst ~metasenv context (enum_from (x+2) kl) m
           end else
            match returns_a_coinductive ~subst [] ty with
             | None ->