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 exception Impossible of int;;
27 exception NotWellTyped of string;;
28 exception WrongUriToConstant of string;;
29 exception WrongUriToVariable of string;;
30 exception WrongUriToMutualInductiveDefinitions of string;;
31 exception ListTooShort;;
32 exception NotPositiveOccurrences of string;;
33 exception NotWellFormedTypeOfInductiveConstructor of string;;
34 exception WrongRequiredArgument of string;;
35 exception RelToHiddenHypothesis;;
36 exception MetasenvInconsistency;;
40 let rec debug_aux t i =
42 let module U = UriManager in
43 CicPp.ppobj (C.Variable ("DEBUG", None, t, [])) ^ "\n" ^ i
46 raise (NotWellTyped ("\n" ^ List.fold_right debug_aux (t::context) ""))
47 (*print_endline ("\n" ^ List.fold_right debug_aux (t::context) "") ; flush stdout*)
53 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
54 | (_,_) -> raise ListTooShort
57 let debrujin_constructor uri number_of_types =
61 C.Rel n as t when n <= k -> t
63 raise (NotWellTyped ("Debrujin: open term found"))
64 | C.Var (uri,exp_named_subst) ->
65 let exp_named_subst' =
66 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
68 C.Var (uri,exp_named_subst')
69 | C.Meta _ -> assert false
71 | C.Implicit as t -> t
72 | C.Cast (te,ty) -> C.Cast (aux k te, aux k ty)
73 | C.Prod (n,s,t) -> C.Prod (n, aux k s, aux (k+1) t)
74 | C.Lambda (n,s,t) -> C.Lambda (n, aux k s, aux (k+1) t)
75 | C.LetIn (n,s,t) -> C.LetIn (n, aux k s, aux (k+1) t)
76 | C.Appl l -> C.Appl (List.map (aux k) l)
77 | C.Const (uri,exp_named_subst) ->
78 let exp_named_subst' =
79 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
81 C.Const (uri,exp_named_subst')
82 | C.MutInd (uri',tyno,exp_named_subst) when UriManager.eq uri uri' ->
83 if exp_named_subst != [] then
86 ("Debrujin: a non-empty explicit named substitution is applied to " ^
87 "a mutual inductive type which is being defined")) ;
88 C.Rel (k + number_of_types - tyno) ;
89 | C.MutInd (uri',tyno,exp_named_subst) ->
90 let exp_named_subst' =
91 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
93 C.MutInd (uri',tyno,exp_named_subst')
94 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
95 let exp_named_subst' =
96 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
98 C.MutConstruct (uri,tyno,consno,exp_named_subst')
99 | C.MutCase (sp,i,outty,t,pl) ->
100 C.MutCase (sp, i, aux k outty, aux k t,
103 let len = List.length fl in
106 (fun (name, i, ty, bo) -> (name, i, aux k ty, aux (k+len) bo))
111 let len = List.length fl in
114 (fun (name, ty, bo) -> (name, aux k ty, aux (k+len) bo))
117 C.CoFix (i, liftedfl)
122 exception CicEnvironmentError;;
124 let rec type_of_constant uri =
125 let module C = Cic in
126 let module R = CicReduction in
127 let module U = UriManager in
129 match CicEnvironment.is_type_checked ~trust:true uri with
130 CicEnvironment.CheckedObj cobj -> cobj
131 | CicEnvironment.UncheckedObj uobj ->
132 Logger.log (`Start_type_checking uri) ;
133 (* let's typecheck the uncooked obj *)
135 C.Constant (_,Some te,ty,_) ->
136 let _ = type_of ty in
137 if not (R.are_convertible [] (type_of te) ty) then
138 raise (NotWellTyped ("Constant " ^ (U.string_of_uri uri)))
139 | C.Constant (_,None,ty,_) ->
140 (* only to check that ty is well-typed *)
141 let _ = type_of ty in ()
142 | C.CurrentProof (_,conjs,te,ty,_) ->
145 (fun metasenv ((_,context,ty) as conj) ->
146 ignore (type_of_aux' metasenv context ty) ;
150 let _ = type_of_aux' conjs [] ty in
151 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
153 raise (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri)))
154 | _ -> raise (WrongUriToConstant (U.string_of_uri uri))
156 CicEnvironment.set_type_checking_info uri ;
157 Logger.log (`Type_checking_completed uri) ;
158 match CicEnvironment.is_type_checked ~trust:false uri with
159 CicEnvironment.CheckedObj cobj -> cobj
160 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
163 C.Constant (_,_,ty,_) -> ty
164 | C.CurrentProof (_,_,_,ty,_) -> ty
165 | _ -> raise (WrongUriToConstant (U.string_of_uri uri))
167 and type_of_variable uri =
168 let module C = Cic in
169 let module R = CicReduction in
170 let module U = UriManager in
171 (* 0 because a variable is never cooked => no partial cooking at one level *)
172 match CicEnvironment.is_type_checked ~trust:true uri with
173 CicEnvironment.CheckedObj (C.Variable (_,_,ty,_)) -> ty
174 | CicEnvironment.UncheckedObj (C.Variable (_,bo,ty,_)) ->
175 Logger.log (`Start_type_checking uri) ;
176 (* only to check that ty is well-typed *)
177 let _ = type_of ty in
181 if not (R.are_convertible [] (type_of bo) ty) then
182 raise (NotWellTyped ("Variable " ^ (U.string_of_uri uri)))
184 CicEnvironment.set_type_checking_info uri ;
185 Logger.log (`Type_checking_completed uri) ;
187 | _ -> raise (WrongUriToVariable (UriManager.string_of_uri uri))
189 and does_not_occur context n nn te =
190 let module C = Cic in
191 (*CSC: whd sembra essere superflua perche' un caso in cui l'occorrenza *)
192 (*CSC: venga mangiata durante la whd sembra presentare problemi di *)
194 match CicReduction.whd context te with
195 C.Rel m when m > n && m <= nn -> false
201 does_not_occur context n nn te && does_not_occur context n nn ty
202 | C.Prod (name,so,dest) ->
203 does_not_occur context n nn so &&
204 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1) dest
205 | C.Lambda (name,so,dest) ->
206 does_not_occur context n nn so &&
207 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1) dest
208 | C.LetIn (name,so,dest) ->
209 does_not_occur context n nn so &&
210 does_not_occur ((Some (name,(C.Def so)))::context) (n + 1) (nn + 1) dest
212 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
213 | C.Var (_,exp_named_subst)
214 | C.Const (_,exp_named_subst)
215 | C.MutInd (_,_,exp_named_subst)
216 | C.MutConstruct (_,_,_,exp_named_subst) ->
217 List.fold_right (fun (_,x) i -> i && does_not_occur context n nn x)
219 | C.MutCase (_,_,out,te,pl) ->
220 does_not_occur context n nn out && does_not_occur context n nn te &&
221 List.fold_right (fun x i -> i && does_not_occur context n nn x) pl true
223 let len = List.length fl in
224 let n_plus_len = n + len in
225 let nn_plus_len = nn + len in
227 List.map (fun (n,_,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
230 (fun (_,_,ty,bo) i ->
231 i && does_not_occur context n nn ty &&
232 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
235 let len = List.length fl in
236 let n_plus_len = n + len in
237 let nn_plus_len = nn + len in
239 List.map (fun (n,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
243 i && does_not_occur context n nn ty &&
244 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
247 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
248 (*CSC questa funzione e' simile alla are_all_occurrences_positive, ma fa *)
249 (*CSC dei controlli leggermente diversi. Viene invocata solamente dalla *)
250 (*CSC strictly_positive *)
251 (*CSC definizione (giusta???) tratta dalla mail di Hugo ;-) *)
252 and weakly_positive context n nn uri te =
253 let module C = Cic in
254 (*CSC: Che schifo! Bisogna capire meglio e trovare una soluzione ragionevole!*)
256 C.MutInd (UriManager.uri_of_string "cic:/Coq/Init/Datatypes/nat.ind",0,[])
258 (*CSC mettere in cicSubstitution *)
259 let rec subst_inductive_type_with_dummy_mutind =
261 C.MutInd (uri',0,_) when UriManager.eq uri' uri ->
263 | C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri ->
265 | C.Cast (te,ty) -> subst_inductive_type_with_dummy_mutind te
266 | C.Prod (name,so,ta) ->
267 C.Prod (name, subst_inductive_type_with_dummy_mutind so,
268 subst_inductive_type_with_dummy_mutind ta)
269 | C.Lambda (name,so,ta) ->
270 C.Lambda (name, subst_inductive_type_with_dummy_mutind so,
271 subst_inductive_type_with_dummy_mutind ta)
273 C.Appl (List.map subst_inductive_type_with_dummy_mutind tl)
274 | C.MutCase (uri,i,outtype,term,pl) ->
276 subst_inductive_type_with_dummy_mutind outtype,
277 subst_inductive_type_with_dummy_mutind term,
278 List.map subst_inductive_type_with_dummy_mutind pl)
280 C.Fix (i,List.map (fun (name,i,ty,bo) -> (name,i,
281 subst_inductive_type_with_dummy_mutind ty,
282 subst_inductive_type_with_dummy_mutind bo)) fl)
284 C.CoFix (i,List.map (fun (name,ty,bo) -> (name,
285 subst_inductive_type_with_dummy_mutind ty,
286 subst_inductive_type_with_dummy_mutind bo)) fl)
287 | C.Const (uri,exp_named_subst) ->
288 let exp_named_subst' =
290 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
293 C.Const (uri,exp_named_subst')
294 | C.MutInd (uri,typeno,exp_named_subst) ->
295 let exp_named_subst' =
297 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
300 C.MutInd (uri,typeno,exp_named_subst')
301 | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
302 let exp_named_subst' =
304 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
307 C.MutConstruct (uri,typeno,consno,exp_named_subst')
310 match CicReduction.whd context te with
311 C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri -> true
312 | C.MutInd (uri',0,_) when UriManager.eq uri' uri -> true
313 | C.Prod (C.Anonymous,source,dest) ->
314 strictly_positive context n nn
315 (subst_inductive_type_with_dummy_mutind source) &&
316 weakly_positive ((Some (C.Anonymous,(C.Decl source)))::context)
317 (n + 1) (nn + 1) uri dest
318 | C.Prod (name,source,dest) when
319 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
320 (* dummy abstraction, so we behave as in the anonimous case *)
321 strictly_positive context n nn
322 (subst_inductive_type_with_dummy_mutind source) &&
323 weakly_positive ((Some (name,(C.Decl source)))::context)
324 (n + 1) (nn + 1) uri dest
325 | C.Prod (name,source,dest) ->
326 does_not_occur context n nn
327 (subst_inductive_type_with_dummy_mutind source)&&
328 weakly_positive ((Some (name,(C.Decl source)))::context)
329 (n + 1) (nn + 1) uri dest
330 | _ -> raise (NotWellFormedTypeOfInductiveConstructor ("Guess where the error is ;-)"))
332 (* instantiate_parameters ps (x1:T1)...(xn:Tn)C *)
333 (* returns ((x_|ps|:T_|ps|)...(xn:Tn)C){ps_1 / x1 ; ... ; ps_|ps| / x_|ps|} *)
334 and instantiate_parameters params c =
335 let module C = Cic in
336 match (c,params) with
338 | (C.Prod (_,_,ta), he::tl) ->
339 instantiate_parameters tl
340 (CicSubstitution.subst he ta)
341 | (C.Cast (te,_), _) -> instantiate_parameters params te
342 | (t,l) -> raise (Impossible 1)
344 and strictly_positive context n nn te =
345 let module C = Cic in
346 let module U = UriManager in
347 match CicReduction.whd context te with
350 (*CSC: bisogna controllare ty????*)
351 strictly_positive context n nn te
352 | C.Prod (name,so,ta) ->
353 does_not_occur context n nn so &&
354 strictly_positive ((Some (name,(C.Decl so)))::context) (n+1) (nn+1) ta
355 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
356 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
357 | C.Appl ((C.MutInd (uri,i,exp_named_subst))::tl) ->
358 let (ok,paramsno,ity,cl,name) =
359 match CicEnvironment.get_obj uri with
360 C.InductiveDefinition (tl,_,paramsno) ->
361 let (name,_,ity,cl) = List.nth tl i in
362 (List.length tl = 1, paramsno, ity, cl, name)
363 | _ -> raise(WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
365 let (params,arguments) = split tl paramsno in
366 let lifted_params = List.map (CicSubstitution.lift 1) params in
370 instantiate_parameters lifted_params
371 (CicSubstitution.subst_vars exp_named_subst te)
376 (fun x i -> i && does_not_occur context n nn x)
378 (*CSC: MEGAPATCH3 (sara' quella giusta?)*)
383 ((Some (C.Name name,(Cic.Decl ity)))::context) (n+1) (nn+1) uri x
385 | t -> does_not_occur context n nn t
387 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
388 and are_all_occurrences_positive context uri indparamsno i n nn te =
389 let module C = Cic in
390 match CicReduction.whd context te with
391 C.Appl ((C.Rel m)::tl) when m = i ->
392 (*CSC: riscrivere fermandosi a 0 *)
393 (* let's check if the inductive type is applied at least to *)
394 (* indparamsno parameters *)
400 match CicReduction.whd context x with
401 C.Rel m when m = n - (indparamsno - k) -> k - 1
402 | _ -> raise (WrongRequiredArgument (UriManager.string_of_uri uri))
406 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
408 raise (WrongRequiredArgument (UriManager.string_of_uri uri))
409 | C.Rel m when m = i ->
410 if indparamsno = 0 then
413 raise (WrongRequiredArgument (UriManager.string_of_uri uri))
414 | C.Prod (C.Anonymous,source,dest) ->
415 strictly_positive context n nn source &&
416 are_all_occurrences_positive
417 ((Some (C.Anonymous,(C.Decl source)))::context) uri indparamsno
418 (i+1) (n + 1) (nn + 1) dest
419 | C.Prod (name,source,dest) when
420 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
421 (* dummy abstraction, so we behave as in the anonimous case *)
422 strictly_positive context n nn source &&
423 are_all_occurrences_positive
424 ((Some (name,(C.Decl source)))::context) uri indparamsno
425 (i+1) (n + 1) (nn + 1) dest
426 | C.Prod (name,source,dest) ->
427 does_not_occur context n nn source &&
428 are_all_occurrences_positive ((Some (name,(C.Decl source)))::context)
429 uri indparamsno (i+1) (n + 1) (nn + 1) dest
430 | _ -> raise (NotWellFormedTypeOfInductiveConstructor (UriManager.string_of_uri uri))
432 (* Main function to checks the correctness of a mutual *)
433 (* inductive block definition. This is the function *)
434 (* exported to the proof-engine. *)
435 and typecheck_mutual_inductive_defs uri (itl,_,indparamsno) =
436 let module U = UriManager in
437 (* let's check if the arity of the inductive types are well *)
439 List.iter (fun (_,_,x,_) -> let _ = type_of x in ()) itl ;
441 (* let's check if the types of the inductive constructors *)
442 (* are well formed. *)
443 (* In order not to use type_of_aux we put the types of the *)
444 (* mutual inductive types at the head of the types of the *)
445 (* constructors using Prods *)
446 let len = List.length itl in
448 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl in
454 let debrujinedte = debrujin_constructor uri len te in
457 (fun (name,_,ty,_) i -> Cic.Prod (Cic.Name name, ty, i))
460 let _ = type_of augmented_term in
461 (* let's check also the positivity conditions *)
464 (are_all_occurrences_positive tys uri indparamsno i 0 len
467 raise (NotPositiveOccurrences (U.string_of_uri uri))
474 (* Main function to checks the correctness of a mutual *)
475 (* inductive block definition. *)
476 and check_mutual_inductive_defs uri =
478 Cic.InductiveDefinition (itl, params, indparamsno) ->
479 typecheck_mutual_inductive_defs uri (itl,params,indparamsno)
481 raise (WrongUriToMutualInductiveDefinitions (UriManager.string_of_uri uri))
483 and type_of_mutual_inductive_defs uri i =
484 let module C = Cic in
485 let module R = CicReduction in
486 let module U = UriManager in
488 match CicEnvironment.is_type_checked ~trust:true uri with
489 CicEnvironment.CheckedObj cobj -> cobj
490 | CicEnvironment.UncheckedObj uobj ->
491 Logger.log (`Start_type_checking uri) ;
492 check_mutual_inductive_defs uri uobj ;
493 CicEnvironment.set_type_checking_info uri ;
494 Logger.log (`Type_checking_completed uri) ;
495 (match CicEnvironment.is_type_checked ~trust:false uri with
496 CicEnvironment.CheckedObj cobj -> cobj
497 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
501 C.InductiveDefinition (dl,_,_) ->
502 let (_,_,arity,_) = List.nth dl i in
504 | _ -> raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
506 and type_of_mutual_inductive_constr uri i j =
507 let module C = Cic in
508 let module R = CicReduction in
509 let module U = UriManager in
511 match CicEnvironment.is_type_checked ~trust:true uri with
512 CicEnvironment.CheckedObj cobj -> cobj
513 | CicEnvironment.UncheckedObj uobj ->
514 Logger.log (`Start_type_checking uri) ;
515 check_mutual_inductive_defs uri uobj ;
516 CicEnvironment.set_type_checking_info uri ;
517 Logger.log (`Type_checking_completed uri) ;
518 (match CicEnvironment.is_type_checked ~trust:false uri with
519 CicEnvironment.CheckedObj cobj -> cobj
520 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
524 C.InductiveDefinition (dl,_,_) ->
525 let (_,_,_,cl) = List.nth dl i in
526 let (_,ty) = List.nth cl (j-1) in
528 | _ -> raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
530 and recursive_args context n nn te =
531 let module C = Cic in
532 match CicReduction.whd context te with
538 | C.Cast _ (*CSC ??? *) -> raise (Impossible 3) (* due to type-checking *)
539 | C.Prod (name,so,de) ->
540 (not (does_not_occur context n nn so)) ::
541 (recursive_args ((Some (name,(C.Decl so)))::context) (n+1) (nn + 1) de)
543 | C.LetIn _ -> raise (Impossible 4) (* due to type-checking *)
545 | C.Const _ -> raise (Impossible 5)
550 | C.CoFix _ -> raise (Impossible 6) (* due to type-checking *)
552 and get_new_safes context p c rl safes n nn x =
553 let module C = Cic in
554 let module U = UriManager in
555 let module R = CicReduction in
556 match (R.whd context c, R.whd context p, rl) with
557 (C.Prod (_,so,ta1), C.Lambda (name,_,ta2), b::tl) ->
558 (* we are sure that the two sources are convertible because we *)
559 (* have just checked this. So let's go along ... *)
561 List.map (fun x -> x + 1) safes
564 if b then 1::safes' else safes'
566 get_new_safes ((Some (name,(C.Decl so)))::context)
567 ta2 ta1 tl safes'' (n+1) (nn+1) (x+1)
568 | (C.Prod _, (C.MutConstruct _ as e), _)
569 | (C.Prod _, (C.Rel _ as e), _)
570 | (C.MutInd _, e, [])
571 | (C.Appl _, e, []) -> (e,safes,n,nn,x,context)
573 (* CSC: If the next exception is raised, it just means that *)
574 (* CSC: the proof-assistant allows to use very strange things *)
575 (* CSC: as a branch of a case whose type is a Prod. In *)
576 (* CSC: particular, this means that a new (C.Prod, x,_) case *)
577 (* CSC: must be considered in this match. (e.g. x = MutCase) *)
580 and split_prods context n te =
581 let module C = Cic in
582 let module R = CicReduction in
583 match (n, R.whd context te) with
585 | (n, C.Prod (name,so,ta)) when n > 0 ->
586 split_prods ((Some (name,(C.Decl so)))::context) (n - 1) ta
587 | (_, _) -> raise (Impossible 8)
589 and eat_lambdas context n te =
590 let module C = Cic in
591 let module R = CicReduction in
592 match (n, R.whd context te) with
593 (0, _) -> (te, 0, context)
594 | (n, C.Lambda (name,so,ta)) when n > 0 ->
595 let (te, k, context') =
596 eat_lambdas ((Some (name,(C.Decl so)))::context) (n - 1) ta
598 (te, k + 1, context')
599 | (_, _) -> raise (Impossible 9)
601 (*CSC: Tutto quello che segue e' l'intuzione di luca ;-) *)
602 and check_is_really_smaller_arg context n nn kl x safes te =
603 (*CSC: forse la whd si puo' fare solo quando serve veramente. *)
604 (*CSC: cfr guarded_by_destructors *)
605 let module C = Cic in
606 let module U = UriManager in
607 match CicReduction.whd context te with
608 C.Rel m when List.mem m safes -> true
615 (* | C.Cast (te,ty) ->
616 check_is_really_smaller_arg n nn kl x safes te &&
617 check_is_really_smaller_arg n nn kl x safes ty*)
618 (* | C.Prod (_,so,ta) ->
619 check_is_really_smaller_arg n nn kl x safes so &&
620 check_is_really_smaller_arg (n+1) (nn+1) kl (x+1)
621 (List.map (fun x -> x + 1) safes) ta*)
622 | C.Prod _ -> raise (Impossible 10)
623 | C.Lambda (name,so,ta) ->
624 check_is_really_smaller_arg context n nn kl x safes so &&
625 check_is_really_smaller_arg ((Some (name,(C.Decl so)))::context)
626 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
627 | C.LetIn (name,so,ta) ->
628 check_is_really_smaller_arg context n nn kl x safes so &&
629 check_is_really_smaller_arg ((Some (name,(C.Def so)))::context)
630 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
632 (*CSC: sulla coda ci vogliono dei controlli? secondo noi no, ma *)
633 (*CSC: solo perche' non abbiamo trovato controesempi *)
634 check_is_really_smaller_arg context n nn kl x safes he
635 | C.Appl [] -> raise (Impossible 11)
637 | C.MutInd _ -> raise (Impossible 12)
638 | C.MutConstruct _ -> false
639 | C.MutCase (uri,i,outtype,term,pl) ->
641 C.Rel m when List.mem m safes || m = x ->
642 let (tys,len,isinductive,paramsno,cl) =
643 match CicEnvironment.get_obj uri with
644 C.InductiveDefinition (tl,_,paramsno) ->
646 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) tl
648 let (_,isinductive,_,cl) = List.nth tl i in
652 (id, snd (split_prods tys paramsno ty))) cl
654 (tys,List.length tl,isinductive,paramsno,cl')
656 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
658 if not isinductive then
661 i && check_is_really_smaller_arg context n nn kl x safes p)
667 let debrujinedte = debrujin_constructor uri len c in
668 recursive_args tys 0 len debrujinedte
670 let (e,safes',n',nn',x',context') =
671 get_new_safes context p c rl' safes n nn x
674 check_is_really_smaller_arg context' n' nn' kl x' safes' e
675 ) (List.combine pl cl) true
676 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
677 let (tys,len,isinductive,paramsno,cl) =
678 match CicEnvironment.get_obj uri with
679 C.InductiveDefinition (tl,_,paramsno) ->
680 let (_,isinductive,_,cl) = List.nth tl i in
682 List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
687 (id, snd (split_prods tys paramsno ty))) cl
689 (tys,List.length tl,isinductive,paramsno,cl')
691 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
693 if not isinductive then
696 i && check_is_really_smaller_arg context n nn kl x safes p)
699 (*CSC: supponiamo come prima che nessun controllo sia necessario*)
700 (*CSC: sugli argomenti di una applicazione *)
704 let debrujinedte = debrujin_constructor uri len c in
705 recursive_args tys 0 len debrujinedte
707 let (e, safes',n',nn',x',context') =
708 get_new_safes context p c rl' safes n nn x
711 check_is_really_smaller_arg context' n' nn' kl x' safes' e
712 ) (List.combine pl cl) true
716 i && check_is_really_smaller_arg context n nn kl x safes p
720 let len = List.length fl in
721 let n_plus_len = n + len
722 and nn_plus_len = nn + len
723 and x_plus_len = x + len
724 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
725 and safes' = List.map (fun x -> x + len) safes in
727 (fun (_,_,ty,bo) i ->
729 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
733 let len = List.length fl in
734 let n_plus_len = n + len
735 and nn_plus_len = nn + len
736 and x_plus_len = x + len
737 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
738 and safes' = List.map (fun x -> x + len) safes in
742 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
746 and guarded_by_destructors context n nn kl x safes =
747 let module C = Cic in
748 let module U = UriManager in
750 C.Rel m when m > n && m <= nn -> false
752 (match List.nth context (n-1) with
753 Some (_,C.Decl _) -> true
754 | Some (_,C.Def bo) -> guarded_by_destructors context n nn kl x safes bo
755 | None -> raise RelToHiddenHypothesis
761 guarded_by_destructors context n nn kl x safes te &&
762 guarded_by_destructors context n nn kl x safes ty
763 | C.Prod (name,so,ta) ->
764 guarded_by_destructors context n nn kl x safes so &&
765 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
766 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
767 | C.Lambda (name,so,ta) ->
768 guarded_by_destructors context n nn kl x safes so &&
769 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
770 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
771 | C.LetIn (name,so,ta) ->
772 guarded_by_destructors context n nn kl x safes so &&
773 guarded_by_destructors ((Some (name,(C.Def so)))::context)
774 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
775 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
776 let k = List.nth kl (m - n - 1) in
777 if not (List.length tl > k) then false
781 i && guarded_by_destructors context n nn kl x safes param
783 check_is_really_smaller_arg context n nn kl x safes (List.nth tl k)
786 (fun t i -> i && guarded_by_destructors context n nn kl x safes t)
788 | C.Var (_,exp_named_subst)
789 | C.Const (_,exp_named_subst)
790 | C.MutInd (_,_,exp_named_subst)
791 | C.MutConstruct (_,_,_,exp_named_subst) ->
793 (fun (_,t) i -> i && guarded_by_destructors context n nn kl x safes t)
795 | C.MutCase (uri,i,outtype,term,pl) ->
797 C.Rel m when List.mem m safes || m = x ->
798 let (tys,len,isinductive,paramsno,cl) =
799 match CicEnvironment.get_obj uri with
800 C.InductiveDefinition (tl,_,paramsno) ->
801 let (_,isinductive,_,cl) = List.nth tl i in
803 List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
808 (id, snd (split_prods tys paramsno ty))) cl
810 (tys,List.length tl,isinductive,paramsno,cl')
812 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
814 if not isinductive then
815 guarded_by_destructors context n nn kl x safes outtype &&
816 guarded_by_destructors context n nn kl x safes term &&
817 (*CSC: manca ??? il controllo sul tipo di term? *)
820 i && guarded_by_destructors context n nn kl x safes p)
823 guarded_by_destructors context n nn kl x safes outtype &&
824 (*CSC: manca ??? il controllo sul tipo di term? *)
828 let debrujinedte = debrujin_constructor uri len c in
829 recursive_args tys 0 len debrujinedte
831 let (e,safes',n',nn',x',context') =
832 get_new_safes context p c rl' safes n nn x
835 guarded_by_destructors context' n' nn' kl x' safes' e
836 ) (List.combine pl cl) true
837 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
838 let (tys,len,isinductive,paramsno,cl) =
839 match CicEnvironment.get_obj uri with
840 C.InductiveDefinition (tl,_,paramsno) ->
841 let (_,isinductive,_,cl) = List.nth tl i in
843 List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
848 (id, snd (split_prods tys paramsno ty))) cl
850 (tys,List.length tl,isinductive,paramsno,cl')
852 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
854 if not isinductive then
855 guarded_by_destructors context n nn kl x safes outtype &&
856 guarded_by_destructors context n nn kl x safes term &&
857 (*CSC: manca ??? il controllo sul tipo di term? *)
860 i && guarded_by_destructors context n nn kl x safes p)
863 guarded_by_destructors context n nn kl x safes outtype &&
864 (*CSC: manca ??? il controllo sul tipo di term? *)
867 i && guarded_by_destructors context n nn kl x safes t)
872 let debrujinedte = debrujin_constructor uri len c in
873 recursive_args tys 0 len debrujinedte
875 let (e, safes',n',nn',x',context') =
876 get_new_safes context p c rl' safes n nn x
879 guarded_by_destructors context' n' nn' kl x' safes' e
880 ) (List.combine pl cl) true
882 guarded_by_destructors context n nn kl x safes outtype &&
883 guarded_by_destructors context n nn kl x safes term &&
884 (*CSC: manca ??? il controllo sul tipo di term? *)
886 (fun p i -> i && guarded_by_destructors context n nn kl x safes p)
890 let len = List.length fl in
891 let n_plus_len = n + len
892 and nn_plus_len = nn + len
893 and x_plus_len = x + len
894 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
895 and safes' = List.map (fun x -> x + len) safes in
897 (fun (_,_,ty,bo) i ->
898 i && guarded_by_destructors context n nn kl x_plus_len safes' ty &&
899 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
903 let len = List.length fl in
904 let n_plus_len = n + len
905 and nn_plus_len = nn + len
906 and x_plus_len = x + len
907 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
908 and safes' = List.map (fun x -> x + len) safes in
912 guarded_by_destructors context n nn kl x_plus_len safes' ty &&
913 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
917 (* the boolean h means already protected *)
918 (* args is the list of arguments the type of the constructor that may be *)
919 (* found in head position must be applied to. *)
920 (*CSC: coInductiveTypeURI non cambia mai di ricorsione in ricorsione *)
921 and guarded_by_constructors context n nn h te args coInductiveTypeURI =
922 let module C = Cic in
923 (*CSC: There is a lot of code replication between the cases X and *)
924 (*CSC: (C.Appl X tl). Maybe it will be better to define a function *)
925 (*CSC: that maps X into (C.Appl X []) when X is not already a C.Appl *)
926 match CicReduction.whd context te with
927 C.Rel m when m > n && m <= nn -> h
935 raise (Impossible 17) (* the term has just been type-checked *)
936 | C.Lambda (name,so,de) ->
937 does_not_occur context n nn so &&
938 guarded_by_constructors ((Some (name,(C.Decl so)))::context)
939 (n + 1) (nn + 1) h de args coInductiveTypeURI
940 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
942 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
943 | C.Appl ((C.MutConstruct (uri,i,j,exp_named_subst))::tl) ->
945 match CicEnvironment.get_cooked_obj ~trust:false uri with
946 C.InductiveDefinition (itl,_,_) ->
947 let (_,_,_,cl) = List.nth itl i in
948 let (_,cons) = List.nth cl (j - 1) in
949 CicSubstitution.subst_vars exp_named_subst cons
951 raise (WrongUriToMutualInductiveDefinitions
952 (UriManager.string_of_uri uri))
954 let rec analyse_branch context ty te =
955 match CicReduction.whd context ty with
956 C.Meta _ -> raise (Impossible 34)
960 does_not_occur context n nn te
962 | C.Cast _ -> raise (Impossible 24) (* due to type-checking *)
963 | C.Prod (name,so,de) ->
964 analyse_branch ((Some (name,(C.Decl so)))::context) de te
966 | C.LetIn _ -> raise (Impossible 25) (* due to type-checking *)
967 | C.Appl ((C.MutInd (uri,_,_))::_) as ty
968 when uri == coInductiveTypeURI ->
969 guarded_by_constructors context n nn true te [] coInductiveTypeURI
970 | C.Appl ((C.MutInd (uri,_,_))::_) as ty ->
971 guarded_by_constructors context n nn true te tl coInductiveTypeURI
973 does_not_occur context n nn te
974 | C.Const _ -> raise (Impossible 26)
975 | C.MutInd (uri,_,_) when uri == coInductiveTypeURI ->
976 guarded_by_constructors context n nn true te [] coInductiveTypeURI
978 does_not_occur context n nn te
979 | C.MutConstruct _ -> raise (Impossible 27)
980 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
981 (*CSC: in head position. *)
984 | C.CoFix _ -> raise (Impossible 28) (* due to type-checking *)
986 let rec analyse_instantiated_type context ty l =
987 match CicReduction.whd context ty with
993 | C.Cast _ -> raise (Impossible 29) (* due to type-checking *)
994 | C.Prod (name,so,de) ->
999 analyse_branch context so he &&
1000 analyse_instantiated_type ((Some (name,(C.Decl so)))::context)
1004 | C.LetIn _ -> raise (Impossible 30) (* due to type-checking *)
1007 (fun i x -> i && does_not_occur context n nn x) true l
1008 | C.Const _ -> raise (Impossible 31)
1011 (fun i x -> i && does_not_occur context n nn x) true l
1012 | C.MutConstruct _ -> raise (Impossible 32)
1013 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
1014 (*CSC: in head position. *)
1017 | C.CoFix _ -> raise (Impossible 33) (* due to type-checking *)
1019 let rec instantiate_type args consty =
1022 | tlhe::tltl as l ->
1023 let consty' = CicReduction.whd context consty in
1029 let instantiated_de = CicSubstitution.subst he de in
1030 (*CSC: siamo sicuri che non sia troppo forte? *)
1031 does_not_occur context n nn tlhe &
1032 instantiate_type tl instantiated_de tltl
1034 (*CSC:We do not consider backbones with a MutCase, a *)
1035 (*CSC:FixPoint, a CoFixPoint and so on in head position.*)
1036 raise (Impossible 23)
1038 | [] -> analyse_instantiated_type context consty' l
1039 (* These are all the other cases *)
1041 instantiate_type args consty tl
1042 | C.Appl ((C.CoFix (_,fl))::tl) ->
1043 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1044 let len = List.length fl in
1045 let n_plus_len = n + len
1046 and nn_plus_len = nn + len
1047 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1048 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1051 i && does_not_occur context n nn ty &&
1052 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1053 args coInductiveTypeURI
1055 | C.Appl ((C.MutCase (_,_,out,te,pl))::tl) ->
1056 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1057 does_not_occur context n nn out &&
1058 does_not_occur context n nn te &&
1062 guarded_by_constructors context n nn h x args coInductiveTypeURI
1065 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
1066 | C.Var (_,exp_named_subst)
1067 | C.Const (_,exp_named_subst) ->
1069 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1070 | C.MutInd _ -> assert false
1071 | C.MutConstruct (_,_,_,exp_named_subst) ->
1073 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1074 | C.MutCase (_,_,out,te,pl) ->
1075 does_not_occur context n nn out &&
1076 does_not_occur context n nn te &&
1080 guarded_by_constructors context n nn h x args coInductiveTypeURI
1083 let len = List.length fl in
1084 let n_plus_len = n + len
1085 and nn_plus_len = nn + len
1086 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1087 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1089 (fun (_,_,ty,bo) i ->
1090 i && does_not_occur context n nn ty &&
1091 does_not_occur (tys@context) n_plus_len nn_plus_len bo
1094 let len = List.length fl in
1095 let n_plus_len = n + len
1096 and nn_plus_len = nn + len
1097 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1098 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1101 i && does_not_occur context n nn ty &&
1102 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1103 args coInductiveTypeURI
1106 and check_allowed_sort_elimination context uri i need_dummy ind arity1 arity2 =
1107 let module C = Cic in
1108 let module U = UriManager in
1109 match (CicReduction.whd context arity1, CicReduction.whd context arity2) with
1110 (C.Prod (_,so1,de1), C.Prod (_,so2,de2))
1111 when CicReduction.are_convertible context so1 so2 ->
1112 check_allowed_sort_elimination context uri i need_dummy
1113 (C.Appl [CicSubstitution.lift 1 ind ; C.Rel 1]) de1 de2
1114 | (C.Sort C.Prop, C.Sort C.Prop) when need_dummy -> true
1115 | (C.Sort C.Prop, C.Sort C.Set)
1116 | (C.Sort C.Prop, C.Sort C.Type) when need_dummy ->
1117 (*CSC: WRONG. MISSING CONDITIONS ON THE ARGUMENTS OF THE CONSTRUTOR *)
1118 (match CicEnvironment.get_obj uri with
1119 C.InductiveDefinition (itl,_,_) ->
1120 let (_,_,_,cl) = List.nth itl i in
1121 (* is a singleton definition or the empty proposition? *)
1122 List.length cl = 1 || List.length cl = 0
1124 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
1126 | (C.Sort C.Set, C.Sort C.Prop) when need_dummy -> true
1127 | (C.Sort C.Set, C.Sort C.Set) when need_dummy -> true
1128 | (C.Sort C.Set, C.Sort C.Type) when need_dummy ->
1129 (match CicEnvironment.get_obj uri with
1130 C.InductiveDefinition (itl,_,paramsno) ->
1132 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1134 let (_,_,_,cl) = List.nth itl i in
1136 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1138 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
1140 | (C.Sort C.Type, C.Sort _) when need_dummy -> true
1141 | (C.Sort C.Prop, C.Prod (name,so,ta)) when not need_dummy ->
1142 let res = CicReduction.are_convertible context so ind
1145 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1146 C.Sort C.Prop -> true
1148 (match CicEnvironment.get_obj uri with
1149 C.InductiveDefinition (itl,_,_) ->
1150 let (_,_,_,cl) = List.nth itl i in
1151 (* is a singleton definition? *)
1154 raise (WrongUriToMutualInductiveDefinitions
1155 (U.string_of_uri uri))
1159 | (C.Sort C.Set, C.Prod (name,so,ta)) when not need_dummy ->
1160 let res = CicReduction.are_convertible context so ind
1163 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1165 | C.Sort C.Set -> true
1167 (match CicEnvironment.get_obj uri with
1168 C.InductiveDefinition (itl,_,paramsno) ->
1169 let (_,_,_,cl) = List.nth itl i in
1172 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1175 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1177 raise (WrongUriToMutualInductiveDefinitions
1178 (U.string_of_uri uri))
1180 | _ -> raise (Impossible 19)
1182 | (C.Sort C.Type, C.Prod (_,so,_)) when not need_dummy ->
1183 CicReduction.are_convertible context so ind
1186 and type_of_branch context argsno need_dummy outtype term constype =
1187 let module C = Cic in
1188 let module R = CicReduction in
1189 match R.whd context constype with
1194 C.Appl [outtype ; term]
1195 | C.Appl (C.MutInd (_,_,_)::tl) ->
1196 let (_,arguments) = split tl argsno
1198 if need_dummy && arguments = [] then
1201 C.Appl (outtype::arguments@(if need_dummy then [] else [term]))
1202 | C.Prod (name,so,de) ->
1204 match CicSubstitution.lift 1 term with
1205 C.Appl l -> C.Appl (l@[C.Rel 1])
1206 | t -> C.Appl [t ; C.Rel 1]
1208 C.Prod (C.Anonymous,so,type_of_branch
1209 ((Some (name,(C.Decl so)))::context) argsno need_dummy
1210 (CicSubstitution.lift 1 outtype) term' de)
1211 | _ -> raise (Impossible 20)
1213 (* check_metasenv_consistency checks that the "canonical" context of a
1214 metavariable is consitent - up to relocation via the relocation list l -
1215 with the actual context *)
1217 and check_metasenv_consistency metasenv context canonical_context l =
1218 let module C = Cic in
1219 let module R = CicReduction in
1220 let module S = CicSubstitution in
1221 let lifted_canonical_context =
1225 | (Some (n,C.Decl t))::tl ->
1226 (Some (n,C.Decl (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1227 | (Some (n,C.Def t))::tl ->
1228 (Some (n,C.Def (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1229 | None::tl -> None::(aux (i+1) tl)
1231 aux 1 canonical_context
1238 | Some t,Some (_,C.Def ct) ->
1239 R.are_convertible context t ct
1240 | Some t,Some (_,C.Decl ct) ->
1241 R.are_convertible context (type_of_aux' metasenv context t) ct
1244 if not res then raise MetasenvInconsistency
1245 ) l lifted_canonical_context
1247 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
1248 and type_of_aux' metasenv context t =
1249 let rec type_of_aux context =
1250 let module C = Cic in
1251 let module R = CicReduction in
1252 let module S = CicSubstitution in
1253 let module U = UriManager in
1257 match List.nth context (n - 1) with
1258 Some (_,C.Decl t) -> S.lift n t
1259 | Some (_,C.Def bo) -> type_of_aux context (S.lift n bo)
1260 | None -> raise RelToHiddenHypothesis
1262 _ -> raise (NotWellTyped "Not a close term")
1264 | C.Var (uri,exp_named_subst) ->
1266 check_exp_named_subst context exp_named_subst ;
1268 CicSubstitution.subst_vars exp_named_subst (type_of_variable uri)
1273 let (_,canonical_context,ty) =
1274 List.find (function (m,_,_) -> n = m) metasenv
1276 check_metasenv_consistency metasenv context canonical_context l;
1277 CicSubstitution.lift_meta l ty
1278 | C.Sort s -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1279 | C.Implicit -> raise (Impossible 21)
1281 let _ = type_of_aux context ty in
1282 if R.are_convertible context (type_of_aux context te) ty then ty
1283 else raise (NotWellTyped "Cast")
1284 | C.Prod (name,s,t) ->
1285 let sort1 = type_of_aux context s
1286 and sort2 = type_of_aux ((Some (name,(C.Decl s)))::context) t in
1287 sort_of_prod context (name,s) (sort1,sort2)
1288 | C.Lambda (n,s,t) ->
1289 let sort1 = type_of_aux context s
1290 and type2 = type_of_aux ((Some (n,(C.Decl s)))::context) t in
1291 let sort2 = type_of_aux ((Some (n,(C.Decl s)))::context) type2 in
1292 (* only to check if the product is well-typed *)
1293 let _ = sort_of_prod context (n,s) (sort1,sort2) in
1295 | C.LetIn (n,s,t) ->
1296 (* only to check if s is well-typed *)
1297 let _ = type_of_aux context s in
1298 (* The type of a LetIn is a LetIn. Extremely slow since the computed
1299 LetIn is later reduced and maybe also re-checked.
1300 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t))
1302 (* The type of the LetIn is reduced. Much faster than the previous
1303 solution. Moreover the inferred type is probably very different
1304 from the expected one.
1305 (CicReduction.whd context
1306 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t)))
1308 (* One-step LetIn reduction. Even faster than the previous solution.
1309 Moreover the inferred type is closer to the expected one. *)
1310 (CicSubstitution.subst s
1311 (type_of_aux ((Some (n,(C.Def s)))::context) t))
1312 | C.Appl (he::tl) when List.length tl > 0 ->
1313 let hetype = type_of_aux context he
1314 and tlbody_and_type = List.map (fun x -> (x, type_of_aux context x)) tl in
1315 eat_prods context hetype tlbody_and_type
1316 | C.Appl _ -> raise (NotWellTyped "Appl: no arguments")
1317 | C.Const (uri,exp_named_subst) ->
1319 check_exp_named_subst context exp_named_subst ;
1321 CicSubstitution.subst_vars exp_named_subst (type_of_constant uri)
1325 | C.MutInd (uri,i,exp_named_subst) ->
1327 check_exp_named_subst context exp_named_subst ;
1329 CicSubstitution.subst_vars exp_named_subst
1330 (type_of_mutual_inductive_defs uri i)
1334 | C.MutConstruct (uri,i,j,exp_named_subst) ->
1335 check_exp_named_subst context exp_named_subst ;
1337 CicSubstitution.subst_vars exp_named_subst
1338 (type_of_mutual_inductive_constr uri i j)
1341 | C.MutCase (uri,i,outtype,term,pl) ->
1342 let outsort = type_of_aux context outtype in
1343 let (need_dummy, k) =
1344 let rec guess_args context t =
1345 match CicReduction.whd context t with
1346 C.Sort _ -> (true, 0)
1347 | C.Prod (name, s, t) ->
1348 let (b, n) = guess_args ((Some (name,(C.Decl s)))::context) t in
1350 (* last prod before sort *)
1351 match CicReduction.whd context s with
1352 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1353 C.MutInd (uri',i',_) when U.eq uri' uri && i' = i ->
1355 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1356 | C.Appl ((C.MutInd (uri',i',_)) :: _)
1357 when U.eq uri' uri && i' = i -> (false, 1)
1361 | _ -> raise (NotWellTyped "MutCase: outtype ill-formed")
1363 (*CSC whd non serve dopo type_of_aux ? *)
1364 let (b, k) = guess_args context outsort in
1365 if not b then (b, k - 1) else (b, k)
1367 let (parameters, arguments, exp_named_subst) =
1368 match R.whd context (type_of_aux context term) with
1369 (*CSC manca il caso dei CAST *)
1370 (*CSC: ma servono i parametri (uri,i)? Se si', perche' non serve anche il *)
1371 (*CSC: parametro exp_named_subst? Se no, perche' non li togliamo? *)
1372 (*CSC: Hint: nella DTD servono per gli stylesheet. *)
1373 C.MutInd (uri',i',exp_named_subst) as typ ->
1374 if U.eq uri uri' && i = i' then ([],[],exp_named_subst)
1375 else raise (NotWellTyped ("MutCase: the term is of type " ^
1377 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1378 string_of_int i ^ "{_}"))
1379 | C.Appl ((C.MutInd (uri',i',exp_named_subst) as typ):: tl) ->
1380 if U.eq uri uri' && i = i' then
1382 split tl (List.length tl - k)
1383 in params,args,exp_named_subst
1384 else raise (NotWellTyped ("MutCase: the term is of type " ^
1386 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1387 string_of_int i ^ "{_}"))
1388 | _ -> raise (NotWellTyped "MutCase: the term is not an inductive one")
1390 (* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
1391 let sort_of_ind_type =
1392 if parameters = [] then
1393 C.MutInd (uri,i,exp_named_subst)
1395 C.Appl ((C.MutInd (uri,i,exp_named_subst))::parameters)
1397 if not (check_allowed_sort_elimination context uri i need_dummy
1398 sort_of_ind_type (type_of_aux context sort_of_ind_type) outsort)
1400 raise (NotWellTyped "MutCase: not allowed sort elimination") ;
1402 (* let's check if the type of branches are right *)
1404 match CicEnvironment.get_cooked_obj ~trust:false uri with
1405 C.InductiveDefinition (_,_,parsno) -> parsno
1407 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
1409 let (_,branches_ok) =
1413 if parameters = [] then
1414 (C.MutConstruct (uri,i,j,exp_named_subst))
1416 (C.Appl (C.MutConstruct (uri,i,j,exp_named_subst)::parameters))
1423 R.are_convertible context (type_of_aux context p)
1424 (type_of_branch context parsno need_dummy outtype cons
1425 (type_of_aux context cons))
1426 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
1430 if not branches_ok then
1431 raise (NotWellTyped "MutCase: wrong type of a branch") ;
1433 if not need_dummy then
1434 C.Appl ((outtype::arguments)@[term])
1435 else if arguments = [] then
1438 C.Appl (outtype::arguments)
1440 let types_times_kl =
1444 let _ = type_of_aux context ty in
1445 (Some (C.Name n,(C.Decl ty)),k)) fl)
1447 let (types,kl) = List.split types_times_kl in
1448 let len = List.length types in
1450 (fun (name,x,ty,bo) ->
1452 (R.are_convertible (types@context) (type_of_aux (types@context) bo)
1453 (CicSubstitution.lift len ty))
1456 let (m, eaten, context') =
1457 eat_lambdas (types @ context) (x + 1) bo
1459 (*let's control the guarded by destructors conditions D{f,k,x,M}*)
1462 (guarded_by_destructors context' eaten (len + eaten) kl 1 [] m)
1464 raise (NotWellTyped "Fix: not guarded by destructors")
1467 raise (NotWellTyped "Fix: ill-typed bodies")
1470 (*CSC: controlli mancanti solo su D{f,k,x,M} *)
1471 let (_,_,ty,_) = List.nth fl i in
1478 let _ = type_of_aux context ty in Some (C.Name n,(C.Decl ty))) fl)
1480 let len = List.length types in
1484 (R.are_convertible (types @ context)
1485 (type_of_aux (types @ context) bo) (CicSubstitution.lift len ty))
1488 (* let's control that the returned type is coinductive *)
1489 match returns_a_coinductive context ty with
1491 raise(NotWellTyped "CoFix: does not return a coinductive type")
1493 (*let's control the guarded by constructors conditions C{f,M}*)
1496 (guarded_by_constructors (types @ context) 0 len false bo
1499 raise (NotWellTyped "CoFix: not guarded by constructors")
1502 raise (NotWellTyped "CoFix: ill-typed bodies")
1505 let (_,ty,_) = List.nth fl i in
1508 and check_exp_named_subst context =
1509 let rec check_exp_named_subst_aux substs =
1512 | ((uri,t) as subst)::tl ->
1514 CicSubstitution.subst_vars substs (type_of_variable uri) in
1515 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1516 Cic.Variable (_,Some bo,_,_) ->
1519 "A variable with a body can not be explicit substituted")
1520 | Cic.Variable (_,None,_,_) -> ()
1521 | _ -> raise (WrongUriToVariable (UriManager.string_of_uri uri))
1523 let typeoft = type_of_aux context t in
1524 if CicReduction.are_convertible context typeoft typeofvar then
1525 check_exp_named_subst_aux (substs@[subst]) tl
1528 CicReduction.fdebug := 0 ;
1529 ignore (CicReduction.are_convertible context typeoft typeofvar) ;
1531 debug typeoft [typeofvar] ;
1532 raise (NotWellTyped "Wrong Explicit Named Substitution")
1535 check_exp_named_subst_aux []
1537 and sort_of_prod context (name,s) (t1, t2) =
1538 let module C = Cic in
1539 let t1' = CicReduction.whd context t1 in
1540 let t2' = CicReduction.whd ((Some (name,C.Decl s))::context) t2 in
1541 match (t1', t2') with
1542 (C.Sort s1, C.Sort s2)
1543 when (s2 = C.Prop or s2 = C.Set) -> (* different from Coq manual!!! *)
1545 | (C.Sort s1, C.Sort s2) -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1549 ("Prod: sort1= " ^ CicPp.ppterm t1' ^ " ; sort2= " ^ CicPp.ppterm t2'))
1551 and eat_prods context hetype =
1552 (*CSC: siamo sicuri che le are_convertible non lavorino con termini non *)
1556 | (hete, hety)::tl ->
1557 (match (CicReduction.whd context hetype) with
1559 if CicReduction.are_convertible context s hety then
1560 (CicReduction.fdebug := -1 ;
1561 eat_prods context (CicSubstitution.subst hete t) tl
1565 CicReduction.fdebug := 0 ;
1566 ignore (CicReduction.are_convertible context s hety) ;
1569 raise (NotWellTyped "Appl: wrong parameter-type")
1571 | _ -> raise (NotWellTyped "Appl: wrong Prod-type")
1574 and returns_a_coinductive context ty =
1575 let module C = Cic in
1576 match CicReduction.whd context ty with
1577 C.MutInd (uri,i,_) ->
1578 (*CSC: definire una funzioncina per questo codice sempre replicato *)
1579 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1580 C.InductiveDefinition (itl,_,_) ->
1581 let (_,is_inductive,_,_) = List.nth itl i in
1582 if is_inductive then None else (Some uri)
1584 raise (WrongUriToMutualInductiveDefinitions
1585 (UriManager.string_of_uri uri))
1587 | C.Appl ((C.MutInd (uri,i,_))::_) ->
1588 (match CicEnvironment.get_obj uri with
1589 C.InductiveDefinition (itl,_,_) ->
1590 let (_,is_inductive,_,_) = List.nth itl i in
1591 if is_inductive then None else (Some uri)
1593 raise (WrongUriToMutualInductiveDefinitions
1594 (UriManager.string_of_uri uri))
1596 | C.Prod (n,so,de) ->
1597 returns_a_coinductive ((Some (n,C.Decl so))::context) de
1602 prerr_endline ("INIZIO TYPE_OF_AUX " ^ CicPp.ppterm t) ; flush stderr ;
1605 type_of_aux context t
1607 in prerr_endline "FINE TYPE_OF_AUX" ; flush stderr ; res
1610 (* is a small constructor? *)
1611 (*CSC: ottimizzare calcolando staticamente *)
1612 and is_small context paramsno c =
1613 let rec is_small_aux context c =
1614 let module C = Cic in
1615 match CicReduction.whd context c with
1617 (*CSC: [] is an empty metasenv. Is it correct? *)
1618 let s = type_of_aux' [] context so in
1619 (s = C.Sort C.Prop || s = C.Sort C.Set) &&
1620 is_small_aux ((Some (n,(C.Decl so)))::context) de
1621 | _ -> true (*CSC: we trust the type-checker *)
1623 let (context',dx) = split_prods context paramsno c in
1624 is_small_aux context' dx
1628 prerr_endline ("INIZIO TYPE_OF_AUX' " ^ CicPp.ppterm t) ; flush stderr ;
1631 type_of_aux' [] [] t
1633 in prerr_endline "FINE TYPE_OF_AUX'" ; flush stderr ; res
1638 let module C = Cic in
1639 let module R = CicReduction in
1640 let module U = UriManager in
1641 match CicEnvironment.is_type_checked ~trust:false uri with
1642 CicEnvironment.CheckedObj _ -> ()
1643 | CicEnvironment.UncheckedObj uobj ->
1644 (* let's typecheck the uncooked object *)
1645 Logger.log (`Start_type_checking uri) ;
1647 C.Constant (_,Some te,ty,_) ->
1648 let _ = type_of ty in
1649 if not (R.are_convertible [] (type_of te ) ty) then
1650 raise (NotWellTyped ("Constant " ^ (U.string_of_uri uri)))
1651 | C.Constant (_,None,ty,_) ->
1652 (* only to check that ty is well-typed *)
1653 let _ = type_of ty in ()
1654 | C.CurrentProof (_,conjs,te,ty,_) ->
1657 (fun metasenv ((_,context,ty) as conj) ->
1658 ignore (type_of_aux' metasenv context ty) ;
1662 let _ = type_of_aux' conjs [] ty in
1663 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
1665 raise (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri)))
1666 | C.Variable (_,bo,ty,_) ->
1667 (* only to check that ty is well-typed *)
1668 let _ = type_of ty in
1672 if not (R.are_convertible [] (type_of bo) ty) then
1673 raise (NotWellTyped ("Variable" ^ (U.string_of_uri uri)))
1675 | C.InductiveDefinition _ ->
1676 check_mutual_inductive_defs uri uobj
1678 CicEnvironment.set_type_checking_info uri ;
1679 Logger.log (`Type_checking_completed uri)