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 (* TODO factorize functions to frequent errors (e.g. "Unknwon mutual inductive
31 exception AssertFailure of string;;
32 exception TypeCheckerFailure of string;;
33 exception SortExpectedMetaFound of string;; (* TODO temp *)
37 let rec debug_aux t i =
39 let module U = UriManager in
40 CicPp.ppobj (C.Variable ("DEBUG", None, t, [])) ^ "\n" ^ i
43 raise (TypeCheckerFailure (List.fold_right debug_aux (t::context) ""))
46 let debug_print = prerr_endline ;;
51 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
53 raise (TypeCheckerFailure "Parameters number < left parameters number")
56 let debrujin_constructor uri number_of_types =
60 C.Rel n as t when n <= k -> t
62 raise (TypeCheckerFailure "unbound variable found in constructor type")
63 | C.Var (uri,exp_named_subst) ->
64 let exp_named_subst' =
65 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
67 C.Var (uri,exp_named_subst')
68 | C.Meta _ -> assert false
70 | C.Implicit as t -> t
71 | C.Cast (te,ty) -> C.Cast (aux k te, aux k ty)
72 | C.Prod (n,s,t) -> C.Prod (n, aux k s, aux (k+1) t)
73 | C.Lambda (n,s,t) -> C.Lambda (n, aux k s, aux (k+1) t)
74 | C.LetIn (n,s,t) -> C.LetIn (n, aux k s, aux (k+1) t)
75 | C.Appl l -> C.Appl (List.map (aux k) l)
76 | C.Const (uri,exp_named_subst) ->
77 let exp_named_subst' =
78 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
80 C.Const (uri,exp_named_subst')
81 | C.MutInd (uri',tyno,exp_named_subst) when UriManager.eq uri uri' ->
82 if exp_named_subst != [] then
83 raise (TypeCheckerFailure
84 ("non-empty explicit named substitution is applied to "^
85 "a mutual inductive type which is being defined")) ;
86 C.Rel (k + number_of_types - tyno) ;
87 | C.MutInd (uri',tyno,exp_named_subst) ->
88 let exp_named_subst' =
89 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
91 C.MutInd (uri',tyno,exp_named_subst')
92 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
93 let exp_named_subst' =
94 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
96 C.MutConstruct (uri,tyno,consno,exp_named_subst')
97 | C.MutCase (sp,i,outty,t,pl) ->
98 C.MutCase (sp, i, aux k outty, aux k t,
101 let len = List.length fl in
104 (fun (name, i, ty, bo) -> (name, i, aux k ty, aux (k+len) bo))
109 let len = List.length fl in
112 (fun (name, ty, bo) -> (name, aux k ty, aux (k+len) bo))
115 C.CoFix (i, liftedfl)
120 exception CicEnvironmentError;;
122 let rec type_of_constant uri =
123 let module C = Cic in
124 let module R = CicReduction in
125 let module U = UriManager in
127 match CicEnvironment.is_type_checked ~trust:true uri with
128 CicEnvironment.CheckedObj cobj -> cobj
129 | CicEnvironment.UncheckedObj uobj ->
130 CicLogger.log (`Start_type_checking uri) ;
131 (* let's typecheck the uncooked obj *)
133 C.Constant (_,Some te,ty,_) ->
134 let _ = type_of ty in
135 let type_of_te = type_of te in
136 if not (R.are_convertible [] type_of_te ty) then
137 raise (TypeCheckerFailure (sprintf
138 "the constant %s is not well typed because the type %s of the body is not convertible to the declared type %s"
139 (U.string_of_uri uri) (CicPp.ppterm type_of_te)
141 | C.Constant (_,None,ty,_) ->
142 (* only to check that ty is well-typed *)
143 let _ = type_of ty in ()
144 | C.CurrentProof (_,conjs,te,ty,_) ->
147 (fun metasenv ((_,context,ty) as conj) ->
148 ignore (type_of_aux' metasenv context ty) ;
152 let _ = type_of_aux' conjs [] ty in
153 let type_of_te = type_of_aux' conjs [] te in
154 if not (R.are_convertible [] type_of_te ty) then
155 raise (TypeCheckerFailure (sprintf
156 "the current proof %s is not well typed because the type %s of the body is not convertible to the declared type %s"
157 (U.string_of_uri uri) (CicPp.ppterm type_of_te)
160 raise (TypeCheckerFailure
161 ("Unknown constant:" ^ U.string_of_uri uri))
163 CicEnvironment.set_type_checking_info uri ;
164 CicLogger.log (`Type_checking_completed uri) ;
165 match CicEnvironment.is_type_checked ~trust:false uri with
166 CicEnvironment.CheckedObj cobj -> cobj
167 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
170 C.Constant (_,_,ty,_) -> ty
171 | C.CurrentProof (_,_,_,ty,_) -> ty
173 raise (TypeCheckerFailure ("Unknown constant:" ^ U.string_of_uri uri))
175 and type_of_variable uri =
176 let module C = Cic in
177 let module R = CicReduction in
178 let module U = UriManager in
179 (* 0 because a variable is never cooked => no partial cooking at one level *)
180 match CicEnvironment.is_type_checked ~trust:true uri with
181 CicEnvironment.CheckedObj (C.Variable (_,_,ty,_)) -> ty
182 | CicEnvironment.UncheckedObj (C.Variable (_,bo,ty,_)) ->
183 CicLogger.log (`Start_type_checking uri) ;
184 (* only to check that ty is well-typed *)
185 let _ = type_of ty in
189 if not (R.are_convertible [] (type_of bo) ty) then
190 raise (TypeCheckerFailure
191 ("Unknown variable:" ^ U.string_of_uri uri))
193 CicEnvironment.set_type_checking_info uri ;
194 CicLogger.log (`Type_checking_completed uri) ;
197 raise (TypeCheckerFailure ("Unknown variable:" ^ U.string_of_uri uri))
199 and does_not_occur context n nn te =
200 let module C = Cic in
201 (*CSC: whd sembra essere superflua perche' un caso in cui l'occorrenza *)
202 (*CSC: venga mangiata durante la whd sembra presentare problemi di *)
204 match CicReduction.whd context te with
205 C.Rel m when m > n && m <= nn -> false
211 does_not_occur context n nn te && does_not_occur context n nn ty
212 | C.Prod (name,so,dest) ->
213 does_not_occur context n nn so &&
214 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1)
216 | C.Lambda (name,so,dest) ->
217 does_not_occur context n nn so &&
218 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1)
220 | C.LetIn (name,so,dest) ->
221 does_not_occur context n nn so &&
222 does_not_occur ((Some (name,(C.Def (so,None))))::context)
223 (n + 1) (nn + 1) dest
225 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
226 | C.Var (_,exp_named_subst)
227 | C.Const (_,exp_named_subst)
228 | C.MutInd (_,_,exp_named_subst)
229 | C.MutConstruct (_,_,_,exp_named_subst) ->
230 List.fold_right (fun (_,x) i -> i && does_not_occur context n nn x)
232 | C.MutCase (_,_,out,te,pl) ->
233 does_not_occur context n nn out && does_not_occur context n nn te &&
234 List.fold_right (fun x i -> i && does_not_occur context n nn x) pl true
236 let len = List.length fl in
237 let n_plus_len = n + len in
238 let nn_plus_len = nn + len in
240 List.map (fun (n,_,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
243 (fun (_,_,ty,bo) i ->
244 i && does_not_occur context n nn ty &&
245 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
248 let len = List.length fl in
249 let n_plus_len = n + len in
250 let nn_plus_len = nn + len in
252 List.map (fun (n,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
256 i && does_not_occur context n nn ty &&
257 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
260 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
261 (*CSC questa funzione e' simile alla are_all_occurrences_positive, ma fa *)
262 (*CSC dei controlli leggermente diversi. Viene invocata solamente dalla *)
263 (*CSC strictly_positive *)
264 (*CSC definizione (giusta???) tratta dalla mail di Hugo ;-) *)
265 and weakly_positive context n nn uri te =
266 let module C = Cic in
267 (*CSC: Che schifo! Bisogna capire meglio e trovare una soluzione ragionevole!*)
269 C.MutInd (UriManager.uri_of_string "cic:/Coq/Init/Datatypes/nat.ind",0,[])
271 (*CSC mettere in cicSubstitution *)
272 let rec subst_inductive_type_with_dummy_mutind =
274 C.MutInd (uri',0,_) when UriManager.eq uri' uri ->
276 | C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri ->
278 | C.Cast (te,ty) -> subst_inductive_type_with_dummy_mutind te
279 | C.Prod (name,so,ta) ->
280 C.Prod (name, subst_inductive_type_with_dummy_mutind so,
281 subst_inductive_type_with_dummy_mutind ta)
282 | C.Lambda (name,so,ta) ->
283 C.Lambda (name, subst_inductive_type_with_dummy_mutind so,
284 subst_inductive_type_with_dummy_mutind ta)
286 C.Appl (List.map subst_inductive_type_with_dummy_mutind tl)
287 | C.MutCase (uri,i,outtype,term,pl) ->
289 subst_inductive_type_with_dummy_mutind outtype,
290 subst_inductive_type_with_dummy_mutind term,
291 List.map subst_inductive_type_with_dummy_mutind pl)
293 C.Fix (i,List.map (fun (name,i,ty,bo) -> (name,i,
294 subst_inductive_type_with_dummy_mutind ty,
295 subst_inductive_type_with_dummy_mutind bo)) fl)
297 C.CoFix (i,List.map (fun (name,ty,bo) -> (name,
298 subst_inductive_type_with_dummy_mutind ty,
299 subst_inductive_type_with_dummy_mutind bo)) fl)
300 | C.Const (uri,exp_named_subst) ->
301 let exp_named_subst' =
303 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
306 C.Const (uri,exp_named_subst')
307 | C.MutInd (uri,typeno,exp_named_subst) ->
308 let exp_named_subst' =
310 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
313 C.MutInd (uri,typeno,exp_named_subst')
314 | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
315 let exp_named_subst' =
317 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
320 C.MutConstruct (uri,typeno,consno,exp_named_subst')
323 match CicReduction.whd context te with
324 C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri -> true
325 | C.MutInd (uri',0,_) when UriManager.eq uri' uri -> true
326 | C.Prod (C.Anonymous,source,dest) ->
327 strictly_positive context n nn
328 (subst_inductive_type_with_dummy_mutind source) &&
329 weakly_positive ((Some (C.Anonymous,(C.Decl source)))::context)
330 (n + 1) (nn + 1) uri dest
331 | C.Prod (name,source,dest) when
332 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
333 (* dummy abstraction, so we behave as in the anonimous case *)
334 strictly_positive context n nn
335 (subst_inductive_type_with_dummy_mutind source) &&
336 weakly_positive ((Some (name,(C.Decl source)))::context)
337 (n + 1) (nn + 1) uri dest
338 | C.Prod (name,source,dest) ->
339 does_not_occur context n nn
340 (subst_inductive_type_with_dummy_mutind source)&&
341 weakly_positive ((Some (name,(C.Decl source)))::context)
342 (n + 1) (nn + 1) uri dest
344 raise (TypeCheckerFailure "Malformed inductive constructor type")
346 (* instantiate_parameters ps (x1:T1)...(xn:Tn)C *)
347 (* returns ((x_|ps|:T_|ps|)...(xn:Tn)C){ps_1 / x1 ; ... ; ps_|ps| / x_|ps|} *)
348 and instantiate_parameters params c =
349 let module C = Cic in
350 match (c,params) with
352 | (C.Prod (_,_,ta), he::tl) ->
353 instantiate_parameters tl
354 (CicSubstitution.subst he ta)
355 | (C.Cast (te,_), _) -> instantiate_parameters params te
356 | (t,l) -> raise (AssertFailure "1")
358 and strictly_positive context n nn te =
359 let module C = Cic in
360 let module U = UriManager in
361 match CicReduction.whd context te with
364 (*CSC: bisogna controllare ty????*)
365 strictly_positive context n nn te
366 | C.Prod (name,so,ta) ->
367 does_not_occur context n nn so &&
368 strictly_positive ((Some (name,(C.Decl so)))::context) (n+1) (nn+1) ta
369 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
370 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
371 | C.Appl ((C.MutInd (uri,i,exp_named_subst))::tl) ->
372 let (ok,paramsno,ity,cl,name) =
373 match CicEnvironment.get_obj uri with
374 C.InductiveDefinition (tl,_,paramsno) ->
375 let (name,_,ity,cl) = List.nth tl i in
376 (List.length tl = 1, paramsno, ity, cl, name)
378 raise (TypeCheckerFailure
379 ("Unknown inductive type:" ^ U.string_of_uri uri))
381 let (params,arguments) = split tl paramsno in
382 let lifted_params = List.map (CicSubstitution.lift 1) params in
386 instantiate_parameters lifted_params
387 (CicSubstitution.subst_vars exp_named_subst te)
392 (fun x i -> i && does_not_occur context n nn x)
394 (*CSC: MEGAPATCH3 (sara' quella giusta?)*)
399 ((Some (C.Name name,(Cic.Decl ity)))::context) (n+1) (nn+1) uri
402 | t -> does_not_occur context n nn t
404 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
405 and are_all_occurrences_positive context uri indparamsno i n nn te =
406 let module C = Cic in
407 match CicReduction.whd context te with
408 C.Appl ((C.Rel m)::tl) when m = i ->
409 (*CSC: riscrivere fermandosi a 0 *)
410 (* let's check if the inductive type is applied at least to *)
411 (* indparamsno parameters *)
417 match CicReduction.whd context x with
418 C.Rel m when m = n - (indparamsno - k) -> k - 1
420 raise (TypeCheckerFailure
421 ("Non-positive occurence in mutual inductive definition(s) " ^
422 UriManager.string_of_uri uri))
426 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
428 raise (TypeCheckerFailure
429 ("Non-positive occurence in mutual inductive definition(s) " ^
430 UriManager.string_of_uri uri))
431 | C.Rel m when m = i ->
432 if indparamsno = 0 then
435 raise (TypeCheckerFailure
436 ("Non-positive occurence in mutual inductive definition(s) " ^
437 UriManager.string_of_uri uri))
438 | C.Prod (C.Anonymous,source,dest) ->
439 strictly_positive context n nn source &&
440 are_all_occurrences_positive
441 ((Some (C.Anonymous,(C.Decl source)))::context) uri indparamsno
442 (i+1) (n + 1) (nn + 1) dest
443 | C.Prod (name,source,dest) when
444 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
445 (* dummy abstraction, so we behave as in the anonimous case *)
446 strictly_positive context n nn source &&
447 are_all_occurrences_positive
448 ((Some (name,(C.Decl source)))::context) uri indparamsno
449 (i+1) (n + 1) (nn + 1) dest
450 | C.Prod (name,source,dest) ->
451 does_not_occur context n nn source &&
452 are_all_occurrences_positive ((Some (name,(C.Decl source)))::context)
453 uri indparamsno (i+1) (n + 1) (nn + 1) dest
456 (TypeCheckerFailure ("Malformed inductive constructor type " ^
457 (UriManager.string_of_uri uri)))
459 (* Main function to checks the correctness of a mutual *)
460 (* inductive block definition. This is the function *)
461 (* exported to the proof-engine. *)
462 and typecheck_mutual_inductive_defs uri (itl,_,indparamsno) =
463 let module U = UriManager in
464 (* let's check if the arity of the inductive types are well *)
466 List.iter (fun (_,_,x,_) -> let _ = type_of x in ()) itl ;
468 (* let's check if the types of the inductive constructors *)
469 (* are well formed. *)
470 (* In order not to use type_of_aux we put the types of the *)
471 (* mutual inductive types at the head of the types of the *)
472 (* constructors using Prods *)
473 let len = List.length itl in
475 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl in
481 let debrujinedte = debrujin_constructor uri len te in
484 (fun (name,_,ty,_) i -> Cic.Prod (Cic.Name name, ty, i))
487 let _ = type_of augmented_term in
488 (* let's check also the positivity conditions *)
491 (are_all_occurrences_positive tys uri indparamsno i 0 len
495 (TypeCheckerFailure ("Non positive occurence in " ^
496 U.string_of_uri uri))
503 (* Main function to checks the correctness of a mutual *)
504 (* inductive block definition. *)
505 and check_mutual_inductive_defs uri =
507 Cic.InductiveDefinition (itl, params, indparamsno) ->
508 typecheck_mutual_inductive_defs uri (itl,params,indparamsno)
510 raise (TypeCheckerFailure ("Unknown mutual inductive definition:" ^
511 UriManager.string_of_uri uri))
513 and type_of_mutual_inductive_defs uri i =
514 let module C = Cic in
515 let module R = CicReduction in
516 let module U = UriManager in
518 match CicEnvironment.is_type_checked ~trust:true uri with
519 CicEnvironment.CheckedObj cobj -> cobj
520 | CicEnvironment.UncheckedObj uobj ->
521 CicLogger.log (`Start_type_checking uri) ;
522 check_mutual_inductive_defs uri uobj ;
523 CicEnvironment.set_type_checking_info uri ;
524 CicLogger.log (`Type_checking_completed uri) ;
525 (match CicEnvironment.is_type_checked ~trust:false uri with
526 CicEnvironment.CheckedObj cobj -> cobj
527 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
531 C.InductiveDefinition (dl,_,_) ->
532 let (_,_,arity,_) = List.nth dl i in
535 raise (TypeCheckerFailure ("Unknown mutual inductive definition:" ^
536 U.string_of_uri uri))
538 and type_of_mutual_inductive_constr uri i j =
539 let module C = Cic in
540 let module R = CicReduction in
541 let module U = UriManager in
543 match CicEnvironment.is_type_checked ~trust:true uri with
544 CicEnvironment.CheckedObj cobj -> cobj
545 | CicEnvironment.UncheckedObj uobj ->
546 CicLogger.log (`Start_type_checking uri) ;
547 check_mutual_inductive_defs uri uobj ;
548 CicEnvironment.set_type_checking_info uri ;
549 CicLogger.log (`Type_checking_completed uri) ;
550 (match CicEnvironment.is_type_checked ~trust:false uri with
551 CicEnvironment.CheckedObj cobj -> cobj
552 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
556 C.InductiveDefinition (dl,_,_) ->
557 let (_,_,_,cl) = List.nth dl i in
558 let (_,ty) = List.nth cl (j-1) in
561 raise (TypeCheckerFailure ("Unknown mutual inductive definition:" ^
562 UriManager.string_of_uri uri))
564 and recursive_args context n nn te =
565 let module C = Cic in
566 match CicReduction.whd context te with
572 | C.Cast _ (*CSC ??? *) ->
573 raise (AssertFailure "3") (* due to type-checking *)
574 | C.Prod (name,so,de) ->
575 (not (does_not_occur context n nn so)) ::
576 (recursive_args ((Some (name,(C.Decl so)))::context) (n+1) (nn + 1) de)
579 raise (AssertFailure "4") (* due to type-checking *)
581 | C.Const _ -> raise (AssertFailure "5")
586 | C.CoFix _ -> raise (AssertFailure "6") (* due to type-checking *)
588 and get_new_safes context p c rl safes n nn x =
589 let module C = Cic in
590 let module U = UriManager in
591 let module R = CicReduction in
592 match (R.whd context c, R.whd context p, rl) with
593 (C.Prod (_,so,ta1), C.Lambda (name,_,ta2), b::tl) ->
594 (* we are sure that the two sources are convertible because we *)
595 (* have just checked this. So let's go along ... *)
597 List.map (fun x -> x + 1) safes
600 if b then 1::safes' else safes'
602 get_new_safes ((Some (name,(C.Decl so)))::context)
603 ta2 ta1 tl safes'' (n+1) (nn+1) (x+1)
604 | (C.Prod _, (C.MutConstruct _ as e), _)
605 | (C.Prod _, (C.Rel _ as e), _)
606 | (C.MutInd _, e, [])
607 | (C.Appl _, e, []) -> (e,safes,n,nn,x,context)
609 (* CSC: If the next exception is raised, it just means that *)
610 (* CSC: the proof-assistant allows to use very strange things *)
611 (* CSC: as a branch of a case whose type is a Prod. In *)
612 (* CSC: particular, this means that a new (C.Prod, x,_) case *)
613 (* CSC: must be considered in this match. (e.g. x = MutCase) *)
614 raise (AssertFailure "7")
616 and split_prods context n te =
617 let module C = Cic in
618 let module R = CicReduction in
619 match (n, R.whd context te) with
621 | (n, C.Prod (name,so,ta)) when n > 0 ->
622 split_prods ((Some (name,(C.Decl so)))::context) (n - 1) ta
623 | (_, _) -> raise (AssertFailure "8")
625 and eat_lambdas context n te =
626 let module C = Cic in
627 let module R = CicReduction in
628 match (n, R.whd context te) with
629 (0, _) -> (te, 0, context)
630 | (n, C.Lambda (name,so,ta)) when n > 0 ->
631 let (te, k, context') =
632 eat_lambdas ((Some (name,(C.Decl so)))::context) (n - 1) ta
634 (te, k + 1, context')
636 raise (AssertFailure (sprintf "9 (%d, %s)" n (CicPp.ppterm te)))
638 (*CSC: Tutto quello che segue e' l'intuzione di luca ;-) *)
639 and check_is_really_smaller_arg context n nn kl x safes te =
640 (*CSC: forse la whd si puo' fare solo quando serve veramente. *)
641 (*CSC: cfr guarded_by_destructors *)
642 let module C = Cic in
643 let module U = UriManager in
644 match CicReduction.whd context te with
645 C.Rel m when List.mem m safes -> true
652 (* | C.Cast (te,ty) ->
653 check_is_really_smaller_arg n nn kl x safes te &&
654 check_is_really_smaller_arg n nn kl x safes ty*)
655 (* | C.Prod (_,so,ta) ->
656 check_is_really_smaller_arg n nn kl x safes so &&
657 check_is_really_smaller_arg (n+1) (nn+1) kl (x+1)
658 (List.map (fun x -> x + 1) safes) ta*)
659 | C.Prod _ -> raise (AssertFailure "10")
660 | C.Lambda (name,so,ta) ->
661 check_is_really_smaller_arg context n nn kl x safes so &&
662 check_is_really_smaller_arg ((Some (name,(C.Decl so)))::context)
663 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
664 | C.LetIn (name,so,ta) ->
665 check_is_really_smaller_arg context n nn kl x safes so &&
666 check_is_really_smaller_arg ((Some (name,(C.Def (so,None))))::context)
667 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
669 (*CSC: sulla coda ci vogliono dei controlli? secondo noi no, ma *)
670 (*CSC: solo perche' non abbiamo trovato controesempi *)
671 check_is_really_smaller_arg context n nn kl x safes he
672 | C.Appl [] -> raise (AssertFailure "11")
674 | C.MutInd _ -> raise (AssertFailure "12")
675 | C.MutConstruct _ -> false
676 | C.MutCase (uri,i,outtype,term,pl) ->
678 C.Rel m when List.mem m safes || m = x ->
679 let (tys,len,isinductive,paramsno,cl) =
680 match CicEnvironment.get_obj uri with
681 C.InductiveDefinition (tl,_,paramsno) ->
684 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) tl
686 let (_,isinductive,_,cl) = List.nth tl i in
690 (id, snd (split_prods tys paramsno ty))) cl
692 (tys,List.length tl,isinductive,paramsno,cl')
694 raise (TypeCheckerFailure
695 ("Unknown mutual inductive definition:" ^
696 UriManager.string_of_uri uri))
698 if not isinductive then
701 i && check_is_really_smaller_arg context n nn kl x safes p)
707 let debrujinedte = debrujin_constructor uri len c in
708 recursive_args tys 0 len debrujinedte
710 let (e,safes',n',nn',x',context') =
711 get_new_safes context p c rl' safes n nn x
714 check_is_really_smaller_arg context' n' nn' kl x' safes' e
715 ) (List.combine pl cl) true
716 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
717 let (tys,len,isinductive,paramsno,cl) =
718 match CicEnvironment.get_obj uri with
719 C.InductiveDefinition (tl,_,paramsno) ->
720 let (_,isinductive,_,cl) = List.nth tl i in
722 List.map (fun (n,_,ty,_) ->
723 Some(Cic.Name n,(Cic.Decl ty))) tl
728 (id, snd (split_prods tys paramsno ty))) cl
730 (tys,List.length tl,isinductive,paramsno,cl')
732 raise (TypeCheckerFailure
733 ("Unknown mutual inductive definition:" ^
734 UriManager.string_of_uri uri))
736 if not isinductive then
739 i && check_is_really_smaller_arg context n nn kl x safes p)
742 (*CSC: supponiamo come prima che nessun controllo sia necessario*)
743 (*CSC: sugli argomenti di una applicazione *)
747 let debrujinedte = debrujin_constructor uri len c in
748 recursive_args tys 0 len debrujinedte
750 let (e, safes',n',nn',x',context') =
751 get_new_safes context p c rl' safes n nn x
754 check_is_really_smaller_arg context' n' nn' kl x' safes' e
755 ) (List.combine pl cl) true
759 i && check_is_really_smaller_arg context n nn kl x safes p
763 let len = List.length fl in
764 let n_plus_len = n + len
765 and nn_plus_len = nn + len
766 and x_plus_len = x + len
767 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
768 and safes' = List.map (fun x -> x + len) safes in
770 (fun (_,_,ty,bo) i ->
772 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
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
785 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
789 and guarded_by_destructors context n nn kl x safes =
790 let module C = Cic in
791 let module U = UriManager in
793 C.Rel m when m > n && m <= nn -> false
795 (match List.nth context (n-1) with
796 Some (_,C.Decl _) -> true
797 | Some (_,C.Def (bo,_)) ->
798 guarded_by_destructors context n nn kl x safes bo
799 | None -> raise (TypeCheckerFailure "Reference to deleted hypothesis")
805 guarded_by_destructors context n nn kl x safes te &&
806 guarded_by_destructors context n nn kl x safes ty
807 | C.Prod (name,so,ta) ->
808 guarded_by_destructors context n nn kl x safes so &&
809 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
810 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
811 | C.Lambda (name,so,ta) ->
812 guarded_by_destructors context n nn kl x safes so &&
813 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
814 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
815 | C.LetIn (name,so,ta) ->
816 guarded_by_destructors context n nn kl x safes so &&
817 guarded_by_destructors ((Some (name,(C.Def (so,None))))::context)
818 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
819 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
820 let k = List.nth kl (m - n - 1) in
821 if not (List.length tl > k) then false
825 i && guarded_by_destructors context n nn kl x safes param
827 check_is_really_smaller_arg context n nn kl x safes (List.nth tl k)
830 (fun t i -> i && guarded_by_destructors context n nn kl x safes t)
832 | C.Var (_,exp_named_subst)
833 | C.Const (_,exp_named_subst)
834 | C.MutInd (_,_,exp_named_subst)
835 | C.MutConstruct (_,_,_,exp_named_subst) ->
837 (fun (_,t) i -> i && guarded_by_destructors context n nn kl x safes t)
839 | C.MutCase (uri,i,outtype,term,pl) ->
841 C.Rel m when List.mem m safes || m = x ->
842 let (tys,len,isinductive,paramsno,cl) =
843 match CicEnvironment.get_obj uri with
844 C.InductiveDefinition (tl,_,paramsno) ->
845 let (_,isinductive,_,cl) = List.nth tl i in
847 List.map (fun (n,_,ty,_) ->
848 Some(Cic.Name n,(Cic.Decl ty))) tl
853 (id, snd (split_prods tys paramsno ty))) cl
855 (tys,List.length tl,isinductive,paramsno,cl')
857 raise (TypeCheckerFailure
858 ("Unknown mutual inductive definition:" ^
859 UriManager.string_of_uri uri))
861 if not isinductive then
862 guarded_by_destructors context n nn kl x safes outtype &&
863 guarded_by_destructors context n nn kl x safes term &&
864 (*CSC: manca ??? il controllo sul tipo di term? *)
867 i && guarded_by_destructors context n nn kl x safes p)
870 guarded_by_destructors context n nn kl x safes outtype &&
871 (*CSC: manca ??? il controllo sul tipo di term? *)
875 let debrujinedte = debrujin_constructor uri len c in
876 recursive_args tys 0 len debrujinedte
878 let (e,safes',n',nn',x',context') =
879 get_new_safes context p c rl' safes n nn x
882 guarded_by_destructors context' n' nn' kl x' safes' e
883 ) (List.combine pl cl) true
884 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
885 let (tys,len,isinductive,paramsno,cl) =
886 match CicEnvironment.get_obj uri with
887 C.InductiveDefinition (tl,_,paramsno) ->
888 let (_,isinductive,_,cl) = List.nth tl i in
891 (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
896 (id, snd (split_prods tys paramsno ty))) cl
898 (tys,List.length tl,isinductive,paramsno,cl')
900 raise (TypeCheckerFailure
901 ("Unknown mutual inductive definition:" ^
902 UriManager.string_of_uri uri))
904 if not isinductive then
905 guarded_by_destructors context n nn kl x safes outtype &&
906 guarded_by_destructors context n nn kl x safes term &&
907 (*CSC: manca ??? il controllo sul tipo di term? *)
910 i && guarded_by_destructors context n nn kl x safes p)
913 guarded_by_destructors context n nn kl x safes outtype &&
914 (*CSC: manca ??? il controllo sul tipo di term? *)
917 i && guarded_by_destructors context n nn kl x safes t)
922 let debrujinedte = debrujin_constructor uri len c in
923 recursive_args tys 0 len debrujinedte
925 let (e, safes',n',nn',x',context') =
926 get_new_safes context p c rl' safes n nn x
929 guarded_by_destructors context' n' nn' kl x' safes' e
930 ) (List.combine pl cl) true
932 guarded_by_destructors context n nn kl x safes outtype &&
933 guarded_by_destructors context n nn kl x safes term &&
934 (*CSC: manca ??? il controllo sul tipo di term? *)
936 (fun p i -> i && guarded_by_destructors context n nn kl x safes p)
940 let len = List.length fl in
941 let n_plus_len = n + len
942 and nn_plus_len = nn + len
943 and x_plus_len = x + len
944 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
945 and safes' = List.map (fun x -> x + len) safes in
947 (fun (_,_,ty,bo) i ->
948 i && guarded_by_destructors context n nn kl x_plus_len safes' ty &&
949 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
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
962 guarded_by_destructors context n nn kl x_plus_len safes' ty &&
963 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
967 (* the boolean h means already protected *)
968 (* args is the list of arguments the type of the constructor that may be *)
969 (* found in head position must be applied to. *)
970 (*CSC: coInductiveTypeURI non cambia mai di ricorsione in ricorsione *)
971 and guarded_by_constructors context n nn h te args coInductiveTypeURI =
972 let module C = Cic in
973 (*CSC: There is a lot of code replication between the cases X and *)
974 (*CSC: (C.Appl X tl). Maybe it will be better to define a function *)
975 (*CSC: that maps X into (C.Appl X []) when X is not already a C.Appl *)
976 match CicReduction.whd context te with
977 C.Rel m when m > n && m <= nn -> h
985 (* the term has just been type-checked *)
986 raise (AssertFailure "17")
987 | C.Lambda (name,so,de) ->
988 does_not_occur context n nn so &&
989 guarded_by_constructors ((Some (name,(C.Decl so)))::context)
990 (n + 1) (nn + 1) h de args coInductiveTypeURI
991 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
993 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
994 | C.Appl ((C.MutConstruct (uri,i,j,exp_named_subst))::tl) ->
996 match CicEnvironment.get_cooked_obj ~trust:false uri with
997 C.InductiveDefinition (itl,_,_) ->
998 let (_,_,_,cl) = List.nth itl i in
999 let (_,cons) = List.nth cl (j - 1) in
1000 CicSubstitution.subst_vars exp_named_subst cons
1002 raise (TypeCheckerFailure ("Unknown mutual inductive definition:" ^
1003 UriManager.string_of_uri uri))
1005 let rec analyse_branch context ty te =
1006 match CicReduction.whd context ty with
1007 C.Meta _ -> raise (AssertFailure "34")
1011 does_not_occur context n nn te
1014 raise (AssertFailure "24")(* due to type-checking *)
1015 | C.Prod (name,so,de) ->
1016 analyse_branch ((Some (name,(C.Decl so)))::context) de te
1019 raise (AssertFailure "25")(* due to type-checking *)
1020 | C.Appl ((C.MutInd (uri,_,_))::_) as ty
1021 when uri == coInductiveTypeURI ->
1022 guarded_by_constructors context n nn true te [] coInductiveTypeURI
1023 | C.Appl ((C.MutInd (uri,_,_))::_) as ty ->
1024 guarded_by_constructors context n nn true te tl coInductiveTypeURI
1026 does_not_occur context n nn te
1027 | C.Const _ -> raise (AssertFailure "26")
1028 | C.MutInd (uri,_,_) when uri == coInductiveTypeURI ->
1029 guarded_by_constructors context n nn true te [] coInductiveTypeURI
1031 does_not_occur context n nn te
1032 | C.MutConstruct _ -> raise (AssertFailure "27")
1033 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
1034 (*CSC: in head position. *)
1038 raise (AssertFailure "28")(* due to type-checking *)
1040 let rec analyse_instantiated_type context ty l =
1041 match CicReduction.whd context ty with
1047 | C.Cast _ -> raise (AssertFailure "29")(* due to type-checking *)
1048 | C.Prod (name,so,de) ->
1053 analyse_branch context so he &&
1054 analyse_instantiated_type
1055 ((Some (name,(C.Decl so)))::context) de tl
1059 raise (AssertFailure "30")(* due to type-checking *)
1062 (fun i x -> i && does_not_occur context n nn x) true l
1063 | C.Const _ -> raise (AssertFailure "31")
1066 (fun i x -> i && does_not_occur context n nn x) true l
1067 | C.MutConstruct _ -> raise (AssertFailure "32")
1068 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
1069 (*CSC: in head position. *)
1073 raise (AssertFailure "33")(* due to type-checking *)
1075 let rec instantiate_type args consty =
1078 | tlhe::tltl as l ->
1079 let consty' = CicReduction.whd context consty in
1085 let instantiated_de = CicSubstitution.subst he de in
1086 (*CSC: siamo sicuri che non sia troppo forte? *)
1087 does_not_occur context n nn tlhe &
1088 instantiate_type tl instantiated_de tltl
1090 (*CSC:We do not consider backbones with a MutCase, a *)
1091 (*CSC:FixPoint, a CoFixPoint and so on in head position.*)
1092 raise (AssertFailure "23")
1094 | [] -> analyse_instantiated_type context consty' l
1095 (* These are all the other cases *)
1097 instantiate_type args consty tl
1098 | C.Appl ((C.CoFix (_,fl))::tl) ->
1099 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1100 let len = List.length fl in
1101 let n_plus_len = n + len
1102 and nn_plus_len = nn + len
1103 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1104 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1107 i && does_not_occur context n nn ty &&
1108 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1109 args coInductiveTypeURI
1111 | C.Appl ((C.MutCase (_,_,out,te,pl))::tl) ->
1112 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1113 does_not_occur context n nn out &&
1114 does_not_occur context n nn te &&
1118 guarded_by_constructors context n nn h x args coInductiveTypeURI
1121 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
1122 | C.Var (_,exp_named_subst)
1123 | C.Const (_,exp_named_subst) ->
1125 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1126 | C.MutInd _ -> assert false
1127 | C.MutConstruct (_,_,_,exp_named_subst) ->
1129 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1130 | C.MutCase (_,_,out,te,pl) ->
1131 does_not_occur context n nn out &&
1132 does_not_occur context n nn te &&
1136 guarded_by_constructors context n nn h x args coInductiveTypeURI
1139 let len = List.length fl in
1140 let n_plus_len = n + len
1141 and nn_plus_len = nn + len
1142 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1143 and tys = List.map (fun (n,_,ty,_)-> Some (C.Name n,(C.Decl ty))) fl in
1145 (fun (_,_,ty,bo) i ->
1146 i && does_not_occur context n nn ty &&
1147 does_not_occur (tys@context) n_plus_len nn_plus_len bo
1150 let len = List.length fl in
1151 let n_plus_len = n + len
1152 and nn_plus_len = nn + len
1153 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1154 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1157 i && does_not_occur context n nn ty &&
1158 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1159 args coInductiveTypeURI
1162 and check_allowed_sort_elimination context uri i need_dummy ind arity1 arity2 =
1163 let module C = Cic in
1164 let module U = UriManager in
1165 match (CicReduction.whd context arity1, CicReduction.whd context arity2) with
1166 (C.Prod (_,so1,de1), C.Prod (_,so2,de2))
1167 when CicReduction.are_convertible context so1 so2 ->
1168 check_allowed_sort_elimination context uri i need_dummy
1169 (C.Appl [CicSubstitution.lift 1 ind ; C.Rel 1]) de1 de2
1170 | (C.Sort C.Prop, C.Sort C.Prop) when need_dummy -> true
1171 | (C.Sort C.Prop, C.Sort C.Set)
1172 | (C.Sort C.Prop, C.Sort C.CProp)
1173 | (C.Sort C.Prop, C.Sort C.Type) when need_dummy ->
1174 (*CSC: WRONG. MISSING CONDITIONS ON THE ARGUMENTS OF THE CONSTRUTOR *)
1175 (match CicEnvironment.get_obj uri with
1176 C.InductiveDefinition (itl,_,_) ->
1177 let (_,_,_,cl) = List.nth itl i in
1178 (* is a singleton definition or the empty proposition? *)
1179 List.length cl = 1 || List.length cl = 0
1181 raise (TypeCheckerFailure ("Unknown mutual inductive definition:" ^
1182 UriManager.string_of_uri uri))
1184 | (C.Sort C.Set, C.Sort C.Prop) when need_dummy -> true
1185 | (C.Sort C.CProp, C.Sort C.Prop) when need_dummy -> true
1186 | (C.Sort C.Set, C.Sort C.Set) when need_dummy -> true
1187 | (C.Sort C.Set, C.Sort C.CProp) when need_dummy -> true
1188 | (C.Sort C.CProp, C.Sort C.Set) when need_dummy -> true
1189 | (C.Sort C.CProp, C.Sort C.CProp) when need_dummy -> true
1190 | ((C.Sort C.Set, C.Sort C.Type) | (C.Sort C.CProp, C.Sort C.Type))
1192 (match CicEnvironment.get_obj uri with
1193 C.InductiveDefinition (itl,_,paramsno) ->
1195 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1197 let (_,_,_,cl) = List.nth itl i in
1199 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1201 raise (TypeCheckerFailure ("Unknown mutual inductive definition:" ^
1202 UriManager.string_of_uri uri))
1204 | (C.Sort C.Type, C.Sort _) when need_dummy -> true
1205 | (C.Sort C.Prop, C.Prod (name,so,ta)) when not need_dummy ->
1206 let res = CicReduction.are_convertible context so ind
1209 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1210 C.Sort C.Prop -> true
1211 | (C.Sort C.Set | C.Sort C.CProp) ->
1212 (match CicEnvironment.get_obj uri with
1213 C.InductiveDefinition (itl,_,_) ->
1214 let (_,_,_,cl) = List.nth itl i in
1215 (* is a singleton definition? *)
1218 raise (TypeCheckerFailure
1219 ("Unknown mutual inductive definition:" ^
1220 UriManager.string_of_uri uri))
1224 | ((C.Sort C.Set, C.Prod (name,so,ta)) | (C.Sort C.CProp, C.Prod (name,so,ta)))
1225 when not need_dummy ->
1226 let res = CicReduction.are_convertible context so ind
1229 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1231 | C.Sort C.Set -> true
1232 | C.Sort C.CProp -> true
1234 (match CicEnvironment.get_obj uri with
1235 C.InductiveDefinition (itl,_,paramsno) ->
1236 let (_,_,_,cl) = List.nth itl i in
1239 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1242 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1244 raise (TypeCheckerFailure
1245 ("Unknown mutual inductive definition:" ^
1246 UriManager.string_of_uri uri))
1248 | _ -> raise (AssertFailure "19")
1250 | (C.Sort C.Type, C.Prod (_,so,_)) when not need_dummy ->
1251 CicReduction.are_convertible context so ind
1254 and type_of_branch context argsno need_dummy outtype term constype =
1255 let module C = Cic in
1256 let module R = CicReduction in
1257 match R.whd context constype with
1262 C.Appl [outtype ; term]
1263 | C.Appl (C.MutInd (_,_,_)::tl) ->
1264 let (_,arguments) = split tl argsno
1266 if need_dummy && arguments = [] then
1269 C.Appl (outtype::arguments@(if need_dummy then [] else [term]))
1270 | C.Prod (name,so,de) ->
1272 match CicSubstitution.lift 1 term with
1273 C.Appl l -> C.Appl (l@[C.Rel 1])
1274 | t -> C.Appl [t ; C.Rel 1]
1276 C.Prod (C.Anonymous,so,type_of_branch
1277 ((Some (name,(C.Decl so)))::context) argsno need_dummy
1278 (CicSubstitution.lift 1 outtype) term' de)
1279 | _ -> raise (AssertFailure "20")
1281 (* check_metasenv_consistency checks that the "canonical" context of a
1282 metavariable is consitent - up to relocation via the relocation list l -
1283 with the actual context *)
1285 and check_metasenv_consistency metasenv context canonical_context l =
1286 let module C = Cic in
1287 let module R = CicReduction in
1288 let module S = CicSubstitution in
1289 let lifted_canonical_context =
1293 | (Some (n,C.Decl t))::tl ->
1294 (Some (n,C.Decl (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1295 | (Some (n,C.Def (t,None)))::tl ->
1296 (Some (n,C.Def ((S.lift_meta l (S.lift i t)),None)))::(aux (i+1) tl)
1297 | None::tl -> None::(aux (i+1) tl)
1298 | (Some (n,C.Def (_,Some _)))::_ -> assert false
1300 aux 1 canonical_context
1306 | Some t,Some (_,C.Def (ct,_)) ->
1307 if not (R.are_convertible context t ct) then
1308 raise (TypeCheckerFailure (sprintf
1309 "Not well typed metavariable local context: expected a term convertible with %s, found %s"
1310 (CicPp.ppterm ct) (CicPp.ppterm t)))
1311 | Some t,Some (_,C.Decl ct) ->
1312 let type_t = type_of_aux' metasenv context t in
1313 if not (R.are_convertible context type_t ct) then
1314 raise (TypeCheckerFailure (sprintf
1315 "Not well typed metavariable local context: expected a term of type %s, found %s of type %s"
1316 (CicPp.ppterm ct) (CicPp.ppterm t) (CicPp.ppterm type_t)))
1318 raise (TypeCheckerFailure
1319 "Not well typed metavariable local context: an hypothesis, that is not hidden, is not instantiated")
1320 ) l lifted_canonical_context
1322 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
1323 and type_of_aux' metasenv context t =
1324 let rec type_of_aux context =
1325 let module C = Cic in
1326 let module R = CicReduction in
1327 let module S = CicSubstitution in
1328 let module U = UriManager in
1332 match List.nth context (n - 1) with
1333 Some (_,C.Decl t) -> S.lift n t
1334 | Some (_,C.Def (_,Some ty)) -> S.lift n ty
1335 | Some (_,C.Def (bo,None)) ->
1336 debug_print "##### CASO DA INVESTIGARE E CAPIRE" ;
1337 type_of_aux context (S.lift n bo)
1338 | None -> raise (TypeCheckerFailure "Reference to deleted hypothesis")
1341 raise (TypeCheckerFailure
1342 "unbound variable found in constructor type")
1344 | C.Var (uri,exp_named_subst) ->
1346 check_exp_named_subst context exp_named_subst ;
1348 CicSubstitution.subst_vars exp_named_subst (type_of_variable uri)
1353 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
1354 check_metasenv_consistency metasenv context canonical_context l;
1355 CicSubstitution.lift_meta l ty
1356 | C.Sort s -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1357 | C.Implicit -> raise (AssertFailure "21")
1358 | C.Cast (te,ty) as t ->
1359 let _ = type_of_aux context ty in
1360 if R.are_convertible context (type_of_aux context te) ty then
1363 raise (TypeCheckerFailure
1364 (sprintf "Invalid cast %s" (CicPp.ppterm t)))
1365 | C.Prod (name,s,t) ->
1366 let sort1 = type_of_aux context s
1367 and sort2 = type_of_aux ((Some (name,(C.Decl s)))::context) t in
1368 sort_of_prod context (name,s) (sort1,sort2)
1369 | C.Lambda (n,s,t) ->
1370 let sort1 = type_of_aux context s
1371 and type2 = type_of_aux ((Some (n,(C.Decl s)))::context) t in
1372 let sort2 = type_of_aux ((Some (n,(C.Decl s)))::context) type2 in
1373 (* only to check if the product is well-typed *)
1374 let _ = sort_of_prod context (n,s) (sort1,sort2) in
1376 | C.LetIn (n,s,t) ->
1377 (* only to check if s is well-typed *)
1378 let ty = type_of_aux context s in
1379 (* The type of a LetIn is a LetIn. Extremely slow since the computed
1380 LetIn is later reduced and maybe also re-checked.
1381 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t))
1383 (* The type of the LetIn is reduced. Much faster than the previous
1384 solution. Moreover the inferred type is probably very different
1385 from the expected one.
1386 (CicReduction.whd context
1387 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t)))
1389 (* One-step LetIn reduction. Even faster than the previous solution.
1390 Moreover the inferred type is closer to the expected one. *)
1391 (CicSubstitution.subst s
1392 (type_of_aux ((Some (n,(C.Def (s,Some ty))))::context) t))
1393 | C.Appl (he::tl) when List.length tl > 0 ->
1394 let hetype = type_of_aux context he
1395 and tlbody_and_type = List.map (fun x -> (x, type_of_aux context x)) tl in
1396 eat_prods context hetype tlbody_and_type
1397 | C.Appl _ -> raise (AssertFailure "Appl: no arguments")
1398 | C.Const (uri,exp_named_subst) ->
1400 check_exp_named_subst context exp_named_subst ;
1402 CicSubstitution.subst_vars exp_named_subst (type_of_constant uri)
1406 | C.MutInd (uri,i,exp_named_subst) ->
1408 check_exp_named_subst context exp_named_subst ;
1410 CicSubstitution.subst_vars exp_named_subst
1411 (type_of_mutual_inductive_defs uri i)
1415 | C.MutConstruct (uri,i,j,exp_named_subst) ->
1416 check_exp_named_subst context exp_named_subst ;
1418 CicSubstitution.subst_vars exp_named_subst
1419 (type_of_mutual_inductive_constr uri i j)
1422 | C.MutCase (uri,i,outtype,term,pl) ->
1423 let outsort = type_of_aux context outtype in
1424 let (need_dummy, k) =
1425 let rec guess_args context t =
1426 let outtype = CicReduction.whd context t in
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)
1444 raise (TypeCheckerFailure (sprintf
1445 "Malformed case analasys' output type %s" (CicPp.ppterm outtype)))
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 (sprintf
1460 "Case analysys: analysed term type is %s, but is expected to be (an application of) %s#1/%d{_}"
1461 (CicPp.ppterm typ) (U.string_of_uri uri) i))
1462 | C.Appl ((C.MutInd (uri',i',exp_named_subst) as typ):: tl) as typ' ->
1463 if U.eq uri uri' && i = i' then
1465 split tl (List.length tl - k)
1466 in params,args,exp_named_subst
1467 else raise (TypeCheckerFailure (sprintf
1468 "Case analysys: analysed term type is %s, but is expected to be (an application of) %s#1/%d{_}"
1469 (CicPp.ppterm typ') (U.string_of_uri uri) i))
1471 raise (TypeCheckerFailure (sprintf
1472 "Case analysis: analysed term %s is not an inductive one"
1473 (CicPp.ppterm term)))
1475 (* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
1476 let sort_of_ind_type =
1477 if parameters = [] then
1478 C.MutInd (uri,i,exp_named_subst)
1480 C.Appl ((C.MutInd (uri,i,exp_named_subst))::parameters)
1482 if not (check_allowed_sort_elimination context uri i need_dummy
1483 sort_of_ind_type (type_of_aux context sort_of_ind_type) outsort)
1486 (TypeCheckerFailure ("Case analasys: sort elimination not allowed"));
1487 (* let's check if the type of branches are right *)
1489 match CicEnvironment.get_cooked_obj ~trust:false uri with
1490 C.InductiveDefinition (_,_,parsno) -> parsno
1492 raise (TypeCheckerFailure
1493 ("Unknown mutual inductive definition:" ^
1494 UriManager.string_of_uri uri))
1496 let (_,branches_ok) =
1500 if parameters = [] then
1501 (C.MutConstruct (uri,i,j,exp_named_subst))
1503 (C.Appl (C.MutConstruct (uri,i,j,exp_named_subst)::parameters))
1510 R.are_convertible context (type_of_aux context p)
1511 (type_of_branch context parsno need_dummy outtype cons
1512 (type_of_aux context cons))
1513 in if not res then debug_print ("#### " ^ CicPp.ppterm (type_of_aux context p) ^ " <==> " ^ CicPp.ppterm (type_of_branch context parsno need_dummy outtype cons (type_of_aux context cons))) ; res
1517 if not branches_ok then
1519 (TypeCheckerFailure "Case analysys: wrong branch type");
1520 if not need_dummy then
1521 C.Appl ((outtype::arguments)@[term])
1522 else if arguments = [] then
1525 C.Appl (outtype::arguments)
1527 let types_times_kl =
1531 let _ = type_of_aux context ty in
1532 (Some (C.Name n,(C.Decl ty)),k)) fl)
1534 let (types,kl) = List.split types_times_kl in
1535 let len = List.length types in
1537 (fun (name,x,ty,bo) ->
1539 (R.are_convertible (types@context) (type_of_aux (types@context) bo)
1540 (CicSubstitution.lift len ty))
1543 let (m, eaten, context') =
1544 eat_lambdas (types @ context) (x + 1) bo
1546 (*let's control the guarded by destructors conditions D{f,k,x,M}*)
1549 (guarded_by_destructors context' eaten (len + eaten) kl 1 [] m)
1552 (TypeCheckerFailure ("Fix: not guarded by destructors"))
1555 raise (TypeCheckerFailure ("Fix: ill-typed bodies"))
1558 (*CSC: controlli mancanti solo su D{f,k,x,M} *)
1559 let (_,_,ty,_) = List.nth fl i in
1566 let _ = type_of_aux context ty in Some (C.Name n,(C.Decl ty))) fl)
1568 let len = List.length types in
1572 (R.are_convertible (types @ context)
1573 (type_of_aux (types @ context) bo) (CicSubstitution.lift len ty))
1576 (* let's control that the returned type is coinductive *)
1577 match returns_a_coinductive context ty with
1581 ("CoFix: does not return a coinductive type"))
1583 (*let's control the guarded by constructors conditions C{f,M}*)
1586 (guarded_by_constructors (types @ context) 0 len false bo
1590 (TypeCheckerFailure ("CoFix: not guarded by constructors"))
1594 (TypeCheckerFailure ("CoFix: ill-typed bodies"))
1597 let (_,ty,_) = List.nth fl i in
1600 and check_exp_named_subst context =
1601 let rec check_exp_named_subst_aux substs =
1604 | ((uri,t) as subst)::tl ->
1606 CicSubstitution.subst_vars substs (type_of_variable uri) in
1607 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1608 Cic.Variable (_,Some bo,_,_) ->
1611 ("A variable with a body can not be explicit substituted"))
1612 | Cic.Variable (_,None,_,_) -> ()
1614 raise (TypeCheckerFailure
1615 ("Unknown mutual inductive definition:" ^
1616 UriManager.string_of_uri uri))
1618 let typeoft = type_of_aux context t in
1619 if CicReduction.are_convertible context typeoft typeofvar then
1620 check_exp_named_subst_aux (substs@[subst]) tl
1623 CicReduction.fdebug := 0 ;
1624 ignore (CicReduction.are_convertible context typeoft typeofvar) ;
1626 debug typeoft [typeofvar] ;
1627 raise (TypeCheckerFailure "Wrong Explicit Named Substitution")
1630 check_exp_named_subst_aux []
1632 and sort_of_prod context (name,s) (t1, t2) =
1633 let module C = Cic in
1634 let t1' = CicReduction.whd context t1 in
1635 let t2' = CicReduction.whd ((Some (name,C.Decl s))::context) t2 in
1636 match (t1', t2') with
1637 (C.Sort s1, C.Sort s2)
1638 when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) -> (* different from Coq manual!!! *)
1640 | (C.Sort s1, C.Sort s2) -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1641 | (_,_) -> raise (SortExpectedMetaFound (sprintf
1642 "Prod: expected two sorts, found = %s, %s" (CicPp.ppterm t1')
1643 (CicPp.ppterm t2')))
1644 (* raise (TypeCheckerFailure (sprintf *)
1646 and eat_prods context hetype =
1647 (*CSC: siamo sicuri che le are_convertible non lavorino con termini non *)
1651 | (hete, hety)::tl ->
1652 (match (CicReduction.whd context hetype) with
1654 if CicReduction.are_convertible context s hety then
1655 (CicReduction.fdebug := -1 ;
1656 eat_prods context (CicSubstitution.subst hete t) tl
1660 CicReduction.fdebug := 0 ;
1661 ignore (CicReduction.are_convertible context s hety) ;
1664 raise (TypeCheckerFailure (sprintf
1665 "Appl: wrong parameter-type, expected %s, found %s"
1666 (CicPp.ppterm hetype) (CicPp.ppterm s)))
1669 raise (TypeCheckerFailure
1670 "Appl: this is not a function, it cannot be applied")
1673 and returns_a_coinductive context ty =
1674 let module C = Cic in
1675 match CicReduction.whd context ty with
1676 C.MutInd (uri,i,_) ->
1677 (*CSC: definire una funzioncina per questo codice sempre replicato *)
1678 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1679 C.InductiveDefinition (itl,_,_) ->
1680 let (_,is_inductive,_,_) = List.nth itl i in
1681 if is_inductive then None else (Some uri)
1683 raise (TypeCheckerFailure
1684 ("Unknown mutual inductive definition:" ^
1685 UriManager.string_of_uri uri))
1687 | C.Appl ((C.MutInd (uri,i,_))::_) ->
1688 (match CicEnvironment.get_obj uri with
1689 C.InductiveDefinition (itl,_,_) ->
1690 let (_,is_inductive,_,_) = List.nth itl i in
1691 if is_inductive then None else (Some uri)
1693 raise (TypeCheckerFailure
1694 ("Unknown mutual inductive definition:" ^
1695 UriManager.string_of_uri uri))
1697 | C.Prod (n,so,de) ->
1698 returns_a_coinductive ((Some (n,C.Decl so))::context) de
1703 debug_print ("INIZIO TYPE_OF_AUX " ^ CicPp.ppterm t) ; flush stderr ;
1706 type_of_aux context t
1708 in debug_print "FINE TYPE_OF_AUX" ; flush stderr ; res
1711 (* is a small constructor? *)
1712 (*CSC: ottimizzare calcolando staticamente *)
1713 and is_small context paramsno c =
1714 let rec is_small_aux context c =
1715 let module C = Cic in
1716 match CicReduction.whd context c with
1718 (*CSC: [] is an empty metasenv. Is it correct? *)
1719 let s = type_of_aux' [] context so in
1720 (s = C.Sort C.Prop || s = C.Sort C.Set || s = C.Sort C.CProp) &&
1721 is_small_aux ((Some (n,(C.Decl so)))::context) de
1722 | _ -> true (*CSC: we trust the type-checker *)
1724 let (context',dx) = split_prods context paramsno c in
1725 is_small_aux context' dx
1729 debug_print ("INIZIO TYPE_OF_AUX' " ^ CicPp.ppterm t) ; flush stderr ;
1732 type_of_aux' [] [] t
1734 in debug_print "FINE TYPE_OF_AUX'" ; flush stderr ; res
1739 let module C = Cic in
1740 let module R = CicReduction in
1741 let module U = UriManager in
1742 match CicEnvironment.is_type_checked ~trust:false uri with
1743 CicEnvironment.CheckedObj _ -> ()
1744 | CicEnvironment.UncheckedObj uobj ->
1745 (* let's typecheck the uncooked object *)
1746 CicLogger.log (`Start_type_checking uri) ;
1748 C.Constant (_,Some te,ty,_) ->
1749 let _ = type_of ty in
1750 if not (R.are_convertible [] (type_of te ) ty) then
1751 raise (TypeCheckerFailure
1752 ("Unknown constant:" ^ U.string_of_uri uri))
1753 | C.Constant (_,None,ty,_) ->
1754 (* only to check that ty is well-typed *)
1755 let _ = type_of ty in ()
1756 | C.CurrentProof (_,conjs,te,ty,_) ->
1759 (fun metasenv ((_,context,ty) as conj) ->
1760 ignore (type_of_aux' metasenv context ty) ;
1764 let _ = type_of_aux' conjs [] ty in
1765 let type_of_te = type_of_aux' conjs [] te in
1766 if not (R.are_convertible [] type_of_te ty)
1768 raise (TypeCheckerFailure (sprintf
1769 "the current proof %s is not well typed because the type %s of the body is not convertible to the declared type %s"
1770 (U.string_of_uri uri) (CicPp.ppterm type_of_te)
1772 | C.Variable (_,bo,ty,_) ->
1773 (* only to check that ty is well-typed *)
1774 let _ = type_of ty in
1778 if not (R.are_convertible [] (type_of bo) ty) then
1779 raise (TypeCheckerFailure
1780 ("Unknown variable:" ^ U.string_of_uri uri))
1782 | C.InductiveDefinition _ ->
1783 check_mutual_inductive_defs uri uobj
1785 CicEnvironment.set_type_checking_info uri ;
1786 CicLogger.log (`Type_checking_completed uri)