X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Fng_kernel%2FnCicTypeChecker.ml;h=81f633bb6c850362623c0b617ff3ccc41e86b52f;hb=3ec1830d5251709ed6c4899c74903498a6cd2744;hp=1760c57e418ce3f9ecf6820021ce0a797caf520c;hpb=0fae7e0c93edd15c8e7f9f8330721f94388100ad;p=helm.git diff --git a/helm/software/components/ng_kernel/nCicTypeChecker.ml b/helm/software/components/ng_kernel/nCicTypeChecker.ml index 1760c57e4..81f633bb6 100644 --- a/helm/software/components/ng_kernel/nCicTypeChecker.ml +++ b/helm/software/components/ng_kernel/nCicTypeChecker.ml @@ -11,6 +11,14 @@ (* $Id: nCicReduction.ml 8250 2008-03-25 17:56:20Z tassi $ *) +(* web interface stuff *) + +let logger = + ref (function (`Start_type_checking _|`Type_checking_completed _) -> ()) +;; + +let set_logger f = logger := f;; + exception TypeCheckerFailure of string Lazy.t exception AssertFailure of string Lazy.t @@ -517,67 +525,6 @@ and guarded_by_constructors ~subst context n nn h te args coInductiveTypeURI = args coInductiveTypeURI ) fl true -and type_of_branch ~subst context argsno need_dummy outtype term constype = - let module C = Cic in - let module R = CicReduction in - match R.whd ~subst context constype with - C.MutInd (_,_,_) -> - if need_dummy then - outtype - else - C.Appl [outtype ; term] - | C.Appl (C.MutInd (_,_,_)::tl) -> - let (_,arguments) = split tl argsno - in - if need_dummy && arguments = [] then - outtype - else - C.Appl (outtype::arguments@(if need_dummy then [] else [term])) - | C.Prod (name,so,de) -> - let term' = - match CicSubstitution.lift 1 term 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 - ((Some (name,(C.Decl so)))::context) argsno need_dummy - (CicSubstitution.lift 1 outtype) term' de) - | _ -> raise (AssertFailure (lazy "20")) - - and returns_a_coinductive ~subst context ty = - let module C = Cic in - match CicReduction.whd ~subst context ty with - C.MutInd (uri,i,_) -> - (*CSC: definire una funzioncina per questo codice sempre replicato *) - let obj,_ = - try - CicEnvironment.get_cooked_obj ~trust:false CicUniv.empty_ugraph uri - with Not_found -> assert false - in - (match obj with - C.InductiveDefinition (itl,_,_,_) -> - let (_,is_inductive,_,_) = List.nth itl i in - if is_inductive then None else (Some uri) - | _ -> - raise (TypeCheckerFailure - (lazy ("Unknown mutual inductive definition:" ^ - UriManager.string_of_uri uri))) - ) - | C.Appl ((C.MutInd (uri,i,_))::_) -> - (let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in - match o with - C.InductiveDefinition (itl,_,_,_) -> - let (_,is_inductive,_,_) = List.nth itl i in - if is_inductive then None else (Some uri) - | _ -> - raise (TypeCheckerFailure - (lazy ("Unknown mutual inductive definition:" ^ - UriManager.string_of_uri uri))) - ) - | C.Prod (n,so,de) -> - returns_a_coinductive ~subst ((Some (n,C.Decl so))::context) de - | _ -> None - in type_of_aux ~logger context t ugraph @@ -818,9 +765,9 @@ let rec typeof ~subst ~metasenv context term = in if List.length pl <> constructorsno then raise (TypeCheckerFailure (lazy ("Wrong number of cases in a match"))); - let j,branches_ok = + let j,branches_ok,p_ty, exp_p_ty = List.fold_left - (fun (j,b) p -> + (fun (j,b,old_p_ty,old_exp_p_ty) p -> if b then let cons = let cons = Ref.Ref (dummy_depth, uri, Ref.Con (tyno, j)) in @@ -830,23 +777,42 @@ 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 in - j+1, R.are_convertible ~subst ~metasenv context ty_p ty_branch + type_of_branch ~subst context leftno outtype cons ty_cons 0 + in + j+1, R.are_convertible ~subst ~metasenv context ty_p ty_branch, + ty_p, ty_branch else - j,false - ) (1,true) pl - in - if not branches_ok then - raise - (TypeCheckerFailure - (lazy (Printf.sprintf "Branch for constructor %s has wrong type" - (NCicPp.ppterm (C.Const - (Ref.Ref (dummy_depth, uri, Ref.Con (tyno, j)))))))); - let res = outtype::arguments@[term] in - R.head_beta_reduce (C.Appl res) + j,false,old_p_ty,old_exp_p_ty + ) (1,true,C.Sort C.Prop,C.Sort C.Prop) pl + in + if not branches_ok then + raise + (TypeCheckerFailure + (lazy (Printf.sprintf ("Branch for constructor %s :=\n%s\n"^^ + "has type %s\nnot convertible with %s") (NCicPp.ppterm (C.Const + (Ref.Ref (dummy_depth, uri, Ref.Con (tyno, j))))) + (NCicPp.ppterm ~context (List.nth pl (j-1))) + (NCicPp.ppterm ~context p_ty) (NCicPp.ppterm ~context exp_p_ty)))); + let res = outtype::arguments@[term] in + R.head_beta_reduce (C.Appl res) | C.Match _ -> assert false - and type_of_branch ~subst context leftno outty cons tycons = 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 - @@ -933,10 +899,10 @@ let rec typeof ~subst ~metasenv context term = let type_t = typeof_aux context t in if not (R.are_convertible ~subst ~metasenv context type_t ct) then raise (TypeCheckerFailure - (lazy (Printf.sprintf - ("Not well typed metavariable local context: "^^ - "expected a term of type %s, found %s of type %s") - (NCicPp.ppterm ct) (NCicPp.ppterm t) (NCicPp.ppterm type_t)))) + (lazy (Printf.sprintf + ("Not well typed metavariable local context: "^^ + "expected a term of type %s, found %s of type %s") + (NCicPp.ppterm ct) (NCicPp.ppterm t) (NCicPp.ppterm type_t)))) ) l lifted_canonical_context with Invalid_argument _ -> @@ -991,7 +957,7 @@ let rec typeof ~subst ~metasenv context term = in typeof_aux context term -and check_mutual_inductive_defs _ = assert false +and check_mutual_inductive_defs _ = () and eat_lambdas ~subst context n te = match (n, R.whd ~subst context te) with @@ -1107,7 +1073,6 @@ and split_prods ~subst context n te = split_prods ~subst ((name,(C.Decl so))::context) (n - 1) ta | _ -> raise (AssertFailure (lazy "split_prods")) -(*CSC: Tutto quello che segue e' l'intuzione di luca ;-) *) and is_really_smaller ~subst (context, recfuns, x, safes as k) te = match R.whd ~subst context te with | C.Rel m when List.mem m safes -> true @@ -1120,6 +1085,7 @@ and is_really_smaller ~subst (context, recfuns, x, safes as k) te = | C.Appl (he::_) -> (*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 | C.Const (Ref.Ref (_,_,Ref.Con _)) -> false | C.Const (Ref.Ref (_,_,Ref.Fix _)) -> assert false @@ -1160,58 +1126,43 @@ and is_really_smaller ~subst (context, recfuns, x, safes as k) te = pl cl | _ -> List.for_all (is_really_smaller ~subst k) pl) -and returns_a_coinductive ~subst _ _ = assert false +and returns_a_coinductive ~subst context ty = + match R.whd ~subst context ty with + | C.Const (Ref.Ref (_,uri,Ref.Ind _) as ref) + | C.Appl (C.Const (Ref.Ref (_,uri,Ref.Ind _) as ref)::_) -> + let isinductive, _, _, _, _ = E.get_checked_indtys ref in + if isinductive then None else (Some uri) + | C.Prod (n,so,de) -> + returns_a_coinductive ~subst ((n,C.Decl so)::context) de + | _ -> None -and type_of_constant ref = assert false (* USARE typecheck_obj0 *) -(* ALIAS typecheck *) -(* - let cobj,ugraph1 = - match CicEnvironment.is_type_checked ~trust:true ugraph uri with - CicEnvironment.CheckedObj (cobj,ugraph') -> cobj,ugraph' - | CicEnvironment.UncheckedObj uobj -> - logger#log (`Start_type_checking uri) ; - let ugraph1_dust = - typecheck_obj0 ~logger uri CicUniv.empty_ugraph uobj in - try - CicEnvironment.set_type_checking_info uri ; - logger#log (`Type_checking_completed uri) ; - (match CicEnvironment.is_type_checked ~trust:false ugraph uri with - CicEnvironment.CheckedObj (cobj,ugraph') -> (cobj,ugraph') - | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError - ) - with - (* - this is raised if set_type_checking_info is called on an object - that has no associated universe file. If we are in univ_maker - phase this is OK since univ_maker will properly commit the - object. - *) - Invalid_argument s -> - (*debug_print (lazy s);*) - uobj,ugraph1_dust +and type_of_constant ((Ref.Ref (_,uri,_)) as ref) = + let cobj = + match E.get_obj uri with + | true, cobj -> cobj + | false, uobj -> + !logger (`Start_type_checking uri); + check_obj_well_typed uobj; + E.add_obj uobj; + !logger (`Type_checking_completed uri); + if not (fst (E.get_obj uri)) then + raise (AssertFailure (lazy "environment error")); + uobj in -CASO COSTRUTTORE - match cobj with - C.InductiveDefinition (dl,_,_,_) -> - let (_,_,arity,_) = List.nth dl i in - arity,ugraph1 - | _ -> - raise (TypeCheckerFailure - (lazy ("Unknown mutual inductive definition:" ^ U.string_of_uri uri))) -CASO TIPO INDUTTIVO - match cobj with - C.InductiveDefinition (dl,_,_,_) -> - let (_,_,_,cl) = List.nth dl i in - let (_,ty) = List.nth cl (j-1) in - ty,ugraph1 - | _ -> - raise (TypeCheckerFailure - (lazy ("Unknown mutual inductive definition:" ^ UriManager.string_of_uri uri))) -CASO COSTANTE -CASO FIX/COFIX -*) + match cobj, ref with + | (_,_,_,_,C.Inductive (_,_,tl,_)), Ref.Ref (_,_,Ref.Ind i) -> + let _,_,arity,_ = List.nth tl i in arity + | (_,_,_,_,C.Inductive (_,_,tl,_)), Ref.Ref (_,_,Ref.Con (i,j)) -> + let _,_,_,cl = List.nth tl i in + let _,_,arity = List.nth cl (j-1) in + arity + | (_,_,_,_,C.Fixpoint (_,fl,_)), Ref.Ref (_,_,(Ref.Fix (i,_)|Ref.CoFix i)) -> + let _,_,_,arity,_ = List.nth fl i in + arity + | (_,_,_,_,C.Constant (_,_,_,ty,_)), Ref.Ref (_,_,(Ref.Def |Ref.Decl)) -> ty + | _ -> raise (AssertFailure (lazy "type_of_constant: environment/reference")) -and typecheck_obj0 (uri,height,metasenv,subst,kind) = +and check_obj_well_typed (uri,height,metasenv,subst,kind) = (* CSC: here we should typecheck the metasenv and the subst *) assert (metasenv = [] && subst = []); match kind with @@ -1223,7 +1174,7 @@ and typecheck_obj0 (uri,height,metasenv,subst,kind) = "the type of the body is not the one expected:\n%s\nvs\n%s" (NCicPp.ppterm ty_te) (NCicPp.ppterm ty)))) | C.Constant (_,_,None,ty,_) -> ignore (typeof ~subst ~metasenv [] ty) - | C.Inductive _ as obj -> check_mutual_inductive_defs uri obj + | C.Inductive _ as obj -> check_mutual_inductive_defs obj | C.Fixpoint (inductive,fl,_) -> let types,kl,len = List.fold_left @@ -1233,6 +1184,7 @@ and typecheck_obj0 (uri,height,metasenv,subst,kind) = ) ([],[],0) fl in List.iter (fun (_,name,x,ty,bo) -> + let bo = debruijn uri len bo in let ty_bo = typeof ~subst ~metasenv types bo in if not (R.are_convertible ~subst ~metasenv types ty_bo (S.lift len ty)) then raise (TypeCheckerFailure (lazy ("(Co)Fix: ill-typed bodies"))) @@ -1260,9 +1212,6 @@ and typecheck_obj0 (uri,height,metasenv,subst,kind) = (lazy "CoFix: not guarded by constructors")) ) fl -let typecheck_obj (*uri*) obj = assert false (* - let ugraph = typecheck_obj0 ~logger uri CicUniv.empty_ugraph obj in - let ugraph, univlist, obj = CicUnivUtils.clean_and_fill uri obj ugraph in - CicEnvironment.add_type_checked_obj uri (obj,ugraph,univlist) -*) -;; +let typecheck_obj = check_obj_well_typed;; + +(* EOF *)