(* $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
args coInductiveTypeURI
) fl true
- 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
| (arg, ty_arg)::tl ->
(match R.whd ~subst context ty_he with
| C.Prod (n,s,t) ->
+(*
+ prerr_endline (NCicPp.ppterm ~context s ^ " - Vs - " ^ NCicPp.ppterm
+ ~context ty_arg);
+ prerr_endline (NCicPp.ppterm ~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
else
exception NotGuarded;;
let rec typeof ~subst ~metasenv context term =
- let rec typeof_aux context = function
+ let rec typeof_aux context =
+ fun t -> (*prerr_endline (NCicPp.ppterm ~context t); *)
+ match t with
| C.Rel n ->
(try
match List.nth context (n - 1) with
| C.Appl (he::(_::_ as args)) ->
let ty_he = typeof_aux context he in
let args_with_ty = List.map (fun t -> t, typeof_aux context t) args in
+(*
+ prerr_endline ("HEAD: " ^ NCicPp.ppterm ~context ty_he);
+ prerr_endline ("TARGS: " ^ String.concat " | " (List.map (NCicPp.ppterm
+ ~context) (List.map snd args_with_ty)));
+ prerr_endline ("ARGS: " ^ String.concat " | " (List.map (NCicPp.ppterm
+ ~context) (List.map fst args_with_ty)));
+*)
eat_prods ~subst ~metasenv context ty_he args_with_ty
| C.Appl _ -> raise (AssertFailure (lazy "Appl of length < 2"))
| C.Match (Ref.Ref (dummy_depth,uri,Ref.Ind tyno) as r,outtype,term,pl) ->
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
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 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 liftno =
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 _ ->
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
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
| C.Constant (_,_,Some te,ty,_) ->
+ prerr_endline ("TY: " ^ NCicPp.ppterm ty);
+ prerr_endline ("BO: " ^ NCicPp.ppterm te);
let _ = typeof ~subst ~metasenv [] ty in
let ty_te = typeof ~subst ~metasenv [] te in
+ 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 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
) ([],[],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")))
(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 *)