X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_kernel%2FnCicTypeChecker.ml;h=d9e6120d94d7cda03d172600d5699cc801cccbd1;hb=bf7f52019b3f65b6d635a8b49a63f0d95080f189;hp=c68982ff7dddea804aba27eeb53b8f478d62cfdf;hpb=341a777b344e7adb1e989dda3fdd643a3d9fb5f5;p=helm.git diff --git a/helm/software/components/ng_kernel/nCicTypeChecker.ml b/helm/software/components/ng_kernel/nCicTypeChecker.ml index c68982ff7..d9e6120d9 100644 --- a/helm/software/components/ng_kernel/nCicTypeChecker.ml +++ b/helm/software/components/ng_kernel/nCicTypeChecker.ml @@ -121,7 +121,7 @@ let debruijn uri number_of_types context = aux (List.length context) ;; -let sort_of_prod ~metasenv ~subst context (name,s) (t1, t2) = +let sort_of_prod ~metasenv ~subst context (name,s) t (t1, t2) = let t1 = R.whd ~subst context t1 in let t2 = R.whd ~subst ((name,C.Decl s)::context) t2 in match t1, t2 with @@ -131,11 +131,15 @@ let sort_of_prod ~metasenv ~subst context (name,s) (t1, t2) = | C.Meta (_,(_,(C.Irl 0 | C.Ctx []))), C.Sort _ | C.Meta (_,(_,(C.Irl 0 | C.Ctx []))), C.Meta (_,(_,(C.Irl 0 | C.Ctx []))) | C.Sort _, C.Meta (_,(_,(C.Irl 0 | C.Ctx []))) -> t2 - | _ -> + | x, (C.Sort _ | C.Meta (_,(_,(C.Irl 0 | C.Ctx [])))) + | _, x -> + let y, context = + if x == t1 then s, context else t, ((name,C.Decl s)::context) + in raise (TypeCheckerFailure (lazy (Printf.sprintf - "Prod: expected two sorts, found = %s, %s" - (PP.ppterm ~subst ~metasenv ~context t1) - (PP.ppterm ~subst ~metasenv ~context t2)))) + "%s is expected to be a type, but its type is %s that is not a sort" + (PP.ppterm ~subst ~metasenv ~context y) + (PP.ppterm ~subst ~metasenv ~context x)))) ;; (* instantiate_parameters ps (x1:T1)...(xn:Tn)C *) @@ -340,6 +344,26 @@ and are_all_occurrences_positive ~subst context uri indparamsno i n nn te = exception NotGuarded of string Lazy.t;; +let type_of_branch ~subst context leftno outty cons tycons = + let rec aux liftno context cons tycons = + match R.whd ~subst context tycons with + | C.Const (Ref.Ref (_,Ref.Ind _)) -> C.Appl [S.lift liftno outty ; cons] + | C.Appl (C.Const (Ref.Ref (_,Ref.Ind _))::tl) -> + let _,arguments = HExtlib.split_nth leftno tl in + C.Appl (S.lift liftno outty::arguments@[cons]) + | C.Prod (name,so,de) -> + let cons = + match S.lift 1 cons with + | C.Appl l -> C.Appl (l@[C.Rel 1]) + | t -> C.Appl [t ; C.Rel 1] + in + C.Prod (name,so, aux (liftno+1) ((name,(C.Decl so))::context) cons de) + | _ -> raise (AssertFailure (lazy "type_of_branch")) + in + aux 0 context cons tycons +;; + + let rec typeof ~subst ~metasenv context term = let rec typeof_aux context = fun t -> (*prerr_endline (PP.ppterm ~metasenv ~subst ~context t);*) @@ -361,7 +385,8 @@ let rec typeof ~subst ~metasenv context term = try let _,c,_,ty = U.lookup_subst n subst in c,ty with U.Subst_not_found _ -> try - let _,c,ty = U.lookup_meta n metasenv in c,ty + let _,c,ty = U.lookup_meta n metasenv in c, ty +(* match ty with C.Implicit _ -> assert false | _ -> c,ty *) with U.Meta_not_found _ -> raise (AssertFailure (lazy (Printf.sprintf "%s not found" (PP.ppterm ~subst ~metasenv ~context t)))) @@ -372,7 +397,7 @@ let rec typeof ~subst ~metasenv context term = | C.Prod (name,s,t) -> let sort1 = typeof_aux context s in let sort2 = typeof_aux ((name,(C.Decl s))::context) t in - sort_of_prod ~metasenv ~subst context (name,s) (sort1,sort2) + sort_of_prod ~metasenv ~subst context (name,s) t (sort1,sort2) | C.Lambda (n,s,t) -> let sort = typeof_aux context s in (match R.whd ~subst context sort with @@ -389,7 +414,7 @@ let rec typeof ~subst ~metasenv context term = | 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 get_relevance context ty_t ty) then + if not (R.are_convertible ~subst context ty_t ty) then raise (TypeCheckerFailure (lazy (Printf.sprintf @@ -458,9 +483,9 @@ let rec typeof ~subst ~metasenv context term = let ty_p = typeof_aux context p in let ty_cons = typeof_aux context cons in let ty_branch = - type_of_branch ~subst context leftno outtype cons ty_cons 0 + type_of_branch ~subst context leftno outtype cons ty_cons in - j+1, R.are_convertible ~subst get_relevance context ty_p ty_branch, + j+1, R.are_convertible ~subst context ty_p ty_branch, ty_p, ty_branch else j,false,old_p_ty,old_exp_p_ty @@ -480,23 +505,6 @@ let rec typeof ~subst ~metasenv context term = R.head_beta_reduce (C.Appl res) | C.Match _ -> assert false - and type_of_branch ~subst context leftno outty cons tycons liftno = - match R.whd ~subst context tycons with - | C.Const (Ref.Ref (_,Ref.Ind _)) -> C.Appl [S.lift liftno outty ; cons] - | C.Appl (C.Const (Ref.Ref (_,Ref.Ind _))::tl) -> - let _,arguments = HExtlib.split_nth leftno tl in - C.Appl (S.lift liftno outty::arguments@[cons]) - | C.Prod (name,so,de) -> - let cons = - match S.lift 1 cons with - | C.Appl l -> C.Appl (l@[C.Rel 1]) - | t -> C.Appl [t ; C.Rel 1] - in - C.Prod (name,so, - type_of_branch ~subst ((name,(C.Decl so))::context) - leftno outty cons de (liftno+1)) - | _ -> raise (AssertFailure (lazy "type_of_branch")) - (* check_metasenv_consistency checks that the "canonical" context of a metavariable is consitent - up to relocation via the relocation list l - with the actual context *) @@ -522,7 +530,7 @@ let rec typeof ~subst ~metasenv context term = (_,C.Decl t1), (_,C.Decl t2) | (_,C.Def (t1,_)), (_,C.Def (t2,_)) | (_,C.Def (_,t1)), (_,C.Decl t2) -> - if not (R.are_convertible ~subst get_relevance tl t1 t2) then + if not (R.are_convertible ~subst tl t1 t2) then raise (TypeCheckerFailure (lazy (Printf.sprintf @@ -573,7 +581,7 @@ let rec typeof ~subst ~metasenv context term = with Failure _ -> t) | _ -> t in - if not (R.are_convertible ~subst get_relevance context optimized_t ct) + if not (R.are_convertible ~subst context optimized_t ct) then raise (TypeCheckerFailure @@ -584,7 +592,7 @@ let rec typeof ~subst ~metasenv context term = (PP.ppterm ~subst ~metasenv ~context t)))) | t, (_,C.Decl ct) -> let type_t = typeof_aux context t in - if not (R.are_convertible ~subst get_relevance context type_t ct) then + if not (R.are_convertible ~subst context type_t ct) then raise (TypeCheckerFailure (lazy (Printf.sprintf ("Not well typed metavariable local context: "^^ @@ -599,67 +607,67 @@ let rec typeof ~subst ~metasenv context term = "Local and canonical context %s have different lengths" (PP.ppterm ~subst ~metasenv ~context term)))) - and check_allowed_sort_elimination ~subst ~metasenv r = - let mkapp he arg = - match he with - | C.Appl l -> C.Appl (l @ [arg]) - | t -> C.Appl [t;arg] in - let rec aux context ind arity1 arity2 = - let arity1 = R.whd ~subst context arity1 in - let arity2 = R.whd ~subst context arity2 in - match arity1,arity2 with - | C.Prod (name,so1,de1), C.Prod (_,so2,de2) -> - if not (R.are_convertible ~subst get_relevance context so1 so2) then - raise (TypeCheckerFailure (lazy (Printf.sprintf - "In outtype: expected %s, found %s" - (PP.ppterm ~subst ~metasenv ~context so1) - (PP.ppterm ~subst ~metasenv ~context so2) - ))); - aux ((name, C.Decl so1)::context) - (mkapp (S.lift 1 ind) (C.Rel 1)) de1 de2 - | C.Sort _, C.Prod (name,so,ta) -> - if not (R.are_convertible ~subst get_relevance context so ind) then - raise (TypeCheckerFailure (lazy (Printf.sprintf - "In outtype: expected %s, found %s" - (PP.ppterm ~subst ~metasenv ~context ind) - (PP.ppterm ~subst ~metasenv ~context so) - ))); - (match arity1, R.whd ~subst ((name,C.Decl so)::context) ta with - | (C.Sort C.Type _, C.Sort _) - | (C.Sort C.Prop, C.Sort C.Prop) -> () - | (C.Sort C.Prop, C.Sort C.Type _) -> - (* TODO: we should pass all these parameters since we - * have them already *) - let _,leftno,itl,_,i = E.get_checked_indtys r in - let itl_len = List.length itl in - let _,itname,ittype,cl = List.nth itl i in - let cl_len = List.length cl in - (* is it a singleton, non recursive and non informative - definition or an empty one? *) - if not - (cl_len = 0 || - (itl_len = 1 && cl_len = 1 && - let _,_,constrty = List.hd cl in - is_non_recursive_singleton r itname ittype constrty && - is_non_informative leftno constrty)) - then - raise (TypeCheckerFailure (lazy - ("Sort elimination not allowed"))); - | _,_ -> ()) - | _,_ -> () - in - aux - in typeof_aux context term +and check_allowed_sort_elimination ~subst ~metasenv r = + let mkapp he arg = + match he with + | C.Appl l -> C.Appl (l @ [arg]) + | t -> C.Appl [t;arg] in + let rec aux context ind arity1 arity2 = + let arity1 = R.whd ~subst context arity1 in + let arity2 = R.whd ~subst context arity2 in + match arity1,arity2 with + | C.Prod (name,so1,de1), C.Prod (_,so2,de2) -> + if not (R.are_convertible ~subst context so1 so2) then + raise (TypeCheckerFailure (lazy (Printf.sprintf + "In outtype: expected %s, found %s" + (PP.ppterm ~subst ~metasenv ~context so1) + (PP.ppterm ~subst ~metasenv ~context so2) + ))); + aux ((name, C.Decl so1)::context) + (mkapp (S.lift 1 ind) (C.Rel 1)) de1 de2 + | C.Sort _, C.Prod (name,so,ta) -> + if not (R.are_convertible ~subst context so ind) then + raise (TypeCheckerFailure (lazy (Printf.sprintf + "In outtype: expected %s, found %s" + (PP.ppterm ~subst ~metasenv ~context ind) + (PP.ppterm ~subst ~metasenv ~context so) + ))); + (match arity1, R.whd ~subst ((name,C.Decl so)::context) ta with + | (C.Sort C.Type _, C.Sort _) + | (C.Sort C.Prop, C.Sort C.Prop) -> () + | (C.Sort C.Prop, C.Sort C.Type _) -> + (* TODO: we should pass all these parameters since we + * have them already *) + let _,leftno,itl,_,i = E.get_checked_indtys r in + let itl_len = List.length itl in + let _,itname,ittype,cl = List.nth itl i in + let cl_len = List.length cl in + (* is it a singleton, non recursive and non informative + definition or an empty one? *) + if not + (cl_len = 0 || + (itl_len = 1 && cl_len = 1 && + let _,_,constrty = List.hd cl in + is_non_recursive_singleton r itname ittype constrty && + is_non_informative leftno constrty)) + then + raise (TypeCheckerFailure (lazy + ("Sort elimination not allowed"))); + | _,_ -> ()) + | _,_ -> () + in + aux + and eat_prods ~subst ~metasenv context he ty_he args_with_ty = let rec aux ty_he = function | [] -> ty_he | (arg, ty_arg)::tl -> match R.whd ~subst context ty_he with | C.Prod (_,s,t) -> - if R.are_convertible ~subst get_relevance context ty_arg s then + if R.are_convertible ~subst context ty_arg s then aux (S.subst ~avoid_beta_redexes:true arg t) tl else raise @@ -689,7 +697,16 @@ and eat_prods ~subst ~metasenv context he ty_he args_with_ty = and is_non_recursive_singleton (Ref.Ref (uri,_)) iname ity cty = let ctx = [iname, C.Decl ity] in let cty = debruijn uri 1 [] cty in - does_not_occur ~subst:[] ctx 0 1 cty + let len = List.length ctx in + let rec aux ctx n nn t = + match R.whd ctx t with + | C.Prod (name, src, tgt) -> + does_not_occur ~subst:[] ctx n nn src && + aux ((name, C.Decl src) :: ctx) (n+1) (nn+1) tgt + | C.Rel k | C.Appl (C.Rel k :: _) when k = nn -> true + | _ -> assert false + in + aux ctx (len-1) len cty and is_non_informative paramsno c = let rec aux context c = @@ -727,11 +744,11 @@ and check_mutual_inductive_defs uri ~metasenv ~subst leftno tyl = let convertible = match item1,item2 with (n1,C.Decl ty1),(n2,C.Decl ty2) -> - n1 = n2 && R.are_convertible ~subst get_relevance context ty1 ty2 + n1 = n2 && R.are_convertible ~subst context ty1 ty2 | (n1,C.Def (bo1,ty1)),(n2,C.Def (bo2,ty2)) -> n1 = n2 - && R.are_convertible ~subst get_relevance context ty1 ty2 - && R.are_convertible ~subst get_relevance context bo1 bo2 + && R.are_convertible ~subst context ty1 ty2 + && R.are_convertible ~subst context bo1 bo2 | _,_ -> false in if not convertible then @@ -1111,7 +1128,7 @@ let typecheck_context ~metasenv ~subst context = | name,C.Def (te,ty) -> ignore (typeof ~metasenv ~subst:[] context ty); let ty' = typeof ~metasenv ~subst:[] context te in - if not (R.are_convertible ~subst get_relevance context ty' ty) then + if not (R.are_convertible ~subst context ty' ty) then raise (AssertFailure (lazy (Printf.sprintf ( "the type of the definiens for %s in the context is not "^^ "convertible with the declared one.\n"^^ @@ -1149,7 +1166,7 @@ let typecheck_subst ~metasenv subst = typecheck_context ~metasenv ~subst context; ignore (typeof ~metasenv ~subst context ty); let ty' = typeof ~metasenv ~subst context bo in - if not (R.are_convertible ~subst get_relevance context ty' ty) then + if not (R.are_convertible ~subst context ty' ty) then raise (AssertFailure (lazy (Printf.sprintf ( "the type of the definiens for %d in the substitution is not "^^ "convertible with the declared one.\n"^^ @@ -1170,7 +1187,7 @@ let typecheck_obj (uri,_height,metasenv,subst,kind) = | C.Constant (relevance,_,Some te,ty,_) -> let _ = typeof ~subst ~metasenv [] ty in let ty_te = typeof ~subst ~metasenv [] te in - if not (R.are_convertible ~subst get_relevance [] ty_te ty) then + if not (R.are_convertible ~subst [] ty_te ty) then raise (TypeCheckerFailure (lazy (Printf.sprintf ( "the type of the body is not convertible with the declared one.\n"^^ "inferred type:\n%s\nexpected type:\n%s") @@ -1202,7 +1219,7 @@ let typecheck_obj (uri,_height,metasenv,subst,kind) = in List.iter2 (fun (_,_,x,ty,_) bo -> let ty_bo = typeof ~subst ~metasenv types bo in - if not (R.are_convertible ~subst get_relevance types ty_bo ty) + if not (R.are_convertible ~subst types ty_bo ty) then raise (TypeCheckerFailure (lazy ("(Co)Fix: ill-typed bodies"))) else if inductive then begin @@ -1278,4 +1295,6 @@ E.set_typecheck_obj typecheck_obj obj) ;; +let _ = NCicReduction.set_get_relevance get_relevance;; + (* EOF *)