1 (* Copyright (C) 2000, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
26 type type_checker_exn =
28 | NotWellTyped of string
29 | WrongUriToConstant of string
30 | WrongUriToVariable of string
31 | WrongUriToMutualInductiveDefinitions of string
33 | NotPositiveOccurrences of string
34 | NotWellFormedTypeOfInductiveConstructor of string
35 | WrongRequiredArgument of string
36 | RelToHiddenHypothesis
37 | MetasenvInconsistency;;
39 (* This is the only exception that will be raised *)
40 exception TypeCheckerFailure of type_checker_exn;;
44 let rec debug_aux t i =
46 let module U = UriManager in
47 CicPp.ppobj (C.Variable ("DEBUG", None, t, [])) ^ "\n" ^ i
52 (NotWellTyped ("\n" ^ List.fold_right debug_aux (t::context) "")))
53 (*print_endline ("\n" ^ List.fold_right debug_aux (t::context) "") ; flush stdout*)
59 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
60 | (_,_) -> raise (TypeCheckerFailure ListTooShort)
63 let debrujin_constructor uri number_of_types =
67 C.Rel n as t when n <= k -> t
69 raise (TypeCheckerFailure (NotWellTyped ("Debrujin: open term found")))
70 | C.Var (uri,exp_named_subst) ->
71 let exp_named_subst' =
72 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
74 C.Var (uri,exp_named_subst')
75 | C.Meta _ -> assert false
77 | C.Implicit as t -> t
78 | C.Cast (te,ty) -> C.Cast (aux k te, aux k ty)
79 | C.Prod (n,s,t) -> C.Prod (n, aux k s, aux (k+1) t)
80 | C.Lambda (n,s,t) -> C.Lambda (n, aux k s, aux (k+1) t)
81 | C.LetIn (n,s,t) -> C.LetIn (n, aux k s, aux (k+1) t)
82 | C.Appl l -> C.Appl (List.map (aux k) l)
83 | C.Const (uri,exp_named_subst) ->
84 let exp_named_subst' =
85 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
87 C.Const (uri,exp_named_subst')
88 | C.MutInd (uri',tyno,exp_named_subst) when UriManager.eq uri uri' ->
89 if exp_named_subst != [] then
93 ("Debrujin: a non-empty explicit named substitution is applied to "^
94 "a mutual inductive type which is being defined"))) ;
95 C.Rel (k + number_of_types - tyno) ;
96 | C.MutInd (uri',tyno,exp_named_subst) ->
97 let exp_named_subst' =
98 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
100 C.MutInd (uri',tyno,exp_named_subst')
101 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
102 let exp_named_subst' =
103 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
105 C.MutConstruct (uri,tyno,consno,exp_named_subst')
106 | C.MutCase (sp,i,outty,t,pl) ->
107 C.MutCase (sp, i, aux k outty, aux k t,
110 let len = List.length fl in
113 (fun (name, i, ty, bo) -> (name, i, aux k ty, aux (k+len) bo))
118 let len = List.length fl in
121 (fun (name, ty, bo) -> (name, aux k ty, aux (k+len) bo))
124 C.CoFix (i, liftedfl)
129 exception CicEnvironmentError;;
131 let rec type_of_constant uri =
132 let module C = Cic in
133 let module R = CicReduction in
134 let module U = UriManager in
136 match CicEnvironment.is_type_checked ~trust:true uri with
137 CicEnvironment.CheckedObj cobj -> cobj
138 | CicEnvironment.UncheckedObj uobj ->
139 Logger.log (`Start_type_checking uri) ;
140 (* let's typecheck the uncooked obj *)
142 C.Constant (_,Some te,ty,_) ->
143 let _ = type_of ty in
144 if not (R.are_convertible [] (type_of te) ty) then
147 (NotWellTyped ("Constant " ^ (U.string_of_uri uri))))
148 | C.Constant (_,None,ty,_) ->
149 (* only to check that ty is well-typed *)
150 let _ = type_of ty in ()
151 | C.CurrentProof (_,conjs,te,ty,_) ->
154 (fun metasenv ((_,context,ty) as conj) ->
155 ignore (type_of_aux' metasenv context ty) ;
159 let _ = type_of_aux' conjs [] ty in
160 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
164 (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri))))
166 raise (TypeCheckerFailure (WrongUriToConstant (U.string_of_uri uri)))
168 CicEnvironment.set_type_checking_info uri ;
169 Logger.log (`Type_checking_completed uri) ;
170 match CicEnvironment.is_type_checked ~trust:false uri with
171 CicEnvironment.CheckedObj cobj -> cobj
172 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
175 C.Constant (_,_,ty,_) -> ty
176 | C.CurrentProof (_,_,_,ty,_) -> ty
177 | _ -> raise (TypeCheckerFailure (WrongUriToConstant (U.string_of_uri uri)))
179 and type_of_variable uri =
180 let module C = Cic in
181 let module R = CicReduction in
182 let module U = UriManager in
183 (* 0 because a variable is never cooked => no partial cooking at one level *)
184 match CicEnvironment.is_type_checked ~trust:true uri with
185 CicEnvironment.CheckedObj (C.Variable (_,_,ty,_)) -> ty
186 | CicEnvironment.UncheckedObj (C.Variable (_,bo,ty,_)) ->
187 Logger.log (`Start_type_checking uri) ;
188 (* only to check that ty is well-typed *)
189 let _ = type_of ty in
193 if not (R.are_convertible [] (type_of bo) ty) then
196 (NotWellTyped ("Variable " ^ (U.string_of_uri uri))))
198 CicEnvironment.set_type_checking_info uri ;
199 Logger.log (`Type_checking_completed uri) ;
203 (TypeCheckerFailure (WrongUriToVariable (UriManager.string_of_uri uri)))
205 and does_not_occur context n nn te =
206 let module C = Cic in
207 (*CSC: whd sembra essere superflua perche' un caso in cui l'occorrenza *)
208 (*CSC: venga mangiata durante la whd sembra presentare problemi di *)
210 match CicReduction.whd context te with
211 C.Rel m when m > n && m <= nn -> false
217 does_not_occur context n nn te && does_not_occur context n nn ty
218 | C.Prod (name,so,dest) ->
219 does_not_occur context n nn so &&
220 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1)
222 | C.Lambda (name,so,dest) ->
223 does_not_occur context n nn so &&
224 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1)
226 | C.LetIn (name,so,dest) ->
227 does_not_occur context n nn so &&
228 does_not_occur ((Some (name,(C.Def (so,None))))::context)
229 (n + 1) (nn + 1) dest
231 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
232 | C.Var (_,exp_named_subst)
233 | C.Const (_,exp_named_subst)
234 | C.MutInd (_,_,exp_named_subst)
235 | C.MutConstruct (_,_,_,exp_named_subst) ->
236 List.fold_right (fun (_,x) i -> i && does_not_occur context n nn x)
238 | C.MutCase (_,_,out,te,pl) ->
239 does_not_occur context n nn out && does_not_occur context n nn te &&
240 List.fold_right (fun x i -> i && does_not_occur context n nn x) pl true
242 let len = List.length fl in
243 let n_plus_len = n + len in
244 let nn_plus_len = nn + len in
246 List.map (fun (n,_,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
249 (fun (_,_,ty,bo) i ->
250 i && does_not_occur context n nn ty &&
251 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
254 let len = List.length fl in
255 let n_plus_len = n + len in
256 let nn_plus_len = nn + len in
258 List.map (fun (n,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
262 i && does_not_occur context n nn ty &&
263 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
266 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
267 (*CSC questa funzione e' simile alla are_all_occurrences_positive, ma fa *)
268 (*CSC dei controlli leggermente diversi. Viene invocata solamente dalla *)
269 (*CSC strictly_positive *)
270 (*CSC definizione (giusta???) tratta dalla mail di Hugo ;-) *)
271 and weakly_positive context n nn uri te =
272 let module C = Cic in
273 (*CSC: Che schifo! Bisogna capire meglio e trovare una soluzione ragionevole!*)
275 C.MutInd (UriManager.uri_of_string "cic:/Coq/Init/Datatypes/nat.ind",0,[])
277 (*CSC mettere in cicSubstitution *)
278 let rec subst_inductive_type_with_dummy_mutind =
280 C.MutInd (uri',0,_) when UriManager.eq uri' uri ->
282 | C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri ->
284 | C.Cast (te,ty) -> subst_inductive_type_with_dummy_mutind te
285 | C.Prod (name,so,ta) ->
286 C.Prod (name, subst_inductive_type_with_dummy_mutind so,
287 subst_inductive_type_with_dummy_mutind ta)
288 | C.Lambda (name,so,ta) ->
289 C.Lambda (name, subst_inductive_type_with_dummy_mutind so,
290 subst_inductive_type_with_dummy_mutind ta)
292 C.Appl (List.map subst_inductive_type_with_dummy_mutind tl)
293 | C.MutCase (uri,i,outtype,term,pl) ->
295 subst_inductive_type_with_dummy_mutind outtype,
296 subst_inductive_type_with_dummy_mutind term,
297 List.map subst_inductive_type_with_dummy_mutind pl)
299 C.Fix (i,List.map (fun (name,i,ty,bo) -> (name,i,
300 subst_inductive_type_with_dummy_mutind ty,
301 subst_inductive_type_with_dummy_mutind bo)) fl)
303 C.CoFix (i,List.map (fun (name,ty,bo) -> (name,
304 subst_inductive_type_with_dummy_mutind ty,
305 subst_inductive_type_with_dummy_mutind bo)) fl)
306 | C.Const (uri,exp_named_subst) ->
307 let exp_named_subst' =
309 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
312 C.Const (uri,exp_named_subst')
313 | C.MutInd (uri,typeno,exp_named_subst) ->
314 let exp_named_subst' =
316 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
319 C.MutInd (uri,typeno,exp_named_subst')
320 | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
321 let exp_named_subst' =
323 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
326 C.MutConstruct (uri,typeno,consno,exp_named_subst')
329 match CicReduction.whd context te with
330 C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri -> true
331 | C.MutInd (uri',0,_) when UriManager.eq uri' uri -> true
332 | C.Prod (C.Anonymous,source,dest) ->
333 strictly_positive context n nn
334 (subst_inductive_type_with_dummy_mutind source) &&
335 weakly_positive ((Some (C.Anonymous,(C.Decl source)))::context)
336 (n + 1) (nn + 1) uri dest
337 | C.Prod (name,source,dest) when
338 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
339 (* dummy abstraction, so we behave as in the anonimous case *)
340 strictly_positive context n nn
341 (subst_inductive_type_with_dummy_mutind source) &&
342 weakly_positive ((Some (name,(C.Decl source)))::context)
343 (n + 1) (nn + 1) uri dest
344 | C.Prod (name,source,dest) ->
345 does_not_occur context n nn
346 (subst_inductive_type_with_dummy_mutind source)&&
347 weakly_positive ((Some (name,(C.Decl source)))::context)
348 (n + 1) (nn + 1) uri dest
352 (NotWellFormedTypeOfInductiveConstructor
353 ("Guess where the error is ;-)")))
355 (* instantiate_parameters ps (x1:T1)...(xn:Tn)C *)
356 (* returns ((x_|ps|:T_|ps|)...(xn:Tn)C){ps_1 / x1 ; ... ; ps_|ps| / x_|ps|} *)
357 and instantiate_parameters params c =
358 let module C = Cic in
359 match (c,params) with
361 | (C.Prod (_,_,ta), he::tl) ->
362 instantiate_parameters tl
363 (CicSubstitution.subst he ta)
364 | (C.Cast (te,_), _) -> instantiate_parameters params te
365 | (t,l) -> raise (TypeCheckerFailure (Impossible 1))
367 and strictly_positive context n nn te =
368 let module C = Cic in
369 let module U = UriManager in
370 match CicReduction.whd context te with
373 (*CSC: bisogna controllare ty????*)
374 strictly_positive context n nn te
375 | C.Prod (name,so,ta) ->
376 does_not_occur context n nn so &&
377 strictly_positive ((Some (name,(C.Decl so)))::context) (n+1) (nn+1) ta
378 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
379 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
380 | C.Appl ((C.MutInd (uri,i,exp_named_subst))::tl) ->
381 let (ok,paramsno,ity,cl,name) =
382 match CicEnvironment.get_obj uri with
383 C.InductiveDefinition (tl,_,paramsno) ->
384 let (name,_,ity,cl) = List.nth tl i in
385 (List.length tl = 1, paramsno, ity, cl, name)
389 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
391 let (params,arguments) = split tl paramsno in
392 let lifted_params = List.map (CicSubstitution.lift 1) params in
396 instantiate_parameters lifted_params
397 (CicSubstitution.subst_vars exp_named_subst te)
402 (fun x i -> i && does_not_occur context n nn x)
404 (*CSC: MEGAPATCH3 (sara' quella giusta?)*)
409 ((Some (C.Name name,(Cic.Decl ity)))::context) (n+1) (nn+1) uri
412 | t -> does_not_occur context n nn t
414 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
415 and are_all_occurrences_positive context uri indparamsno i n nn te =
416 let module C = Cic in
417 match CicReduction.whd context te with
418 C.Appl ((C.Rel m)::tl) when m = i ->
419 (*CSC: riscrivere fermandosi a 0 *)
420 (* let's check if the inductive type is applied at least to *)
421 (* indparamsno parameters *)
427 match CicReduction.whd context x with
428 C.Rel m when m = n - (indparamsno - k) -> k - 1
432 (WrongRequiredArgument (UriManager.string_of_uri uri)))
436 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
440 (WrongRequiredArgument (UriManager.string_of_uri uri)))
441 | C.Rel m when m = i ->
442 if indparamsno = 0 then
447 (WrongRequiredArgument (UriManager.string_of_uri uri)))
448 | C.Prod (C.Anonymous,source,dest) ->
449 strictly_positive context n nn source &&
450 are_all_occurrences_positive
451 ((Some (C.Anonymous,(C.Decl source)))::context) uri indparamsno
452 (i+1) (n + 1) (nn + 1) dest
453 | C.Prod (name,source,dest) when
454 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
455 (* dummy abstraction, so we behave as in the anonimous case *)
456 strictly_positive context n nn source &&
457 are_all_occurrences_positive
458 ((Some (name,(C.Decl source)))::context) uri indparamsno
459 (i+1) (n + 1) (nn + 1) dest
460 | C.Prod (name,source,dest) ->
461 does_not_occur context n nn source &&
462 are_all_occurrences_positive ((Some (name,(C.Decl source)))::context)
463 uri indparamsno (i+1) (n + 1) (nn + 1) dest
467 (NotWellFormedTypeOfInductiveConstructor (UriManager.string_of_uri uri)))
469 (* Main function to checks the correctness of a mutual *)
470 (* inductive block definition. This is the function *)
471 (* exported to the proof-engine. *)
472 and typecheck_mutual_inductive_defs uri (itl,_,indparamsno) =
473 let module U = UriManager in
474 (* let's check if the arity of the inductive types are well *)
476 List.iter (fun (_,_,x,_) -> let _ = type_of x in ()) itl ;
478 (* let's check if the types of the inductive constructors *)
479 (* are well formed. *)
480 (* In order not to use type_of_aux we put the types of the *)
481 (* mutual inductive types at the head of the types of the *)
482 (* constructors using Prods *)
483 let len = List.length itl in
485 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl in
491 let debrujinedte = debrujin_constructor uri len te in
494 (fun (name,_,ty,_) i -> Cic.Prod (Cic.Name name, ty, i))
497 let _ = type_of augmented_term in
498 (* let's check also the positivity conditions *)
501 (are_all_occurrences_positive tys uri indparamsno i 0 len
506 (NotPositiveOccurrences (U.string_of_uri uri)))
513 (* Main function to checks the correctness of a mutual *)
514 (* inductive block definition. *)
515 and check_mutual_inductive_defs uri =
517 Cic.InductiveDefinition (itl, params, indparamsno) ->
518 typecheck_mutual_inductive_defs uri (itl,params,indparamsno)
522 (WrongUriToMutualInductiveDefinitions (UriManager.string_of_uri uri)))
524 and type_of_mutual_inductive_defs uri i =
525 let module C = Cic in
526 let module R = CicReduction in
527 let module U = UriManager in
529 match CicEnvironment.is_type_checked ~trust:true uri with
530 CicEnvironment.CheckedObj cobj -> cobj
531 | CicEnvironment.UncheckedObj uobj ->
532 Logger.log (`Start_type_checking uri) ;
533 check_mutual_inductive_defs uri uobj ;
534 CicEnvironment.set_type_checking_info uri ;
535 Logger.log (`Type_checking_completed uri) ;
536 (match CicEnvironment.is_type_checked ~trust:false uri with
537 CicEnvironment.CheckedObj cobj -> cobj
538 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
542 C.InductiveDefinition (dl,_,_) ->
543 let (_,_,arity,_) = List.nth dl i in
548 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
550 and type_of_mutual_inductive_constr uri i j =
551 let module C = Cic in
552 let module R = CicReduction in
553 let module U = UriManager in
555 match CicEnvironment.is_type_checked ~trust:true uri with
556 CicEnvironment.CheckedObj cobj -> cobj
557 | CicEnvironment.UncheckedObj uobj ->
558 Logger.log (`Start_type_checking uri) ;
559 check_mutual_inductive_defs uri uobj ;
560 CicEnvironment.set_type_checking_info uri ;
561 Logger.log (`Type_checking_completed uri) ;
562 (match CicEnvironment.is_type_checked ~trust:false uri with
563 CicEnvironment.CheckedObj cobj -> cobj
564 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
568 C.InductiveDefinition (dl,_,_) ->
569 let (_,_,_,cl) = List.nth dl i in
570 let (_,ty) = List.nth cl (j-1) in
575 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
577 and recursive_args context n nn te =
578 let module C = Cic in
579 match CicReduction.whd context te with
585 | C.Cast _ (*CSC ??? *) ->
586 raise (TypeCheckerFailure (Impossible 3)) (* due to type-checking *)
587 | C.Prod (name,so,de) ->
588 (not (does_not_occur context n nn so)) ::
589 (recursive_args ((Some (name,(C.Decl so)))::context) (n+1) (nn + 1) de)
592 raise (TypeCheckerFailure (Impossible 4)) (* due to type-checking *)
594 | C.Const _ -> raise (TypeCheckerFailure (Impossible 5))
600 raise (TypeCheckerFailure (Impossible 6)) (* due to type-checking *)
602 and get_new_safes context p c rl safes n nn x =
603 let module C = Cic in
604 let module U = UriManager in
605 let module R = CicReduction in
606 match (R.whd context c, R.whd context p, rl) with
607 (C.Prod (_,so,ta1), C.Lambda (name,_,ta2), b::tl) ->
608 (* we are sure that the two sources are convertible because we *)
609 (* have just checked this. So let's go along ... *)
611 List.map (fun x -> x + 1) safes
614 if b then 1::safes' else safes'
616 get_new_safes ((Some (name,(C.Decl so)))::context)
617 ta2 ta1 tl safes'' (n+1) (nn+1) (x+1)
618 | (C.Prod _, (C.MutConstruct _ as e), _)
619 | (C.Prod _, (C.Rel _ as e), _)
620 | (C.MutInd _, e, [])
621 | (C.Appl _, e, []) -> (e,safes,n,nn,x,context)
623 (* CSC: If the next exception is raised, it just means that *)
624 (* CSC: the proof-assistant allows to use very strange things *)
625 (* CSC: as a branch of a case whose type is a Prod. In *)
626 (* CSC: particular, this means that a new (C.Prod, x,_) case *)
627 (* CSC: must be considered in this match. (e.g. x = MutCase) *)
628 raise (TypeCheckerFailure (Impossible 7))
630 and split_prods context n te =
631 let module C = Cic in
632 let module R = CicReduction in
633 match (n, R.whd context te) with
635 | (n, C.Prod (name,so,ta)) when n > 0 ->
636 split_prods ((Some (name,(C.Decl so)))::context) (n - 1) ta
637 | (_, _) -> raise (TypeCheckerFailure (Impossible 8))
639 and eat_lambdas context n te =
640 let module C = Cic in
641 let module R = CicReduction in
642 match (n, R.whd context te) with
643 (0, _) -> (te, 0, context)
644 | (n, C.Lambda (name,so,ta)) when n > 0 ->
645 let (te, k, context') =
646 eat_lambdas ((Some (name,(C.Decl so)))::context) (n - 1) ta
648 (te, k + 1, context')
649 | (_, _) -> raise (TypeCheckerFailure (Impossible 9))
651 (*CSC: Tutto quello che segue e' l'intuzione di luca ;-) *)
652 and check_is_really_smaller_arg context n nn kl x safes te =
653 (*CSC: forse la whd si puo' fare solo quando serve veramente. *)
654 (*CSC: cfr guarded_by_destructors *)
655 let module C = Cic in
656 let module U = UriManager in
657 match CicReduction.whd context te with
658 C.Rel m when List.mem m safes -> true
665 (* | C.Cast (te,ty) ->
666 check_is_really_smaller_arg n nn kl x safes te &&
667 check_is_really_smaller_arg n nn kl x safes ty*)
668 (* | C.Prod (_,so,ta) ->
669 check_is_really_smaller_arg n nn kl x safes so &&
670 check_is_really_smaller_arg (n+1) (nn+1) kl (x+1)
671 (List.map (fun x -> x + 1) safes) ta*)
672 | C.Prod _ -> raise (TypeCheckerFailure (Impossible 10))
673 | C.Lambda (name,so,ta) ->
674 check_is_really_smaller_arg context n nn kl x safes so &&
675 check_is_really_smaller_arg ((Some (name,(C.Decl so)))::context)
676 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
677 | C.LetIn (name,so,ta) ->
678 check_is_really_smaller_arg context n nn kl x safes so &&
679 check_is_really_smaller_arg ((Some (name,(C.Def (so,None))))::context)
680 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
682 (*CSC: sulla coda ci vogliono dei controlli? secondo noi no, ma *)
683 (*CSC: solo perche' non abbiamo trovato controesempi *)
684 check_is_really_smaller_arg context n nn kl x safes he
685 | C.Appl [] -> raise (TypeCheckerFailure (Impossible 11))
687 | C.MutInd _ -> raise (TypeCheckerFailure (Impossible 12))
688 | C.MutConstruct _ -> false
689 | C.MutCase (uri,i,outtype,term,pl) ->
691 C.Rel m when List.mem m safes || m = x ->
692 let (tys,len,isinductive,paramsno,cl) =
693 match CicEnvironment.get_obj uri with
694 C.InductiveDefinition (tl,_,paramsno) ->
697 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) tl
699 let (_,isinductive,_,cl) = List.nth tl i in
703 (id, snd (split_prods tys paramsno ty))) cl
705 (tys,List.length tl,isinductive,paramsno,cl')
709 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
711 if not isinductive then
714 i && check_is_really_smaller_arg context n nn kl x safes p)
720 let debrujinedte = debrujin_constructor uri len c in
721 recursive_args tys 0 len debrujinedte
723 let (e,safes',n',nn',x',context') =
724 get_new_safes context p c rl' safes n nn x
727 check_is_really_smaller_arg context' n' nn' kl x' safes' e
728 ) (List.combine pl cl) true
729 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
730 let (tys,len,isinductive,paramsno,cl) =
731 match CicEnvironment.get_obj uri with
732 C.InductiveDefinition (tl,_,paramsno) ->
733 let (_,isinductive,_,cl) = List.nth tl i in
735 List.map (fun (n,_,ty,_) ->
736 Some(Cic.Name n,(Cic.Decl ty))) tl
741 (id, snd (split_prods tys paramsno ty))) cl
743 (tys,List.length tl,isinductive,paramsno,cl')
747 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
749 if not isinductive then
752 i && check_is_really_smaller_arg context n nn kl x safes p)
755 (*CSC: supponiamo come prima che nessun controllo sia necessario*)
756 (*CSC: sugli argomenti di una applicazione *)
760 let debrujinedte = debrujin_constructor uri len c in
761 recursive_args tys 0 len debrujinedte
763 let (e, safes',n',nn',x',context') =
764 get_new_safes context p c rl' safes n nn x
767 check_is_really_smaller_arg context' n' nn' kl x' safes' e
768 ) (List.combine pl cl) true
772 i && check_is_really_smaller_arg context n nn kl x safes p
776 let len = List.length fl in
777 let n_plus_len = n + len
778 and nn_plus_len = nn + len
779 and x_plus_len = x + len
780 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
781 and safes' = List.map (fun x -> x + len) safes in
783 (fun (_,_,ty,bo) i ->
785 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
789 let len = List.length fl in
790 let n_plus_len = n + len
791 and nn_plus_len = nn + len
792 and x_plus_len = x + len
793 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
794 and safes' = List.map (fun x -> x + len) safes in
798 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
802 and guarded_by_destructors context n nn kl x safes =
803 let module C = Cic in
804 let module U = UriManager in
806 C.Rel m when m > n && m <= nn -> false
808 (match List.nth context (n-1) with
809 Some (_,C.Decl _) -> true
810 | Some (_,C.Def (bo,_)) ->
811 guarded_by_destructors context n nn kl x safes bo
812 | None -> raise (TypeCheckerFailure RelToHiddenHypothesis)
818 guarded_by_destructors context n nn kl x safes te &&
819 guarded_by_destructors context n nn kl x safes ty
820 | C.Prod (name,so,ta) ->
821 guarded_by_destructors context n nn kl x safes so &&
822 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
823 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
824 | C.Lambda (name,so,ta) ->
825 guarded_by_destructors context n nn kl x safes so &&
826 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
827 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
828 | C.LetIn (name,so,ta) ->
829 guarded_by_destructors context n nn kl x safes so &&
830 guarded_by_destructors ((Some (name,(C.Def (so,None))))::context)
831 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
832 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
833 let k = List.nth kl (m - n - 1) in
834 if not (List.length tl > k) then false
838 i && guarded_by_destructors context n nn kl x safes param
840 check_is_really_smaller_arg context n nn kl x safes (List.nth tl k)
843 (fun t i -> i && guarded_by_destructors context n nn kl x safes t)
845 | C.Var (_,exp_named_subst)
846 | C.Const (_,exp_named_subst)
847 | C.MutInd (_,_,exp_named_subst)
848 | C.MutConstruct (_,_,_,exp_named_subst) ->
850 (fun (_,t) i -> i && guarded_by_destructors context n nn kl x safes t)
852 | C.MutCase (uri,i,outtype,term,pl) ->
854 C.Rel m when List.mem m safes || m = x ->
855 let (tys,len,isinductive,paramsno,cl) =
856 match CicEnvironment.get_obj uri with
857 C.InductiveDefinition (tl,_,paramsno) ->
858 let (_,isinductive,_,cl) = List.nth tl i in
860 List.map (fun (n,_,ty,_) ->
861 Some(Cic.Name n,(Cic.Decl ty))) tl
866 (id, snd (split_prods tys paramsno ty))) cl
868 (tys,List.length tl,isinductive,paramsno,cl')
872 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
874 if not isinductive then
875 guarded_by_destructors context n nn kl x safes outtype &&
876 guarded_by_destructors context n nn kl x safes term &&
877 (*CSC: manca ??? il controllo sul tipo di term? *)
880 i && guarded_by_destructors context n nn kl x safes p)
883 guarded_by_destructors context n nn kl x safes outtype &&
884 (*CSC: manca ??? il controllo sul tipo di term? *)
888 let debrujinedte = debrujin_constructor uri len c in
889 recursive_args tys 0 len debrujinedte
891 let (e,safes',n',nn',x',context') =
892 get_new_safes context p c rl' safes n nn x
895 guarded_by_destructors context' n' nn' kl x' safes' e
896 ) (List.combine pl cl) true
897 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
898 let (tys,len,isinductive,paramsno,cl) =
899 match CicEnvironment.get_obj uri with
900 C.InductiveDefinition (tl,_,paramsno) ->
901 let (_,isinductive,_,cl) = List.nth tl i in
904 (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
909 (id, snd (split_prods tys paramsno ty))) cl
911 (tys,List.length tl,isinductive,paramsno,cl')
915 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
917 if not isinductive then
918 guarded_by_destructors context n nn kl x safes outtype &&
919 guarded_by_destructors context n nn kl x safes term &&
920 (*CSC: manca ??? il controllo sul tipo di term? *)
923 i && guarded_by_destructors context n nn kl x safes p)
926 guarded_by_destructors context n nn kl x safes outtype &&
927 (*CSC: manca ??? il controllo sul tipo di term? *)
930 i && guarded_by_destructors context n nn kl x safes t)
935 let debrujinedte = debrujin_constructor uri len c in
936 recursive_args tys 0 len debrujinedte
938 let (e, safes',n',nn',x',context') =
939 get_new_safes context p c rl' safes n nn x
942 guarded_by_destructors context' n' nn' kl x' safes' e
943 ) (List.combine pl cl) true
945 guarded_by_destructors context n nn kl x safes outtype &&
946 guarded_by_destructors context n nn kl x safes term &&
947 (*CSC: manca ??? il controllo sul tipo di term? *)
949 (fun p i -> i && guarded_by_destructors context n nn kl x safes p)
953 let len = List.length fl in
954 let n_plus_len = n + len
955 and nn_plus_len = nn + len
956 and x_plus_len = x + len
957 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
958 and safes' = List.map (fun x -> x + len) safes in
960 (fun (_,_,ty,bo) i ->
961 i && guarded_by_destructors context n nn kl x_plus_len safes' ty &&
962 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
966 let len = List.length fl in
967 let n_plus_len = n + len
968 and nn_plus_len = nn + len
969 and x_plus_len = x + len
970 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
971 and safes' = List.map (fun x -> x + len) safes in
975 guarded_by_destructors context n nn kl x_plus_len safes' ty &&
976 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
980 (* the boolean h means already protected *)
981 (* args is the list of arguments the type of the constructor that may be *)
982 (* found in head position must be applied to. *)
983 (*CSC: coInductiveTypeURI non cambia mai di ricorsione in ricorsione *)
984 and guarded_by_constructors context n nn h te args coInductiveTypeURI =
985 let module C = Cic in
986 (*CSC: There is a lot of code replication between the cases X and *)
987 (*CSC: (C.Appl X tl). Maybe it will be better to define a function *)
988 (*CSC: that maps X into (C.Appl X []) when X is not already a C.Appl *)
989 match CicReduction.whd context te with
990 C.Rel m when m > n && m <= nn -> h
998 (* the term has just been type-checked *)
999 raise (TypeCheckerFailure (Impossible 17))
1000 | C.Lambda (name,so,de) ->
1001 does_not_occur context n nn so &&
1002 guarded_by_constructors ((Some (name,(C.Decl so)))::context)
1003 (n + 1) (nn + 1) h de args coInductiveTypeURI
1004 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
1006 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
1007 | C.Appl ((C.MutConstruct (uri,i,j,exp_named_subst))::tl) ->
1009 match CicEnvironment.get_cooked_obj ~trust:false uri with
1010 C.InductiveDefinition (itl,_,_) ->
1011 let (_,_,_,cl) = List.nth itl i in
1012 let (_,cons) = List.nth cl (j - 1) in
1013 CicSubstitution.subst_vars exp_named_subst cons
1017 (WrongUriToMutualInductiveDefinitions
1018 (UriManager.string_of_uri uri)))
1020 let rec analyse_branch context ty te =
1021 match CicReduction.whd context ty with
1022 C.Meta _ -> raise (TypeCheckerFailure (Impossible 34))
1026 does_not_occur context n nn te
1029 raise (TypeCheckerFailure (Impossible 24))(* due to type-checking *)
1030 | C.Prod (name,so,de) ->
1031 analyse_branch ((Some (name,(C.Decl so)))::context) de te
1034 raise (TypeCheckerFailure (Impossible 25))(* due to type-checking *)
1035 | C.Appl ((C.MutInd (uri,_,_))::_) as ty
1036 when uri == coInductiveTypeURI ->
1037 guarded_by_constructors context n nn true te [] coInductiveTypeURI
1038 | C.Appl ((C.MutInd (uri,_,_))::_) as ty ->
1039 guarded_by_constructors context n nn true te tl coInductiveTypeURI
1041 does_not_occur context n nn te
1042 | C.Const _ -> raise (TypeCheckerFailure (Impossible 26))
1043 | C.MutInd (uri,_,_) when uri == coInductiveTypeURI ->
1044 guarded_by_constructors context n nn true te [] coInductiveTypeURI
1046 does_not_occur context n nn te
1047 | C.MutConstruct _ -> raise (TypeCheckerFailure (Impossible 27))
1048 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
1049 (*CSC: in head position. *)
1053 raise (TypeCheckerFailure (Impossible 28))(* due to type-checking *)
1055 let rec analyse_instantiated_type context ty l =
1056 match CicReduction.whd context ty with
1063 raise (TypeCheckerFailure (Impossible 29))(* due to type-checking *)
1064 | C.Prod (name,so,de) ->
1069 analyse_branch context so he &&
1070 analyse_instantiated_type
1071 ((Some (name,(C.Decl so)))::context) de tl
1075 raise (TypeCheckerFailure (Impossible 30))(* due to type-checking *)
1078 (fun i x -> i && does_not_occur context n nn x) true l
1079 | C.Const _ -> raise (TypeCheckerFailure (Impossible 31))
1082 (fun i x -> i && does_not_occur context n nn x) true l
1083 | C.MutConstruct _ -> raise (TypeCheckerFailure (Impossible 32))
1084 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
1085 (*CSC: in head position. *)
1089 raise (TypeCheckerFailure (Impossible 33))(* due to type-checking *)
1091 let rec instantiate_type args consty =
1094 | tlhe::tltl as l ->
1095 let consty' = CicReduction.whd context consty in
1101 let instantiated_de = CicSubstitution.subst he de in
1102 (*CSC: siamo sicuri che non sia troppo forte? *)
1103 does_not_occur context n nn tlhe &
1104 instantiate_type tl instantiated_de tltl
1106 (*CSC:We do not consider backbones with a MutCase, a *)
1107 (*CSC:FixPoint, a CoFixPoint and so on in head position.*)
1108 raise (TypeCheckerFailure (Impossible 23))
1110 | [] -> analyse_instantiated_type context consty' l
1111 (* These are all the other cases *)
1113 instantiate_type args consty tl
1114 | C.Appl ((C.CoFix (_,fl))::tl) ->
1115 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1116 let len = List.length fl in
1117 let n_plus_len = n + len
1118 and nn_plus_len = nn + len
1119 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1120 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1123 i && does_not_occur context n nn ty &&
1124 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1125 args coInductiveTypeURI
1127 | C.Appl ((C.MutCase (_,_,out,te,pl))::tl) ->
1128 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1129 does_not_occur context n nn out &&
1130 does_not_occur context n nn te &&
1134 guarded_by_constructors context n nn h x args coInductiveTypeURI
1137 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
1138 | C.Var (_,exp_named_subst)
1139 | C.Const (_,exp_named_subst) ->
1141 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1142 | C.MutInd _ -> assert false
1143 | C.MutConstruct (_,_,_,exp_named_subst) ->
1145 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1146 | C.MutCase (_,_,out,te,pl) ->
1147 does_not_occur context n nn out &&
1148 does_not_occur context n nn te &&
1152 guarded_by_constructors context n nn h x args coInductiveTypeURI
1155 let len = List.length fl in
1156 let n_plus_len = n + len
1157 and nn_plus_len = nn + len
1158 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1159 and tys = List.map (fun (n,_,ty,_)-> Some (C.Name n,(C.Decl ty))) fl in
1161 (fun (_,_,ty,bo) i ->
1162 i && does_not_occur context n nn ty &&
1163 does_not_occur (tys@context) n_plus_len nn_plus_len bo
1166 let len = List.length fl in
1167 let n_plus_len = n + len
1168 and nn_plus_len = nn + len
1169 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1170 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1173 i && does_not_occur context n nn ty &&
1174 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1175 args coInductiveTypeURI
1178 and check_allowed_sort_elimination context uri i need_dummy ind arity1 arity2 =
1179 let module C = Cic in
1180 let module U = UriManager in
1181 match (CicReduction.whd context arity1, CicReduction.whd context arity2) with
1182 (C.Prod (_,so1,de1), C.Prod (_,so2,de2))
1183 when CicReduction.are_convertible context so1 so2 ->
1184 check_allowed_sort_elimination context uri i need_dummy
1185 (C.Appl [CicSubstitution.lift 1 ind ; C.Rel 1]) de1 de2
1186 | (C.Sort C.Prop, C.Sort C.Prop) when need_dummy -> true
1187 | (C.Sort C.Prop, C.Sort C.Set)
1188 | (C.Sort C.Prop, C.Sort C.Type) when need_dummy ->
1189 (*CSC: WRONG. MISSING CONDITIONS ON THE ARGUMENTS OF THE CONSTRUTOR *)
1190 (match CicEnvironment.get_obj uri with
1191 C.InductiveDefinition (itl,_,_) ->
1192 let (_,_,_,cl) = List.nth itl i in
1193 (* is a singleton definition or the empty proposition? *)
1194 List.length cl = 1 || List.length cl = 0
1198 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
1200 | (C.Sort C.Set, C.Sort C.Prop) when need_dummy -> true
1201 | (C.Sort C.Set, C.Sort C.Set) when need_dummy -> true
1202 | (C.Sort C.Set, C.Sort C.Type) when need_dummy ->
1203 (match CicEnvironment.get_obj uri with
1204 C.InductiveDefinition (itl,_,paramsno) ->
1206 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1208 let (_,_,_,cl) = List.nth itl i in
1210 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1214 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
1216 | (C.Sort C.Type, C.Sort _) when need_dummy -> true
1217 | (C.Sort C.Prop, C.Prod (name,so,ta)) when not need_dummy ->
1218 let res = CicReduction.are_convertible context so ind
1221 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1222 C.Sort C.Prop -> true
1224 (match CicEnvironment.get_obj uri with
1225 C.InductiveDefinition (itl,_,_) ->
1226 let (_,_,_,cl) = List.nth itl i in
1227 (* is a singleton definition? *)
1232 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
1236 | (C.Sort C.Set, C.Prod (name,so,ta)) when not need_dummy ->
1237 let res = CicReduction.are_convertible context so ind
1240 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1242 | C.Sort C.Set -> true
1244 (match CicEnvironment.get_obj uri with
1245 C.InductiveDefinition (itl,_,paramsno) ->
1246 let (_,_,_,cl) = List.nth itl i in
1249 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1252 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1256 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
1258 | _ -> raise (TypeCheckerFailure (Impossible 19))
1260 | (C.Sort C.Type, C.Prod (_,so,_)) when not need_dummy ->
1261 CicReduction.are_convertible context so ind
1264 and type_of_branch context argsno need_dummy outtype term constype =
1265 let module C = Cic in
1266 let module R = CicReduction in
1267 match R.whd context constype with
1272 C.Appl [outtype ; term]
1273 | C.Appl (C.MutInd (_,_,_)::tl) ->
1274 let (_,arguments) = split tl argsno
1276 if need_dummy && arguments = [] then
1279 C.Appl (outtype::arguments@(if need_dummy then [] else [term]))
1280 | C.Prod (name,so,de) ->
1282 match CicSubstitution.lift 1 term with
1283 C.Appl l -> C.Appl (l@[C.Rel 1])
1284 | t -> C.Appl [t ; C.Rel 1]
1286 C.Prod (C.Anonymous,so,type_of_branch
1287 ((Some (name,(C.Decl so)))::context) argsno need_dummy
1288 (CicSubstitution.lift 1 outtype) term' de)
1289 | _ -> raise (TypeCheckerFailure (Impossible 20))
1291 (* check_metasenv_consistency checks that the "canonical" context of a
1292 metavariable is consitent - up to relocation via the relocation list l -
1293 with the actual context *)
1295 and check_metasenv_consistency metasenv context canonical_context l =
1296 let module C = Cic in
1297 let module R = CicReduction in
1298 let module S = CicSubstitution in
1299 let lifted_canonical_context =
1303 | (Some (n,C.Decl t))::tl ->
1304 (Some (n,C.Decl (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1305 | (Some (n,C.Def (t,None)))::tl ->
1306 (Some (n,C.Def ((S.lift_meta l (S.lift i t)),None)))::(aux (i+1) tl)
1307 | None::tl -> None::(aux (i+1) tl)
1308 | (Some (n,C.Def (_,Some _)))::_ -> assert false
1310 aux 1 canonical_context
1317 | Some t,Some (_,C.Def (ct,_)) ->
1318 R.are_convertible context t ct
1319 | Some t,Some (_,C.Decl ct) ->
1320 R.are_convertible context (type_of_aux' metasenv context t) ct
1323 if not res then raise (TypeCheckerFailure MetasenvInconsistency)
1324 ) l lifted_canonical_context
1326 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
1327 and type_of_aux' metasenv context t =
1328 let rec type_of_aux context =
1329 let module C = Cic in
1330 let module R = CicReduction in
1331 let module S = CicSubstitution in
1332 let module U = UriManager in
1336 match List.nth context (n - 1) with
1337 Some (_,C.Decl t) -> S.lift n t
1338 | Some (_,C.Def (_,Some ty)) -> S.lift n ty
1339 | Some (_,C.Def (bo,None)) ->
1340 prerr_endline "##### CASO DA INVESTIGARE E CAPIRE" ;
1341 type_of_aux context (S.lift n bo)
1342 | None -> raise (TypeCheckerFailure RelToHiddenHypothesis)
1344 _ -> raise (TypeCheckerFailure (NotWellTyped "Not a close term"))
1346 | C.Var (uri,exp_named_subst) ->
1348 check_exp_named_subst context exp_named_subst ;
1350 CicSubstitution.subst_vars exp_named_subst (type_of_variable uri)
1355 let (_,canonical_context,ty) =
1356 List.find (function (m,_,_) -> n = m) metasenv
1358 check_metasenv_consistency metasenv context canonical_context l;
1359 CicSubstitution.lift_meta l ty
1360 | C.Sort s -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1361 | C.Implicit -> raise (TypeCheckerFailure (Impossible 21))
1363 let _ = type_of_aux context ty in
1364 if R.are_convertible context (type_of_aux context te) ty then ty
1365 else raise (TypeCheckerFailure (NotWellTyped "Cast"))
1366 | C.Prod (name,s,t) ->
1367 let sort1 = type_of_aux context s
1368 and sort2 = type_of_aux ((Some (name,(C.Decl s)))::context) t in
1369 sort_of_prod context (name,s) (sort1,sort2)
1370 | C.Lambda (n,s,t) ->
1371 let sort1 = type_of_aux context s
1372 and type2 = type_of_aux ((Some (n,(C.Decl s)))::context) t in
1373 let sort2 = type_of_aux ((Some (n,(C.Decl s)))::context) type2 in
1374 (* only to check if the product is well-typed *)
1375 let _ = sort_of_prod context (n,s) (sort1,sort2) in
1377 | C.LetIn (n,s,t) ->
1378 (* only to check if s is well-typed *)
1379 let ty = type_of_aux context s in
1380 (* The type of a LetIn is a LetIn. Extremely slow since the computed
1381 LetIn is later reduced and maybe also re-checked.
1382 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t))
1384 (* The type of the LetIn is reduced. Much faster than the previous
1385 solution. Moreover the inferred type is probably very different
1386 from the expected one.
1387 (CicReduction.whd context
1388 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t)))
1390 (* One-step LetIn reduction. Even faster than the previous solution.
1391 Moreover the inferred type is closer to the expected one. *)
1392 (CicSubstitution.subst s
1393 (type_of_aux ((Some (n,(C.Def (s,Some ty))))::context) t))
1394 | C.Appl (he::tl) when List.length tl > 0 ->
1395 let hetype = type_of_aux context he
1396 and tlbody_and_type = List.map (fun x -> (x, type_of_aux context x)) tl in
1397 eat_prods context hetype tlbody_and_type
1398 | C.Appl _ -> raise (TypeCheckerFailure (NotWellTyped "Appl: no arguments"))
1399 | C.Const (uri,exp_named_subst) ->
1401 check_exp_named_subst context exp_named_subst ;
1403 CicSubstitution.subst_vars exp_named_subst (type_of_constant uri)
1407 | C.MutInd (uri,i,exp_named_subst) ->
1409 check_exp_named_subst context exp_named_subst ;
1411 CicSubstitution.subst_vars exp_named_subst
1412 (type_of_mutual_inductive_defs uri i)
1416 | C.MutConstruct (uri,i,j,exp_named_subst) ->
1417 check_exp_named_subst context exp_named_subst ;
1419 CicSubstitution.subst_vars exp_named_subst
1420 (type_of_mutual_inductive_constr uri i j)
1423 | C.MutCase (uri,i,outtype,term,pl) ->
1424 let outsort = type_of_aux context outtype in
1425 let (need_dummy, k) =
1426 let rec guess_args context t =
1427 match CicReduction.whd context t with
1428 C.Sort _ -> (true, 0)
1429 | C.Prod (name, s, t) ->
1430 let (b, n) = guess_args ((Some (name,(C.Decl s)))::context) t in
1432 (* last prod before sort *)
1433 match CicReduction.whd context s with
1434 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1435 C.MutInd (uri',i',_) when U.eq uri' uri && i' = i ->
1437 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1438 | C.Appl ((C.MutInd (uri',i',_)) :: _)
1439 when U.eq uri' uri && i' = i -> (false, 1)
1445 (TypeCheckerFailure (NotWellTyped "MutCase: outtype ill-formed"))
1447 (*CSC whd non serve dopo type_of_aux ? *)
1448 let (b, k) = guess_args context outsort in
1449 if not b then (b, k - 1) else (b, k)
1451 let (parameters, arguments, exp_named_subst) =
1452 match R.whd context (type_of_aux context term) with
1453 (*CSC manca il caso dei CAST *)
1454 (*CSC: ma servono i parametri (uri,i)? Se si', perche' non serve anche il *)
1455 (*CSC: parametro exp_named_subst? Se no, perche' non li togliamo? *)
1456 (*CSC: Hint: nella DTD servono per gli stylesheet. *)
1457 C.MutInd (uri',i',exp_named_subst) as typ ->
1458 if U.eq uri uri' && i = i' then ([],[],exp_named_subst)
1459 else raise (TypeCheckerFailure
1460 (NotWellTyped ("MutCase: the term is of type " ^
1462 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1463 string_of_int i ^ "{_}")))
1464 | C.Appl ((C.MutInd (uri',i',exp_named_subst) as typ):: tl) ->
1465 if U.eq uri uri' && i = i' then
1467 split tl (List.length tl - k)
1468 in params,args,exp_named_subst
1469 else raise (TypeCheckerFailure (NotWellTyped
1470 ("MutCase: the term is of type " ^
1472 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1473 string_of_int i ^ "{_}")))
1474 | _ -> raise (TypeCheckerFailure
1475 (NotWellTyped "MutCase: the term is not an inductive one"))
1477 (* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
1478 let sort_of_ind_type =
1479 if parameters = [] then
1480 C.MutInd (uri,i,exp_named_subst)
1482 C.Appl ((C.MutInd (uri,i,exp_named_subst))::parameters)
1484 if not (check_allowed_sort_elimination context uri i need_dummy
1485 sort_of_ind_type (type_of_aux context sort_of_ind_type) outsort)
1489 (NotWellTyped "MutCase: not allowed sort elimination")) ;
1491 (* let's check if the type of branches are right *)
1493 match CicEnvironment.get_cooked_obj ~trust:false uri with
1494 C.InductiveDefinition (_,_,parsno) -> parsno
1498 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
1500 let (_,branches_ok) =
1504 if parameters = [] then
1505 (C.MutConstruct (uri,i,j,exp_named_subst))
1507 (C.Appl (C.MutConstruct (uri,i,j,exp_named_subst)::parameters))
1514 R.are_convertible context (type_of_aux context p)
1515 (type_of_branch context parsno need_dummy outtype cons
1516 (type_of_aux context cons))
1517 in if not res then prerr_endline ("#### " ^ CicPp.ppterm (type_of_aux context p) ^ " <==> " ^ CicPp.ppterm (type_of_branch context parsno need_dummy outtype cons (type_of_aux context cons))) ; res
1521 if not branches_ok then
1524 (NotWellTyped "MutCase: wrong type of a branch")) ;
1526 if not need_dummy then
1527 C.Appl ((outtype::arguments)@[term])
1528 else if arguments = [] then
1531 C.Appl (outtype::arguments)
1533 let types_times_kl =
1537 let _ = type_of_aux context ty in
1538 (Some (C.Name n,(C.Decl ty)),k)) fl)
1540 let (types,kl) = List.split types_times_kl in
1541 let len = List.length types in
1543 (fun (name,x,ty,bo) ->
1545 (R.are_convertible (types@context) (type_of_aux (types@context) bo)
1546 (CicSubstitution.lift len ty))
1549 let (m, eaten, context') =
1550 eat_lambdas (types @ context) (x + 1) bo
1552 (*let's control the guarded by destructors conditions D{f,k,x,M}*)
1555 (guarded_by_destructors context' eaten (len + eaten) kl 1 [] m)
1559 (NotWellTyped "Fix: not guarded by destructors"))
1562 raise (TypeCheckerFailure (NotWellTyped "Fix: ill-typed bodies"))
1565 (*CSC: controlli mancanti solo su D{f,k,x,M} *)
1566 let (_,_,ty,_) = List.nth fl i in
1573 let _ = type_of_aux context ty in Some (C.Name n,(C.Decl ty))) fl)
1575 let len = List.length types in
1579 (R.are_convertible (types @ context)
1580 (type_of_aux (types @ context) bo) (CicSubstitution.lift len ty))
1583 (* let's control that the returned type is coinductive *)
1584 match returns_a_coinductive context ty with
1588 (NotWellTyped "CoFix: does not return a coinductive type"))
1590 (*let's control the guarded by constructors conditions C{f,M}*)
1593 (guarded_by_constructors (types @ context) 0 len false bo
1598 (NotWellTyped "CoFix: not guarded by constructors"))
1603 (NotWellTyped "CoFix: ill-typed bodies"))
1606 let (_,ty,_) = List.nth fl i in
1609 and check_exp_named_subst context =
1610 let rec check_exp_named_subst_aux substs =
1613 | ((uri,t) as subst)::tl ->
1615 CicSubstitution.subst_vars substs (type_of_variable uri) in
1616 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1617 Cic.Variable (_,Some bo,_,_) ->
1621 "A variable with a body can not be explicit substituted"))
1622 | Cic.Variable (_,None,_,_) -> ()
1626 (WrongUriToVariable (UriManager.string_of_uri uri)))
1628 let typeoft = type_of_aux context t in
1629 if CicReduction.are_convertible context typeoft typeofvar then
1630 check_exp_named_subst_aux (substs@[subst]) tl
1633 CicReduction.fdebug := 0 ;
1634 ignore (CicReduction.are_convertible context typeoft typeofvar) ;
1636 debug typeoft [typeofvar] ;
1639 (NotWellTyped "Wrong Explicit Named Substitution"))
1642 check_exp_named_subst_aux []
1644 and sort_of_prod context (name,s) (t1, t2) =
1645 let module C = Cic in
1646 let t1' = CicReduction.whd context t1 in
1647 let t2' = CicReduction.whd ((Some (name,C.Decl s))::context) t2 in
1648 match (t1', t2') with
1649 (C.Sort s1, C.Sort s2)
1650 when (s2 = C.Prop or s2 = C.Set) -> (* different from Coq manual!!! *)
1652 | (C.Sort s1, C.Sort s2) -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1657 ("Prod: sort1= " ^ CicPp.ppterm t1' ^ " ; sort2= "^ CicPp.ppterm t2')))
1659 and eat_prods context hetype =
1660 (*CSC: siamo sicuri che le are_convertible non lavorino con termini non *)
1664 | (hete, hety)::tl ->
1665 (match (CicReduction.whd context hetype) with
1667 if CicReduction.are_convertible context s hety then
1668 (CicReduction.fdebug := -1 ;
1669 eat_prods context (CicSubstitution.subst hete t) tl
1673 CicReduction.fdebug := 0 ;
1674 ignore (CicReduction.are_convertible context s hety) ;
1678 (TypeCheckerFailure (NotWellTyped "Appl: wrong parameter-type"))
1680 | _ -> raise (TypeCheckerFailure (NotWellTyped "Appl: wrong Prod-type"))
1683 and returns_a_coinductive context ty =
1684 let module C = Cic in
1685 match CicReduction.whd context ty with
1686 C.MutInd (uri,i,_) ->
1687 (*CSC: definire una funzioncina per questo codice sempre replicato *)
1688 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1689 C.InductiveDefinition (itl,_,_) ->
1690 let (_,is_inductive,_,_) = List.nth itl i in
1691 if is_inductive then None else (Some uri)
1694 (TypeCheckerFailure (WrongUriToMutualInductiveDefinitions
1695 (UriManager.string_of_uri uri)))
1697 | C.Appl ((C.MutInd (uri,i,_))::_) ->
1698 (match CicEnvironment.get_obj uri with
1699 C.InductiveDefinition (itl,_,_) ->
1700 let (_,is_inductive,_,_) = List.nth itl i in
1701 if is_inductive then None else (Some uri)
1705 (WrongUriToMutualInductiveDefinitions
1706 (UriManager.string_of_uri uri)))
1708 | C.Prod (n,so,de) ->
1709 returns_a_coinductive ((Some (n,C.Decl so))::context) de
1714 prerr_endline ("INIZIO TYPE_OF_AUX " ^ CicPp.ppterm t) ; flush stderr ;
1717 type_of_aux context t
1719 in prerr_endline "FINE TYPE_OF_AUX" ; flush stderr ; res
1722 (* is a small constructor? *)
1723 (*CSC: ottimizzare calcolando staticamente *)
1724 and is_small context paramsno c =
1725 let rec is_small_aux context c =
1726 let module C = Cic in
1727 match CicReduction.whd context c with
1729 (*CSC: [] is an empty metasenv. Is it correct? *)
1730 let s = type_of_aux' [] context so in
1731 (s = C.Sort C.Prop || s = C.Sort C.Set) &&
1732 is_small_aux ((Some (n,(C.Decl so)))::context) de
1733 | _ -> true (*CSC: we trust the type-checker *)
1735 let (context',dx) = split_prods context paramsno c in
1736 is_small_aux context' dx
1740 prerr_endline ("INIZIO TYPE_OF_AUX' " ^ CicPp.ppterm t) ; flush stderr ;
1743 type_of_aux' [] [] t
1745 in prerr_endline "FINE TYPE_OF_AUX'" ; flush stderr ; res
1750 let module C = Cic in
1751 let module R = CicReduction in
1752 let module U = UriManager in
1753 match CicEnvironment.is_type_checked ~trust:false uri with
1754 CicEnvironment.CheckedObj _ -> ()
1755 | CicEnvironment.UncheckedObj uobj ->
1756 (* let's typecheck the uncooked object *)
1757 Logger.log (`Start_type_checking uri) ;
1759 C.Constant (_,Some te,ty,_) ->
1760 let _ = type_of ty in
1761 if not (R.are_convertible [] (type_of te ) ty) then
1764 (NotWellTyped ("Constant " ^ (U.string_of_uri uri))))
1765 | C.Constant (_,None,ty,_) ->
1766 (* only to check that ty is well-typed *)
1767 let _ = type_of ty in ()
1768 | C.CurrentProof (_,conjs,te,ty,_) ->
1771 (fun metasenv ((_,context,ty) as conj) ->
1772 ignore (type_of_aux' metasenv context ty) ;
1776 let _ = type_of_aux' conjs [] ty in
1777 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
1781 (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri))))
1782 | C.Variable (_,bo,ty,_) ->
1783 (* only to check that ty is well-typed *)
1784 let _ = type_of ty in
1788 if not (R.are_convertible [] (type_of bo) ty) then
1791 (NotWellTyped ("Variable" ^ (U.string_of_uri uri))))
1793 | C.InductiveDefinition _ ->
1794 check_mutual_inductive_defs uri uobj
1796 CicEnvironment.set_type_checking_info uri ;
1797 Logger.log (`Type_checking_completed uri)