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 CicLogger.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 CicLogger.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 CicLogger.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 CicLogger.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 CicLogger.log (`Start_type_checking uri) ;
533 check_mutual_inductive_defs uri uobj ;
534 CicEnvironment.set_type_checking_info uri ;
535 CicLogger.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 CicLogger.log (`Start_type_checking uri) ;
559 check_mutual_inductive_defs uri uobj ;
560 CicEnvironment.set_type_checking_info uri ;
561 CicLogger.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.CProp)
1189 | (C.Sort C.Prop, C.Sort C.Type) when need_dummy ->
1190 (*CSC: WRONG. MISSING CONDITIONS ON THE ARGUMENTS OF THE CONSTRUTOR *)
1191 (match CicEnvironment.get_obj uri with
1192 C.InductiveDefinition (itl,_,_) ->
1193 let (_,_,_,cl) = List.nth itl i in
1194 (* is a singleton definition or the empty proposition? *)
1195 List.length cl = 1 || List.length cl = 0
1199 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
1201 | (C.Sort C.Set, C.Sort C.Prop) when need_dummy -> true
1202 | (C.Sort C.CProp, C.Sort C.Prop) when need_dummy -> true
1203 | (C.Sort C.Set, C.Sort C.Set) when need_dummy -> true
1204 | (C.Sort C.Set, C.Sort C.CProp) when need_dummy -> true
1205 | (C.Sort C.CProp, C.Sort C.Set) when need_dummy -> true
1206 | (C.Sort C.CProp, C.Sort C.CProp) when need_dummy -> true
1207 | ((C.Sort C.Set, C.Sort C.Type) | (C.Sort C.CProp, C.Sort C.Type))
1209 (match CicEnvironment.get_obj uri with
1210 C.InductiveDefinition (itl,_,paramsno) ->
1212 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1214 let (_,_,_,cl) = List.nth itl i in
1216 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1220 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
1222 | (C.Sort C.Type, C.Sort _) when need_dummy -> true
1223 | (C.Sort C.Prop, C.Prod (name,so,ta)) when not need_dummy ->
1224 let res = CicReduction.are_convertible context so ind
1227 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1228 C.Sort C.Prop -> true
1229 | (C.Sort C.Set | C.Sort C.CProp) ->
1230 (match CicEnvironment.get_obj uri with
1231 C.InductiveDefinition (itl,_,_) ->
1232 let (_,_,_,cl) = List.nth itl i in
1233 (* is a singleton definition? *)
1238 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
1242 | ((C.Sort C.Set, C.Prod (name,so,ta)) | (C.Sort C.CProp, C.Prod (name,so,ta)))
1243 when not need_dummy ->
1244 let res = CicReduction.are_convertible context so ind
1247 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1249 | C.Sort C.Set -> true
1250 | C.Sort C.CProp -> true
1252 (match CicEnvironment.get_obj uri with
1253 C.InductiveDefinition (itl,_,paramsno) ->
1254 let (_,_,_,cl) = List.nth itl i in
1257 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1260 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1264 (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri)))
1266 | _ -> raise (TypeCheckerFailure (Impossible 19))
1268 | (C.Sort C.Type, C.Prod (_,so,_)) when not need_dummy ->
1269 CicReduction.are_convertible context so ind
1272 and type_of_branch context argsno need_dummy outtype term constype =
1273 let module C = Cic in
1274 let module R = CicReduction in
1275 match R.whd context constype with
1280 C.Appl [outtype ; term]
1281 | C.Appl (C.MutInd (_,_,_)::tl) ->
1282 let (_,arguments) = split tl argsno
1284 if need_dummy && arguments = [] then
1287 C.Appl (outtype::arguments@(if need_dummy then [] else [term]))
1288 | C.Prod (name,so,de) ->
1290 match CicSubstitution.lift 1 term with
1291 C.Appl l -> C.Appl (l@[C.Rel 1])
1292 | t -> C.Appl [t ; C.Rel 1]
1294 C.Prod (C.Anonymous,so,type_of_branch
1295 ((Some (name,(C.Decl so)))::context) argsno need_dummy
1296 (CicSubstitution.lift 1 outtype) term' de)
1297 | _ -> raise (TypeCheckerFailure (Impossible 20))
1299 (* check_metasenv_consistency checks that the "canonical" context of a
1300 metavariable is consitent - up to relocation via the relocation list l -
1301 with the actual context *)
1303 and check_metasenv_consistency metasenv context canonical_context l =
1304 let module C = Cic in
1305 let module R = CicReduction in
1306 let module S = CicSubstitution in
1307 let lifted_canonical_context =
1311 | (Some (n,C.Decl t))::tl ->
1312 (Some (n,C.Decl (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1313 | (Some (n,C.Def (t,None)))::tl ->
1314 (Some (n,C.Def ((S.lift_meta l (S.lift i t)),None)))::(aux (i+1) tl)
1315 | None::tl -> None::(aux (i+1) tl)
1316 | (Some (n,C.Def (_,Some _)))::_ -> assert false
1318 aux 1 canonical_context
1325 | Some t,Some (_,C.Def (ct,_)) ->
1326 R.are_convertible context t ct
1327 | Some t,Some (_,C.Decl ct) ->
1328 R.are_convertible context (type_of_aux' metasenv context t) ct
1331 if not res then raise (TypeCheckerFailure MetasenvInconsistency)
1332 ) l lifted_canonical_context
1334 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
1335 and type_of_aux' metasenv context t =
1336 let rec type_of_aux context =
1337 let module C = Cic in
1338 let module R = CicReduction in
1339 let module S = CicSubstitution in
1340 let module U = UriManager in
1344 match List.nth context (n - 1) with
1345 Some (_,C.Decl t) -> S.lift n t
1346 | Some (_,C.Def (_,Some ty)) -> S.lift n ty
1347 | Some (_,C.Def (bo,None)) ->
1348 prerr_endline "##### CASO DA INVESTIGARE E CAPIRE" ;
1349 type_of_aux context (S.lift n bo)
1350 | None -> raise (TypeCheckerFailure RelToHiddenHypothesis)
1352 _ -> raise (TypeCheckerFailure (NotWellTyped "Not a close term"))
1354 | C.Var (uri,exp_named_subst) ->
1356 check_exp_named_subst context exp_named_subst ;
1358 CicSubstitution.subst_vars exp_named_subst (type_of_variable uri)
1363 let (_,canonical_context,ty) =
1364 List.find (function (m,_,_) -> n = m) metasenv
1366 check_metasenv_consistency metasenv context canonical_context l;
1367 CicSubstitution.lift_meta l ty
1368 | C.Sort s -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1369 | C.Implicit -> raise (TypeCheckerFailure (Impossible 21))
1371 let _ = type_of_aux context ty in
1372 if R.are_convertible context (type_of_aux context te) ty then ty
1373 else raise (TypeCheckerFailure (NotWellTyped "Cast"))
1374 | C.Prod (name,s,t) ->
1375 let sort1 = type_of_aux context s
1376 and sort2 = type_of_aux ((Some (name,(C.Decl s)))::context) t in
1377 sort_of_prod context (name,s) (sort1,sort2)
1378 | C.Lambda (n,s,t) ->
1379 let sort1 = type_of_aux context s
1380 and type2 = type_of_aux ((Some (n,(C.Decl s)))::context) t in
1381 let sort2 = type_of_aux ((Some (n,(C.Decl s)))::context) type2 in
1382 (* only to check if the product is well-typed *)
1383 let _ = sort_of_prod context (n,s) (sort1,sort2) in
1385 | C.LetIn (n,s,t) ->
1386 (* only to check if s is well-typed *)
1387 let ty = type_of_aux context s in
1388 (* The type of a LetIn is a LetIn. Extremely slow since the computed
1389 LetIn is later reduced and maybe also re-checked.
1390 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t))
1392 (* The type of the LetIn is reduced. Much faster than the previous
1393 solution. Moreover the inferred type is probably very different
1394 from the expected one.
1395 (CicReduction.whd context
1396 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t)))
1398 (* One-step LetIn reduction. Even faster than the previous solution.
1399 Moreover the inferred type is closer to the expected one. *)
1400 (CicSubstitution.subst s
1401 (type_of_aux ((Some (n,(C.Def (s,Some ty))))::context) t))
1402 | C.Appl (he::tl) when List.length tl > 0 ->
1403 let hetype = type_of_aux context he
1404 and tlbody_and_type = List.map (fun x -> (x, type_of_aux context x)) tl in
1405 eat_prods context hetype tlbody_and_type
1406 | C.Appl _ -> raise (TypeCheckerFailure (NotWellTyped "Appl: no arguments"))
1407 | C.Const (uri,exp_named_subst) ->
1409 check_exp_named_subst context exp_named_subst ;
1411 CicSubstitution.subst_vars exp_named_subst (type_of_constant uri)
1415 | C.MutInd (uri,i,exp_named_subst) ->
1417 check_exp_named_subst context exp_named_subst ;
1419 CicSubstitution.subst_vars exp_named_subst
1420 (type_of_mutual_inductive_defs uri i)
1424 | C.MutConstruct (uri,i,j,exp_named_subst) ->
1425 check_exp_named_subst context exp_named_subst ;
1427 CicSubstitution.subst_vars exp_named_subst
1428 (type_of_mutual_inductive_constr uri i j)
1431 | C.MutCase (uri,i,outtype,term,pl) ->
1432 let outsort = type_of_aux context outtype in
1433 let (need_dummy, k) =
1434 let rec guess_args context t =
1435 match CicReduction.whd context t with
1436 C.Sort _ -> (true, 0)
1437 | C.Prod (name, s, t) ->
1438 let (b, n) = guess_args ((Some (name,(C.Decl s)))::context) t in
1440 (* last prod before sort *)
1441 match CicReduction.whd context s with
1442 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1443 C.MutInd (uri',i',_) when U.eq uri' uri && i' = i ->
1445 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1446 | C.Appl ((C.MutInd (uri',i',_)) :: _)
1447 when U.eq uri' uri && i' = i -> (false, 1)
1453 (TypeCheckerFailure (NotWellTyped "MutCase: outtype ill-formed"))
1455 (*CSC whd non serve dopo type_of_aux ? *)
1456 let (b, k) = guess_args context outsort in
1457 if not b then (b, k - 1) else (b, k)
1459 let (parameters, arguments, exp_named_subst) =
1460 match R.whd context (type_of_aux context term) with
1461 (*CSC manca il caso dei CAST *)
1462 (*CSC: ma servono i parametri (uri,i)? Se si', perche' non serve anche il *)
1463 (*CSC: parametro exp_named_subst? Se no, perche' non li togliamo? *)
1464 (*CSC: Hint: nella DTD servono per gli stylesheet. *)
1465 C.MutInd (uri',i',exp_named_subst) as typ ->
1466 if U.eq uri uri' && i = i' then ([],[],exp_named_subst)
1467 else raise (TypeCheckerFailure
1468 (NotWellTyped ("MutCase: the term is of type " ^
1470 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1471 string_of_int i ^ "{_}")))
1472 | C.Appl ((C.MutInd (uri',i',exp_named_subst) as typ):: tl) ->
1473 if U.eq uri uri' && i = i' then
1475 split tl (List.length tl - k)
1476 in params,args,exp_named_subst
1477 else raise (TypeCheckerFailure (NotWellTyped
1478 ("MutCase: the term is of type " ^
1480 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1481 string_of_int i ^ "{_}")))
1482 | _ -> raise (TypeCheckerFailure
1483 (NotWellTyped "MutCase: the term is not an inductive one"))
1485 (* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
1486 let sort_of_ind_type =
1487 if parameters = [] then
1488 C.MutInd (uri,i,exp_named_subst)
1490 C.Appl ((C.MutInd (uri,i,exp_named_subst))::parameters)
1492 if not (check_allowed_sort_elimination context uri i need_dummy
1493 sort_of_ind_type (type_of_aux context sort_of_ind_type) outsort)
1497 (NotWellTyped "MutCase: not allowed sort elimination")) ;
1499 (* let's check if the type of branches are right *)
1501 match CicEnvironment.get_cooked_obj ~trust:false uri with
1502 C.InductiveDefinition (_,_,parsno) -> parsno
1506 (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri)))
1508 let (_,branches_ok) =
1512 if parameters = [] then
1513 (C.MutConstruct (uri,i,j,exp_named_subst))
1515 (C.Appl (C.MutConstruct (uri,i,j,exp_named_subst)::parameters))
1522 R.are_convertible context (type_of_aux context p)
1523 (type_of_branch context parsno need_dummy outtype cons
1524 (type_of_aux context cons))
1525 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
1529 if not branches_ok then
1532 (NotWellTyped "MutCase: wrong type of a branch")) ;
1534 if not need_dummy then
1535 C.Appl ((outtype::arguments)@[term])
1536 else if arguments = [] then
1539 C.Appl (outtype::arguments)
1541 let types_times_kl =
1545 let _ = type_of_aux context ty in
1546 (Some (C.Name n,(C.Decl ty)),k)) fl)
1548 let (types,kl) = List.split types_times_kl in
1549 let len = List.length types in
1551 (fun (name,x,ty,bo) ->
1553 (R.are_convertible (types@context) (type_of_aux (types@context) bo)
1554 (CicSubstitution.lift len ty))
1557 let (m, eaten, context') =
1558 eat_lambdas (types @ context) (x + 1) bo
1560 (*let's control the guarded by destructors conditions D{f,k,x,M}*)
1563 (guarded_by_destructors context' eaten (len + eaten) kl 1 [] m)
1567 (NotWellTyped "Fix: not guarded by destructors"))
1570 raise (TypeCheckerFailure (NotWellTyped "Fix: ill-typed bodies"))
1573 (*CSC: controlli mancanti solo su D{f,k,x,M} *)
1574 let (_,_,ty,_) = List.nth fl i in
1581 let _ = type_of_aux context ty in Some (C.Name n,(C.Decl ty))) fl)
1583 let len = List.length types in
1587 (R.are_convertible (types @ context)
1588 (type_of_aux (types @ context) bo) (CicSubstitution.lift len ty))
1591 (* let's control that the returned type is coinductive *)
1592 match returns_a_coinductive context ty with
1596 (NotWellTyped "CoFix: does not return a coinductive type"))
1598 (*let's control the guarded by constructors conditions C{f,M}*)
1601 (guarded_by_constructors (types @ context) 0 len false bo
1606 (NotWellTyped "CoFix: not guarded by constructors"))
1611 (NotWellTyped "CoFix: ill-typed bodies"))
1614 let (_,ty,_) = List.nth fl i in
1617 and check_exp_named_subst context =
1618 let rec check_exp_named_subst_aux substs =
1621 | ((uri,t) as subst)::tl ->
1623 CicSubstitution.subst_vars substs (type_of_variable uri) in
1624 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1625 Cic.Variable (_,Some bo,_,_) ->
1629 "A variable with a body can not be explicit substituted"))
1630 | Cic.Variable (_,None,_,_) -> ()
1634 (WrongUriToVariable (UriManager.string_of_uri uri)))
1636 let typeoft = type_of_aux context t in
1637 if CicReduction.are_convertible context typeoft typeofvar then
1638 check_exp_named_subst_aux (substs@[subst]) tl
1641 CicReduction.fdebug := 0 ;
1642 ignore (CicReduction.are_convertible context typeoft typeofvar) ;
1644 debug typeoft [typeofvar] ;
1647 (NotWellTyped "Wrong Explicit Named Substitution"))
1650 check_exp_named_subst_aux []
1652 and sort_of_prod context (name,s) (t1, t2) =
1653 let module C = Cic in
1654 let t1' = CicReduction.whd context t1 in
1655 let t2' = CicReduction.whd ((Some (name,C.Decl s))::context) t2 in
1656 match (t1', t2') with
1657 (C.Sort s1, C.Sort s2)
1658 when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) -> (* different from Coq manual!!! *)
1660 | (C.Sort s1, C.Sort s2) -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1665 ("Prod: sort1= " ^ CicPp.ppterm t1' ^ " ; sort2= "^ CicPp.ppterm t2')))
1667 and eat_prods context hetype =
1668 (*CSC: siamo sicuri che le are_convertible non lavorino con termini non *)
1672 | (hete, hety)::tl ->
1673 (match (CicReduction.whd context hetype) with
1675 if CicReduction.are_convertible context s hety then
1676 (CicReduction.fdebug := -1 ;
1677 eat_prods context (CicSubstitution.subst hete t) tl
1681 CicReduction.fdebug := 0 ;
1682 ignore (CicReduction.are_convertible context s hety) ;
1686 (TypeCheckerFailure (NotWellTyped "Appl: wrong parameter-type"))
1688 | _ -> raise (TypeCheckerFailure (NotWellTyped "Appl: wrong Prod-type"))
1691 and returns_a_coinductive context ty =
1692 let module C = Cic in
1693 match CicReduction.whd context ty with
1694 C.MutInd (uri,i,_) ->
1695 (*CSC: definire una funzioncina per questo codice sempre replicato *)
1696 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1697 C.InductiveDefinition (itl,_,_) ->
1698 let (_,is_inductive,_,_) = List.nth itl i in
1699 if is_inductive then None else (Some uri)
1702 (TypeCheckerFailure (WrongUriToMutualInductiveDefinitions
1703 (UriManager.string_of_uri uri)))
1705 | C.Appl ((C.MutInd (uri,i,_))::_) ->
1706 (match CicEnvironment.get_obj uri with
1707 C.InductiveDefinition (itl,_,_) ->
1708 let (_,is_inductive,_,_) = List.nth itl i in
1709 if is_inductive then None else (Some uri)
1713 (WrongUriToMutualInductiveDefinitions
1714 (UriManager.string_of_uri uri)))
1716 | C.Prod (n,so,de) ->
1717 returns_a_coinductive ((Some (n,C.Decl so))::context) de
1722 prerr_endline ("INIZIO TYPE_OF_AUX " ^ CicPp.ppterm t) ; flush stderr ;
1725 type_of_aux context t
1727 in prerr_endline "FINE TYPE_OF_AUX" ; flush stderr ; res
1730 (* is a small constructor? *)
1731 (*CSC: ottimizzare calcolando staticamente *)
1732 and is_small context paramsno c =
1733 let rec is_small_aux context c =
1734 let module C = Cic in
1735 match CicReduction.whd context c with
1737 (*CSC: [] is an empty metasenv. Is it correct? *)
1738 let s = type_of_aux' [] context so in
1739 (s = C.Sort C.Prop || s = C.Sort C.Set || s = C.Sort C.CProp) &&
1740 is_small_aux ((Some (n,(C.Decl so)))::context) de
1741 | _ -> true (*CSC: we trust the type-checker *)
1743 let (context',dx) = split_prods context paramsno c in
1744 is_small_aux context' dx
1748 prerr_endline ("INIZIO TYPE_OF_AUX' " ^ CicPp.ppterm t) ; flush stderr ;
1751 type_of_aux' [] [] t
1753 in prerr_endline "FINE TYPE_OF_AUX'" ; flush stderr ; res
1758 let module C = Cic in
1759 let module R = CicReduction in
1760 let module U = UriManager in
1761 match CicEnvironment.is_type_checked ~trust:false uri with
1762 CicEnvironment.CheckedObj _ -> ()
1763 | CicEnvironment.UncheckedObj uobj ->
1764 (* let's typecheck the uncooked object *)
1765 CicLogger.log (`Start_type_checking uri) ;
1767 C.Constant (_,Some te,ty,_) ->
1768 let _ = type_of ty in
1769 if not (R.are_convertible [] (type_of te ) ty) then
1772 (NotWellTyped ("Constant " ^ (U.string_of_uri uri))))
1773 | C.Constant (_,None,ty,_) ->
1774 (* only to check that ty is well-typed *)
1775 let _ = type_of ty in ()
1776 | C.CurrentProof (_,conjs,te,ty,_) ->
1779 (fun metasenv ((_,context,ty) as conj) ->
1780 ignore (type_of_aux' metasenv context ty) ;
1784 let _ = type_of_aux' conjs [] ty in
1785 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
1789 (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri))))
1790 | C.Variable (_,bo,ty,_) ->
1791 (* only to check that ty is well-typed *)
1792 let _ = type_of ty in
1796 if not (R.are_convertible [] (type_of bo) ty) then
1799 (NotWellTyped ("Variable" ^ (U.string_of_uri uri))))
1801 | C.InductiveDefinition _ ->
1802 check_mutual_inductive_defs uri uobj
1804 CicEnvironment.set_type_checking_info uri ;
1805 CicLogger.log (`Type_checking_completed uri)