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 =
62 | C.Var (uri,exp_named_subst) ->
63 let exp_named_subst' =
64 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
66 C.Var (uri,exp_named_subst')
67 | C.Meta _ -> assert false
69 | C.Implicit as t -> t
70 | C.Cast (te,ty) -> C.Cast (aux k te, aux k ty)
71 | C.Prod (n,s,t) -> C.Prod (n, aux k s, aux (k+1) t)
72 | C.Lambda (n,s,t) -> C.Lambda (n, aux k s, aux (k+1) t)
73 | C.LetIn (n,s,t) -> C.LetIn (n, aux k s, aux (k+1) t)
74 | C.Appl l -> C.Appl (List.map (aux k) l)
75 | C.Const (uri,exp_named_subst) ->
76 let exp_named_subst' =
77 List.map (function (uri,t) -> (uri,aux k t)) exp_named_subst
79 C.Const (uri,exp_named_subst')
80 | C.MutInd (uri',tyno,exp_named_subst) when UriManager.eq uri uri' ->
81 if exp_named_subst != [] then
84 ("Debrujin: a 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 uri with
128 CicEnvironment.CheckedObj cobj -> cobj
129 | CicEnvironment.UncheckedObj uobj ->
130 Logger.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 if not (R.are_convertible [] (type_of te) ty) then
136 raise (NotWellTyped ("Constant " ^ (U.string_of_uri uri)))
137 | C.Constant (_,None,ty,_) ->
138 (* only to check that ty is well-typed *)
139 let _ = type_of ty in ()
140 | C.CurrentProof (_,conjs,te,ty,_) ->
141 (*CSC: bisogna controllare anche il metasenv!!! *)
142 let _ = type_of_aux' conjs [] ty in
143 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty)
145 raise (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri)))
146 | _ -> raise (WrongUriToConstant (U.string_of_uri uri))
148 CicEnvironment.set_type_checking_info uri ;
149 Logger.log (`Type_checking_completed uri) ;
150 match CicEnvironment.is_type_checked uri with
151 CicEnvironment.CheckedObj cobj -> cobj
152 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
155 C.Constant (_,_,ty,_) -> ty
156 | C.CurrentProof (_,_,_,ty,_) -> ty
157 | _ -> raise (WrongUriToConstant (U.string_of_uri uri))
159 and type_of_variable uri =
160 let module C = Cic in
161 let module R = CicReduction in
162 let module U = UriManager in
163 (* 0 because a variable is never cooked => no partial cooking at one level *)
164 match CicEnvironment.is_type_checked uri with
165 CicEnvironment.CheckedObj (C.Variable (_,_,ty,_)) -> ty
166 | CicEnvironment.UncheckedObj (C.Variable (_,bo,ty,_)) ->
167 Logger.log (`Start_type_checking uri) ;
168 (* only to check that ty is well-typed *)
169 let _ = type_of ty in
173 if not (R.are_convertible [] (type_of bo) ty) then
174 raise (NotWellTyped ("Variable " ^ (U.string_of_uri uri)))
176 CicEnvironment.set_type_checking_info uri ;
177 Logger.log (`Type_checking_completed uri) ;
179 | _ -> raise (WrongUriToVariable (UriManager.string_of_uri uri))
181 and does_not_occur context n nn te =
182 let module C = Cic in
183 (*CSC: whd sembra essere superflua perche' un caso in cui l'occorrenza *)
184 (*CSC: venga mangiata durante la whd sembra presentare problemi di *)
186 match CicReduction.whd context te with
187 C.Rel m when m > n && m <= nn -> false
193 does_not_occur context n nn te && does_not_occur context n nn ty
194 | C.Prod (name,so,dest) ->
195 does_not_occur context n nn so &&
196 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1) dest
197 | C.Lambda (name,so,dest) ->
198 does_not_occur context n nn so &&
199 does_not_occur((Some (name,(C.Decl so)))::context) (n + 1) (nn + 1) dest
200 | C.LetIn (name,so,dest) ->
201 does_not_occur context n nn so &&
202 does_not_occur ((Some (name,(C.Def so)))::context) (n + 1) (nn + 1) dest
204 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
205 | C.Var (_,exp_named_subst)
206 | C.Const (_,exp_named_subst)
207 | C.MutInd (_,_,exp_named_subst)
208 | C.MutConstruct (_,_,_,exp_named_subst) ->
209 List.fold_right (fun (_,x) i -> i && does_not_occur context n nn x)
211 | C.MutCase (_,_,out,te,pl) ->
212 does_not_occur context n nn out && does_not_occur context n nn te &&
213 List.fold_right (fun x i -> i && does_not_occur context n nn x) pl true
215 let len = List.length fl in
216 let n_plus_len = n + len in
217 let nn_plus_len = nn + len in
219 List.map (fun (n,_,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
222 (fun (_,_,ty,bo) i ->
223 i && does_not_occur context n nn ty &&
224 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
227 let len = List.length fl in
228 let n_plus_len = n + len in
229 let nn_plus_len = nn + len in
231 List.map (fun (n,ty,_) -> Some (C.Name n,(Cic.Decl ty))) fl
235 i && does_not_occur context n nn ty &&
236 does_not_occur (tys @ context) n_plus_len nn_plus_len bo
239 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
240 (*CSC questa funzione e' simile alla are_all_occurrences_positive, ma fa *)
241 (*CSC dei controlli leggermente diversi. Viene invocata solamente dalla *)
242 (*CSC strictly_positive *)
243 (*CSC definizione (giusta???) tratta dalla mail di Hugo ;-) *)
244 and weakly_positive context n nn uri te =
245 let module C = Cic in
246 (*CSC: Che schifo! Bisogna capire meglio e trovare una soluzione ragionevole!*)
248 C.MutInd (UriManager.uri_of_string "cic:/Coq/Init/Datatypes/nat.ind",0,[])
250 (*CSC mettere in cicSubstitution *)
251 let rec subst_inductive_type_with_dummy_mutind =
253 C.MutInd (uri',0,_) when UriManager.eq uri' uri ->
255 | C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri ->
257 | C.Cast (te,ty) -> subst_inductive_type_with_dummy_mutind te
258 | C.Prod (name,so,ta) ->
259 C.Prod (name, subst_inductive_type_with_dummy_mutind so,
260 subst_inductive_type_with_dummy_mutind ta)
261 | C.Lambda (name,so,ta) ->
262 C.Lambda (name, subst_inductive_type_with_dummy_mutind so,
263 subst_inductive_type_with_dummy_mutind ta)
265 C.Appl (List.map subst_inductive_type_with_dummy_mutind tl)
266 | C.MutCase (uri,i,outtype,term,pl) ->
268 subst_inductive_type_with_dummy_mutind outtype,
269 subst_inductive_type_with_dummy_mutind term,
270 List.map subst_inductive_type_with_dummy_mutind pl)
272 C.Fix (i,List.map (fun (name,i,ty,bo) -> (name,i,
273 subst_inductive_type_with_dummy_mutind ty,
274 subst_inductive_type_with_dummy_mutind bo)) fl)
276 C.CoFix (i,List.map (fun (name,ty,bo) -> (name,
277 subst_inductive_type_with_dummy_mutind ty,
278 subst_inductive_type_with_dummy_mutind bo)) fl)
279 | C.Const (uri,exp_named_subst) ->
280 let exp_named_subst' =
282 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
285 C.Const (uri,exp_named_subst')
286 | C.MutInd (uri,typeno,exp_named_subst) ->
287 let exp_named_subst' =
289 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
292 C.MutInd (uri,typeno,exp_named_subst')
293 | C.MutConstruct (uri,typeno,consno,exp_named_subst) ->
294 let exp_named_subst' =
296 (function (uri,t) -> (uri,subst_inductive_type_with_dummy_mutind t))
299 C.MutConstruct (uri,typeno,consno,exp_named_subst')
302 match CicReduction.whd context te with
303 C.Appl ((C.MutInd (uri',0,_))::tl) when UriManager.eq uri' uri -> true
304 | C.MutInd (uri',0,_) when UriManager.eq uri' uri -> true
305 | C.Prod (C.Anonymous,source,dest) ->
306 strictly_positive context n nn
307 (subst_inductive_type_with_dummy_mutind source) &&
308 weakly_positive ((Some (C.Anonymous,(C.Decl source)))::context)
309 (n + 1) (nn + 1) uri dest
310 | C.Prod (name,source,dest) when
311 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
312 (* dummy abstraction, so we behave as in the anonimous case *)
313 strictly_positive context n nn
314 (subst_inductive_type_with_dummy_mutind source) &&
315 weakly_positive ((Some (name,(C.Decl source)))::context)
316 (n + 1) (nn + 1) uri dest
317 | C.Prod (name,source,dest) ->
318 does_not_occur context n nn
319 (subst_inductive_type_with_dummy_mutind source)&&
320 weakly_positive ((Some (name,(C.Decl source)))::context)
321 (n + 1) (nn + 1) uri dest
322 | _ -> raise (NotWellFormedTypeOfInductiveConstructor ("Guess where the error is ;-)"))
324 (* instantiate_parameters ps (x1:T1)...(xn:Tn)C *)
325 (* returns ((x_|ps|:T_|ps|)...(xn:Tn)C){ps_1 / x1 ; ... ; ps_|ps| / x_|ps|} *)
326 and instantiate_parameters params c =
327 let module C = Cic in
328 match (c,params) with
330 | (C.Prod (_,_,ta), he::tl) ->
331 instantiate_parameters tl
332 (CicSubstitution.subst he ta)
333 | (C.Cast (te,_), _) -> instantiate_parameters params te
334 | (t,l) -> raise (Impossible 1)
336 and strictly_positive context n nn te =
337 let module C = Cic in
338 let module U = UriManager in
339 match CicReduction.whd context te with
342 (*CSC: bisogna controllare ty????*)
343 strictly_positive context n nn te
344 | C.Prod (name,so,ta) ->
345 does_not_occur context n nn so &&
346 strictly_positive ((Some (name,(C.Decl so)))::context) (n+1) (nn+1) ta
347 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
348 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
349 | C.Appl ((C.MutInd (uri,i,exp_named_subst))::tl) ->
350 let (ok,paramsno,ity,cl,name) =
351 match CicEnvironment.get_obj uri with
352 C.InductiveDefinition (tl,_,paramsno) ->
353 let (name,_,ity,cl) = List.nth tl i in
354 (List.length tl = 1, paramsno, ity, cl, name)
355 | _ -> raise(WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
357 let (params,arguments) = split tl paramsno in
358 let lifted_params = List.map (CicSubstitution.lift 1) params in
362 instantiate_parameters lifted_params
363 (CicSubstitution.subst_vars exp_named_subst te)
368 (fun x i -> i && does_not_occur context n nn x)
370 (*CSC: MEGAPATCH3 (sara' quella giusta?)*)
375 ((Some (C.Name name,(Cic.Decl ity)))::context) (n+1) (nn+1) uri x
377 | t -> does_not_occur context n nn t
379 (*CSC l'indice x dei tipi induttivi e' t.c. n < x <= nn *)
380 and are_all_occurrences_positive context uri indparamsno i n nn te =
381 let module C = Cic in
382 match CicReduction.whd context te with
383 C.Appl ((C.Rel m)::tl) when m = i ->
384 (*CSC: riscrivere fermandosi a 0 *)
385 (* let's check if the inductive type is applied at least to *)
386 (* indparamsno parameters *)
392 match CicReduction.whd context x with
393 C.Rel m when m = n - (indparamsno - k) -> k - 1
394 | _ -> raise (WrongRequiredArgument (UriManager.string_of_uri uri))
398 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
400 raise (WrongRequiredArgument (UriManager.string_of_uri uri))
401 | C.Rel m when m = i ->
402 if indparamsno = 0 then
405 raise (WrongRequiredArgument (UriManager.string_of_uri uri))
406 | C.Prod (C.Anonymous,source,dest) ->
407 strictly_positive context n nn source &&
408 are_all_occurrences_positive
409 ((Some (C.Anonymous,(C.Decl source)))::context) uri indparamsno
410 (i+1) (n + 1) (nn + 1) dest
411 | C.Prod (name,source,dest) when
412 does_not_occur ((Some (name,(C.Decl source)))::context) 0 n dest ->
413 (* dummy abstraction, so we behave as in the anonimous case *)
414 strictly_positive context n nn source &&
415 are_all_occurrences_positive
416 ((Some (name,(C.Decl source)))::context) uri indparamsno
417 (i+1) (n + 1) (nn + 1) dest
418 | C.Prod (name,source,dest) ->
419 does_not_occur context n nn source &&
420 are_all_occurrences_positive ((Some (name,(C.Decl source)))::context)
421 uri indparamsno (i+1) (n + 1) (nn + 1) dest
422 | _ -> raise (NotWellFormedTypeOfInductiveConstructor (UriManager.string_of_uri uri))
424 (* Main function to checks the correctness of a mutual *)
425 (* inductive block definition. *)
426 and check_mutual_inductive_defs uri =
427 let module U = UriManager in
429 Cic.InductiveDefinition (itl, _, indparamsno) ->
430 (* let's check if the arity of the inductive types are well *)
432 List.iter (fun (_,_,x,_) -> let _ = type_of x in ()) itl ;
434 (* let's check if the types of the inductive constructors *)
435 (* are well formed. *)
436 (* In order not to use type_of_aux we put the types of the *)
437 (* mutual inductive types at the head of the types of the *)
438 (* constructors using Prods *)
439 let len = List.length itl in
441 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl in
447 let debrujinedte = debrujin_constructor uri len te in
450 (fun (name,_,ty,_) i -> Cic.Prod (Cic.Name name, ty, i))
453 let _ = type_of augmented_term in
454 (* let's check also the positivity conditions *)
457 (are_all_occurrences_positive tys uri indparamsno i 0 len
460 raise (NotPositiveOccurrences (U.string_of_uri uri))
467 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
469 and type_of_mutual_inductive_defs uri i =
470 let module C = Cic in
471 let module R = CicReduction in
472 let module U = UriManager in
474 match CicEnvironment.is_type_checked uri with
475 CicEnvironment.CheckedObj cobj -> cobj
476 | CicEnvironment.UncheckedObj uobj ->
477 Logger.log (`Start_type_checking uri) ;
478 check_mutual_inductive_defs uri uobj ;
479 CicEnvironment.set_type_checking_info uri ;
480 Logger.log (`Type_checking_completed uri) ;
481 (match CicEnvironment.is_type_checked uri with
482 CicEnvironment.CheckedObj cobj -> cobj
483 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
487 C.InductiveDefinition (dl,_,_) ->
488 let (_,_,arity,_) = List.nth dl i in
490 | _ -> raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
492 and type_of_mutual_inductive_constr uri i j =
493 let module C = Cic in
494 let module R = CicReduction in
495 let module U = UriManager in
497 match CicEnvironment.is_type_checked uri with
498 CicEnvironment.CheckedObj cobj -> cobj
499 | CicEnvironment.UncheckedObj uobj ->
500 Logger.log (`Start_type_checking uri) ;
501 check_mutual_inductive_defs uri uobj ;
502 CicEnvironment.set_type_checking_info uri ;
503 Logger.log (`Type_checking_completed uri) ;
504 (match CicEnvironment.is_type_checked uri with
505 CicEnvironment.CheckedObj cobj -> cobj
506 | CicEnvironment.UncheckedObj _ -> raise CicEnvironmentError
510 C.InductiveDefinition (dl,_,_) ->
511 let (_,_,_,cl) = List.nth dl i in
512 let (_,ty) = List.nth cl (j-1) in
514 | _ -> raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
516 and recursive_args context n nn te =
517 let module C = Cic in
518 match CicReduction.whd context te with
524 | C.Cast _ (*CSC ??? *) -> raise (Impossible 3) (* due to type-checking *)
525 | C.Prod (name,so,de) ->
526 (not (does_not_occur context n nn so)) ::
527 (recursive_args ((Some (name,(C.Decl so)))::context) (n+1) (nn + 1) de)
529 | C.LetIn _ -> raise (Impossible 4) (* due to type-checking *)
531 | C.Const _ -> raise (Impossible 5)
536 | C.CoFix _ -> raise (Impossible 6) (* due to type-checking *)
538 and get_new_safes context p c rl safes n nn x =
539 let module C = Cic in
540 let module U = UriManager in
541 let module R = CicReduction in
542 match (R.whd context c, R.whd context p, rl) with
543 (C.Prod (_,so,ta1), C.Lambda (name,_,ta2), b::tl) ->
544 (* we are sure that the two sources are convertible because we *)
545 (* have just checked this. So let's go along ... *)
547 List.map (fun x -> x + 1) safes
550 if b then 1::safes' else safes'
552 get_new_safes ((Some (name,(C.Decl so)))::context)
553 ta2 ta1 tl safes'' (n+1) (nn+1) (x+1)
554 | (C.Prod _, (C.MutConstruct _ as e), _)
555 | (C.Prod _, (C.Rel _ as e), _)
556 | (C.MutInd _, e, [])
557 | (C.Appl _, e, []) -> (e,safes,n,nn,x,context)
559 (* CSC: If the next exception is raised, it just means that *)
560 (* CSC: the proof-assistant allows to use very strange things *)
561 (* CSC: as a branch of a case whose type is a Prod. In *)
562 (* CSC: particular, this means that a new (C.Prod, x,_) case *)
563 (* CSC: must be considered in this match. (e.g. x = MutCase) *)
566 and split_prods context n te =
567 let module C = Cic in
568 let module R = CicReduction in
569 match (n, R.whd context te) with
571 | (n, C.Prod (name,so,ta)) when n > 0 ->
572 split_prods ((Some (name,(C.Decl so)))::context) (n - 1) ta
573 | (_, _) -> raise (Impossible 8)
575 and eat_lambdas context n te =
576 let module C = Cic in
577 let module R = CicReduction in
578 match (n, R.whd context te) with
579 (0, _) -> (te, 0, context)
580 | (n, C.Lambda (name,so,ta)) when n > 0 ->
581 let (te, k, context') =
582 eat_lambdas ((Some (name,(C.Decl so)))::context) (n - 1) ta
584 (te, k + 1, context')
585 | (_, _) -> raise (Impossible 9)
587 (*CSC: Tutto quello che segue e' l'intuzione di luca ;-) *)
588 and check_is_really_smaller_arg context n nn kl x safes te =
589 (*CSC: forse la whd si puo' fare solo quando serve veramente. *)
590 (*CSC: cfr guarded_by_destructors *)
591 let module C = Cic in
592 let module U = UriManager in
593 match CicReduction.whd context te with
594 C.Rel m when List.mem m safes -> true
601 (* | C.Cast (te,ty) ->
602 check_is_really_smaller_arg n nn kl x safes te &&
603 check_is_really_smaller_arg n nn kl x safes ty*)
604 (* | C.Prod (_,so,ta) ->
605 check_is_really_smaller_arg n nn kl x safes so &&
606 check_is_really_smaller_arg (n+1) (nn+1) kl (x+1)
607 (List.map (fun x -> x + 1) safes) ta*)
608 | C.Prod _ -> raise (Impossible 10)
609 | C.Lambda (name,so,ta) ->
610 check_is_really_smaller_arg context n nn kl x safes so &&
611 check_is_really_smaller_arg ((Some (name,(C.Decl so)))::context)
612 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
613 | C.LetIn (name,so,ta) ->
614 check_is_really_smaller_arg context n nn kl x safes so &&
615 check_is_really_smaller_arg ((Some (name,(C.Def so)))::context)
616 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
618 (*CSC: sulla coda ci vogliono dei controlli? secondo noi no, ma *)
619 (*CSC: solo perche' non abbiamo trovato controesempi *)
620 check_is_really_smaller_arg context n nn kl x safes he
621 | C.Appl [] -> raise (Impossible 11)
623 | C.MutInd _ -> raise (Impossible 12)
624 | C.MutConstruct _ -> false
625 | C.MutCase (uri,i,outtype,term,pl) ->
627 C.Rel m when List.mem m safes || m = x ->
628 let (tys,len,isinductive,paramsno,cl) =
629 match CicEnvironment.get_obj uri with
630 C.InductiveDefinition (tl,_,paramsno) ->
632 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) tl
634 let (_,isinductive,_,cl) = List.nth tl i in
638 (id, ty, snd (split_prods tys paramsno ty))) cl
640 (tys,List.length tl,isinductive,paramsno,cl')
642 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
644 if not isinductive then
647 i && check_is_really_smaller_arg context n nn kl x safes p)
651 (fun (p,(_,te,c)) i ->
653 let debrujinedte = debrujin_constructor uri len te in
654 recursive_args tys 0 len debrujinedte
656 let (e,safes',n',nn',x',context') =
657 get_new_safes context p c rl' safes n nn x
660 check_is_really_smaller_arg context' n' nn' kl x' safes' e
661 ) (List.combine pl cl) true
662 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
663 let (tys,len,isinductive,paramsno,cl) =
664 match CicEnvironment.get_obj uri with
665 C.InductiveDefinition (tl,_,paramsno) ->
666 let (_,isinductive,_,cl) = List.nth tl i in
668 List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
673 (id, ty, snd (split_prods tys paramsno ty))) cl
675 (tys,List.length tl,isinductive,paramsno,cl')
677 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
679 if not isinductive then
682 i && check_is_really_smaller_arg context n nn kl x safes p)
685 (*CSC: supponiamo come prima che nessun controllo sia necessario*)
686 (*CSC: sugli argomenti di una applicazione *)
688 (fun (p,(_,te,c)) i ->
690 let debrujinedte = debrujin_constructor uri len te in
691 recursive_args tys 0 len debrujinedte
693 let (e, safes',n',nn',x',context') =
694 get_new_safes context p c rl' safes n nn x
697 check_is_really_smaller_arg context' n' nn' kl x' safes' e
698 ) (List.combine pl cl) true
702 i && check_is_really_smaller_arg context n nn kl x safes p
706 let len = List.length fl in
707 let n_plus_len = n + len
708 and nn_plus_len = nn + len
709 and x_plus_len = x + len
710 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
711 and safes' = List.map (fun x -> x + len) safes in
713 (fun (_,_,ty,bo) i ->
715 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
719 let len = List.length fl in
720 let n_plus_len = n + len
721 and nn_plus_len = nn + len
722 and x_plus_len = x + len
723 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
724 and safes' = List.map (fun x -> x + len) safes in
728 check_is_really_smaller_arg (tys@context) n_plus_len nn_plus_len kl
732 and guarded_by_destructors context n nn kl x safes =
733 let module C = Cic in
734 let module U = UriManager in
736 C.Rel m when m > n && m <= nn -> false
738 (match List.nth context (n-1) with
739 Some (_,C.Decl _) -> true
740 | Some (_,C.Def bo) -> guarded_by_destructors context n nn kl x safes bo
741 | None -> raise RelToHiddenHypothesis
747 guarded_by_destructors context n nn kl x safes te &&
748 guarded_by_destructors context n nn kl x safes ty
749 | C.Prod (name,so,ta) ->
750 guarded_by_destructors context n nn kl x safes so &&
751 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
752 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
753 | C.Lambda (name,so,ta) ->
754 guarded_by_destructors context n nn kl x safes so &&
755 guarded_by_destructors ((Some (name,(C.Decl so)))::context)
756 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
757 | C.LetIn (name,so,ta) ->
758 guarded_by_destructors context n nn kl x safes so &&
759 guarded_by_destructors ((Some (name,(C.Def so)))::context)
760 (n+1) (nn+1) kl (x+1) (List.map (fun x -> x + 1) safes) ta
761 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
762 let k = List.nth kl (m - n - 1) in
763 if not (List.length tl > k) then false
767 i && guarded_by_destructors context n nn kl x safes param
769 check_is_really_smaller_arg context n nn kl x safes (List.nth tl k)
772 (fun t i -> i && guarded_by_destructors context n nn kl x safes t)
774 | C.Var (_,exp_named_subst)
775 | C.Const (_,exp_named_subst)
776 | C.MutInd (_,_,exp_named_subst)
777 | C.MutConstruct (_,_,_,exp_named_subst) ->
779 (fun (_,t) i -> i && guarded_by_destructors context n nn kl x safes t)
781 | C.MutCase (uri,i,outtype,term,pl) ->
783 C.Rel m when List.mem m safes || m = x ->
784 let (tys,len,isinductive,paramsno,cl) =
785 match CicEnvironment.get_obj uri with
786 C.InductiveDefinition (tl,_,paramsno) ->
787 let (_,isinductive,_,cl) = List.nth tl i in
789 List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
794 (id, ty, snd (split_prods tys paramsno ty))) cl
796 (tys,List.length tl,isinductive,paramsno,cl')
798 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
800 if not isinductive then
801 guarded_by_destructors context n nn kl x safes outtype &&
802 guarded_by_destructors context n nn kl x safes term &&
803 (*CSC: manca ??? il controllo sul tipo di term? *)
806 i && guarded_by_destructors context n nn kl x safes p)
809 guarded_by_destructors context n nn kl x safes outtype &&
810 (*CSC: manca ??? il controllo sul tipo di term? *)
812 (fun (p,(_,te,c)) i ->
814 let debrujinedte = debrujin_constructor uri len te in
815 recursive_args tys 0 len debrujinedte
817 let (e,safes',n',nn',x',context') =
818 get_new_safes context p c rl' safes n nn x
821 guarded_by_destructors context' n' nn' kl x' safes' e
822 ) (List.combine pl cl) true
823 | C.Appl ((C.Rel m)::tl) when List.mem m safes || m = x ->
824 let (tys,len,isinductive,paramsno,cl) =
825 match CicEnvironment.get_obj uri with
826 C.InductiveDefinition (tl,_,paramsno) ->
827 let (_,isinductive,_,cl) = List.nth tl i in
829 List.map (fun (n,_,ty,_) -> Some(Cic.Name n,(Cic.Decl ty))) tl
834 (id, ty, snd (split_prods tys paramsno ty))) cl
836 (tys,List.length tl,isinductive,paramsno,cl')
838 raise (WrongUriToMutualInductiveDefinitions(U.string_of_uri uri))
840 if not isinductive then
841 guarded_by_destructors context n nn kl x safes outtype &&
842 guarded_by_destructors context n nn kl x safes term &&
843 (*CSC: manca ??? il controllo sul tipo di term? *)
846 i && guarded_by_destructors context n nn kl x safes p)
849 guarded_by_destructors context n nn kl x safes outtype &&
850 (*CSC: manca ??? il controllo sul tipo di term? *)
853 i && guarded_by_destructors context n nn kl x safes t)
856 (fun (p,(_,te,c)) i ->
858 let debrujinedte = debrujin_constructor uri len te in
859 recursive_args tys 0 len debrujinedte
861 let (e, safes',n',nn',x',context') =
862 get_new_safes context p c rl' safes n nn x
865 guarded_by_destructors context' n' nn' kl x' safes' e
866 ) (List.combine pl cl) true
868 guarded_by_destructors context n nn kl x safes outtype &&
869 guarded_by_destructors context n nn kl x safes term &&
870 (*CSC: manca ??? il controllo sul tipo di term? *)
872 (fun p i -> i && guarded_by_destructors context n nn kl x safes p)
876 let len = List.length fl in
877 let n_plus_len = n + len
878 and nn_plus_len = nn + len
879 and x_plus_len = x + len
880 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
881 and safes' = List.map (fun x -> x + len) safes in
883 (fun (_,_,ty,bo) i ->
884 i && guarded_by_destructors context n nn kl x_plus_len safes' ty &&
885 guarded_by_destructors (tys@context) n_plus_len nn_plus_len kl
889 let len = List.length fl in
890 let n_plus_len = n + len
891 and nn_plus_len = nn + len
892 and x_plus_len = x + len
893 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl
894 and safes' = List.map (fun x -> x + len) safes in
898 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 (* the boolean h means already protected *)
904 (* args is the list of arguments the type of the constructor that may be *)
905 (* found in head position must be applied to. *)
906 (*CSC: coInductiveTypeURI non cambia mai di ricorsione in ricorsione *)
907 and guarded_by_constructors context n nn h te args coInductiveTypeURI =
908 let module C = Cic in
909 (*CSC: There is a lot of code replication between the cases X and *)
910 (*CSC: (C.Appl X tl). Maybe it will be better to define a function *)
911 (*CSC: that maps X into (C.Appl X []) when X is not already a C.Appl *)
912 match CicReduction.whd context te with
913 C.Rel m when m > n && m <= nn -> h
921 raise (Impossible 17) (* the term has just been type-checked *)
922 | C.Lambda (name,so,de) ->
923 does_not_occur context n nn so &&
924 guarded_by_constructors ((Some (name,(C.Decl so)))::context)
925 (n + 1) (nn + 1) h de args coInductiveTypeURI
926 | C.Appl ((C.Rel m)::tl) when m > n && m <= nn ->
928 List.fold_right (fun x i -> i && does_not_occur context n nn x) tl true
929 | C.Appl ((C.MutConstruct (uri,i,j,exp_named_subst))::tl) ->
931 match CicEnvironment.get_cooked_obj uri with
932 C.InductiveDefinition (itl,_,_) ->
933 let (_,_,_,cl) = List.nth itl i in
934 let (_,cons) = List.nth cl (j - 1) in
935 CicSubstitution.subst_vars exp_named_subst cons
937 raise (WrongUriToMutualInductiveDefinitions
938 (UriManager.string_of_uri uri))
940 let rec analyse_branch context ty te =
941 match CicReduction.whd context ty with
942 C.Meta _ -> raise (Impossible 34)
946 does_not_occur context n nn te
948 | C.Cast _ -> raise (Impossible 24) (* due to type-checking *)
949 | C.Prod (name,so,de) ->
950 analyse_branch ((Some (name,(C.Decl so)))::context) de te
952 | C.LetIn _ -> raise (Impossible 25) (* due to type-checking *)
953 | C.Appl ((C.MutInd (uri,_,_))::_) as ty
954 when uri == coInductiveTypeURI ->
955 guarded_by_constructors context n nn true te [] coInductiveTypeURI
956 | C.Appl ((C.MutInd (uri,_,_))::_) as ty ->
957 guarded_by_constructors context n nn true te tl coInductiveTypeURI
959 does_not_occur context n nn te
960 | C.Const _ -> raise (Impossible 26)
961 | C.MutInd (uri,_,_) when uri == coInductiveTypeURI ->
962 guarded_by_constructors context n nn true te [] coInductiveTypeURI
964 does_not_occur context n nn te
965 | C.MutConstruct _ -> raise (Impossible 27)
966 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
967 (*CSC: in head position. *)
970 | C.CoFix _ -> raise (Impossible 28) (* due to type-checking *)
972 let rec analyse_instantiated_type context ty l =
973 match CicReduction.whd context ty with
979 | C.Cast _ -> raise (Impossible 29) (* due to type-checking *)
980 | C.Prod (name,so,de) ->
985 analyse_branch context so he &&
986 analyse_instantiated_type ((Some (name,(C.Decl so)))::context)
990 | C.LetIn _ -> raise (Impossible 30) (* due to type-checking *)
993 (fun i x -> i && does_not_occur context n nn x) true l
994 | C.Const _ -> raise (Impossible 31)
997 (fun i x -> i && does_not_occur context n nn x) true l
998 | C.MutConstruct _ -> raise (Impossible 32)
999 (*CSC: we do not consider backbones with a MutCase, Fix, Cofix *)
1000 (*CSC: in head position. *)
1003 | C.CoFix _ -> raise (Impossible 33) (* due to type-checking *)
1005 let rec instantiate_type args consty =
1008 | tlhe::tltl as l ->
1009 let consty' = CicReduction.whd context consty in
1015 let instantiated_de = CicSubstitution.subst he de in
1016 (*CSC: siamo sicuri che non sia troppo forte? *)
1017 does_not_occur context n nn tlhe &
1018 instantiate_type tl instantiated_de tltl
1020 (*CSC:We do not consider backbones with a MutCase, a *)
1021 (*CSC:FixPoint, a CoFixPoint and so on in head position.*)
1022 raise (Impossible 23)
1024 | [] -> analyse_instantiated_type context consty' l
1025 (* These are all the other cases *)
1027 instantiate_type args consty tl
1028 | C.Appl ((C.CoFix (_,fl))::tl) ->
1029 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1030 let len = List.length fl in
1031 let n_plus_len = n + len
1032 and nn_plus_len = nn + len
1033 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1034 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1037 i && does_not_occur context n nn ty &&
1038 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1039 args coInductiveTypeURI
1041 | C.Appl ((C.MutCase (_,_,out,te,pl))::tl) ->
1042 List.fold_left (fun i x -> i && does_not_occur context n nn x) true tl &&
1043 does_not_occur context n nn out &&
1044 does_not_occur context n nn te &&
1048 guarded_by_constructors context n nn h x args coInductiveTypeURI
1051 List.fold_right (fun x i -> i && does_not_occur context n nn x) l true
1052 | C.Var (_,exp_named_subst)
1053 | C.Const (_,exp_named_subst) ->
1055 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1056 | C.MutInd _ -> assert false
1057 | C.MutConstruct (_,_,_,exp_named_subst) ->
1059 (fun (_,x) i -> i && does_not_occur context n nn x) exp_named_subst true
1060 | C.MutCase (_,_,out,te,pl) ->
1061 does_not_occur context n nn out &&
1062 does_not_occur context n nn te &&
1066 guarded_by_constructors context n nn h x args coInductiveTypeURI
1069 let len = List.length fl in
1070 let n_plus_len = n + len
1071 and nn_plus_len = nn + len
1072 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1073 and tys = List.map (fun (n,_,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1075 (fun (_,_,ty,bo) i ->
1076 i && does_not_occur context n nn ty &&
1077 does_not_occur (tys@context) n_plus_len nn_plus_len bo
1080 let len = List.length fl in
1081 let n_plus_len = n + len
1082 and nn_plus_len = nn + len
1083 (*CSC: Is a Decl of the ty ok or should I use Def of a Fix? *)
1084 and tys = List.map (fun (n,ty,_) -> Some (C.Name n,(C.Decl ty))) fl in
1087 i && does_not_occur context n nn ty &&
1088 guarded_by_constructors (tys@context) n_plus_len nn_plus_len h bo
1089 args coInductiveTypeURI
1092 and check_allowed_sort_elimination context uri i need_dummy ind arity1 arity2 =
1093 let module C = Cic in
1094 let module U = UriManager in
1095 match (CicReduction.whd context arity1, CicReduction.whd context arity2) with
1096 (C.Prod (_,so1,de1), C.Prod (_,so2,de2))
1097 when CicReduction.are_convertible context so1 so2 ->
1098 check_allowed_sort_elimination context uri i need_dummy
1099 (C.Appl [CicSubstitution.lift 1 ind ; C.Rel 1]) de1 de2
1100 | (C.Sort C.Prop, C.Sort C.Prop) when need_dummy -> true
1101 | (C.Sort C.Prop, C.Sort C.Set)
1102 | (C.Sort C.Prop, C.Sort C.Type) when need_dummy ->
1103 (*CSC: WRONG. MISSING CONDITIONS ON THE ARGUMENTS OF THE CONSTRUTOR *)
1104 (match CicEnvironment.get_obj uri with
1105 C.InductiveDefinition (itl,_,_) ->
1106 let (_,_,_,cl) = List.nth itl i in
1107 (* is a singleton definition or the empty proposition? *)
1108 List.length cl = 1 || List.length cl = 0
1110 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
1112 | (C.Sort C.Set, C.Sort C.Prop) when need_dummy -> true
1113 | (C.Sort C.Set, C.Sort C.Set) when need_dummy -> true
1114 | (C.Sort C.Set, C.Sort C.Type) when need_dummy ->
1115 (match CicEnvironment.get_obj uri with
1116 C.InductiveDefinition (itl,_,paramsno) ->
1118 List.map (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1120 let (_,_,_,cl) = List.nth itl i in
1122 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1124 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
1126 | (C.Sort C.Type, C.Sort _) when need_dummy -> true
1127 | (C.Sort C.Prop, C.Prod (name,so,ta)) when not need_dummy ->
1128 let res = CicReduction.are_convertible context so ind
1131 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1132 C.Sort C.Prop -> true
1134 (match CicEnvironment.get_obj uri with
1135 C.InductiveDefinition (itl,_,_) ->
1136 let (_,_,_,cl) = List.nth itl i in
1137 (* is a singleton definition? *)
1140 raise (WrongUriToMutualInductiveDefinitions
1141 (U.string_of_uri uri))
1145 | (C.Sort C.Set, C.Prod (name,so,ta)) when not need_dummy ->
1146 let res = CicReduction.are_convertible context so ind
1149 (match CicReduction.whd ((Some (name,(C.Decl so)))::context) ta with
1151 | C.Sort C.Set -> true
1153 (match CicEnvironment.get_obj uri with
1154 C.InductiveDefinition (itl,_,paramsno) ->
1155 let (_,_,_,cl) = List.nth itl i in
1158 (fun (n,_,ty,_) -> Some (Cic.Name n,(Cic.Decl ty))) itl
1161 (fun (_,x) i -> i && is_small tys paramsno x) cl true
1163 raise (WrongUriToMutualInductiveDefinitions
1164 (U.string_of_uri uri))
1166 | _ -> raise (Impossible 19)
1168 | (C.Sort C.Type, C.Prod (_,so,_)) when not need_dummy ->
1169 CicReduction.are_convertible context so ind
1172 and type_of_branch context argsno need_dummy outtype term constype =
1173 let module C = Cic in
1174 let module R = CicReduction in
1175 match R.whd context constype with
1180 C.Appl [outtype ; term]
1181 | C.Appl (C.MutInd (_,_,_)::tl) ->
1182 let (_,arguments) = split tl argsno
1184 if need_dummy && arguments = [] then
1187 C.Appl (outtype::arguments@(if need_dummy then [] else [term]))
1188 | C.Prod (name,so,de) ->
1190 match CicSubstitution.lift 1 term with
1191 C.Appl l -> C.Appl (l@[C.Rel 1])
1192 | t -> C.Appl [t ; C.Rel 1]
1194 C.Prod (C.Anonymous,so,type_of_branch
1195 ((Some (name,(C.Decl so)))::context) argsno need_dummy
1196 (CicSubstitution.lift 1 outtype) term' de)
1197 | _ -> raise (Impossible 20)
1199 (* check_metasenv_consistency checks that the "canonical" context of a
1200 metavariable is consitent - up to relocation via the relocation list l -
1201 with the actual context *)
1203 and check_metasenv_consistency metasenv context canonical_context l =
1204 let module C = Cic in
1205 let module R = CicReduction in
1206 let module S = CicSubstitution in
1207 let lifted_canonical_context =
1211 | (Some (n,C.Decl t))::tl ->
1212 (Some (n,C.Decl (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1213 | (Some (n,C.Def t))::tl ->
1214 (Some (n,C.Def (S.lift_meta l (S.lift i t))))::(aux (i+1) tl)
1215 | None::tl -> None::(aux (i+1) tl)
1217 aux 1 canonical_context
1224 | Some t,Some (_,C.Def ct) ->
1225 R.are_convertible context t ct
1226 | Some t,Some (_,C.Decl ct) ->
1227 R.are_convertible context (type_of_aux' metasenv context t) ct
1230 if not res then raise MetasenvInconsistency
1231 ) l lifted_canonical_context
1233 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
1234 and type_of_aux' metasenv context t =
1235 let rec type_of_aux context =
1236 let module C = Cic in
1237 let module R = CicReduction in
1238 let module S = CicSubstitution in
1239 let module U = UriManager in
1243 match List.nth context (n - 1) with
1244 Some (_,C.Decl t) -> S.lift n t
1245 | Some (_,C.Def bo) -> type_of_aux context (S.lift n bo)
1246 | None -> raise RelToHiddenHypothesis
1248 _ -> raise (NotWellTyped "Not a close term")
1250 | C.Var (uri,exp_named_subst) ->
1252 check_exp_named_subst context exp_named_subst ;
1254 CicSubstitution.subst_vars exp_named_subst (type_of_variable uri)
1259 let (_,canonical_context,ty) =
1260 List.find (function (m,_,_) -> n = m) metasenv
1262 check_metasenv_consistency metasenv context canonical_context l;
1263 CicSubstitution.lift_meta l ty
1264 | C.Sort s -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1265 | C.Implicit -> raise (Impossible 21)
1267 let _ = type_of_aux context ty in
1268 if R.are_convertible context (type_of_aux context te) ty then ty
1269 else raise (NotWellTyped "Cast")
1270 | C.Prod (name,s,t) ->
1271 let sort1 = type_of_aux context s
1272 and sort2 = type_of_aux ((Some (name,(C.Decl s)))::context) t in
1273 sort_of_prod context (name,s) (sort1,sort2)
1274 | C.Lambda (n,s,t) ->
1275 let sort1 = type_of_aux context s
1276 and type2 = type_of_aux ((Some (n,(C.Decl s)))::context) t in
1277 let sort2 = type_of_aux ((Some (n,(C.Decl s)))::context) type2 in
1278 (* only to check if the product is well-typed *)
1279 let _ = sort_of_prod context (n,s) (sort1,sort2) in
1281 | C.LetIn (n,s,t) ->
1282 (* only to check if s is well-typed *)
1283 let _ = type_of_aux context s in
1284 (* The type of a LetIn is a LetIn. Extremely slow since the computed
1285 LetIn is later reduced and maybe also re-checked.
1286 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t))
1288 (* The type of the LetIn is reduced. Much faster than the previous
1289 solution. Moreover the inferred type is probably very different
1290 from the expected one.
1291 (CicReduction.whd context
1292 (C.LetIn (n,s, type_of_aux ((Some (n,(C.Def s)))::context) t)))
1294 (* One-step LetIn reduction. Even faster than the previous solution.
1295 Moreover the inferred type is closer to the expected one. *)
1296 (CicSubstitution.subst s
1297 (type_of_aux ((Some (n,(C.Def s)))::context) t))
1298 | C.Appl (he::tl) when List.length tl > 0 ->
1299 let hetype = type_of_aux context he
1300 and tlbody_and_type = List.map (fun x -> (x, type_of_aux context x)) tl in
1301 eat_prods context hetype tlbody_and_type
1302 | C.Appl _ -> raise (NotWellTyped "Appl: no arguments")
1303 | C.Const (uri,exp_named_subst) ->
1305 check_exp_named_subst context exp_named_subst ;
1307 CicSubstitution.subst_vars exp_named_subst (type_of_constant uri)
1311 | C.MutInd (uri,i,exp_named_subst) ->
1313 check_exp_named_subst context exp_named_subst ;
1315 CicSubstitution.subst_vars exp_named_subst
1316 (type_of_mutual_inductive_defs uri i)
1320 | C.MutConstruct (uri,i,j,exp_named_subst) ->
1321 check_exp_named_subst context exp_named_subst ;
1323 CicSubstitution.subst_vars exp_named_subst
1324 (type_of_mutual_inductive_constr uri i j)
1327 | C.MutCase (uri,i,outtype,term,pl) ->
1328 let outsort = type_of_aux context outtype in
1329 let (need_dummy, k) =
1330 let rec guess_args context t =
1331 match CicReduction.whd context t with
1332 C.Sort _ -> (true, 0)
1333 | C.Prod (name, s, t) ->
1334 let (b, n) = guess_args ((Some (name,(C.Decl s)))::context) t in
1336 (* last prod before sort *)
1337 match CicReduction.whd context s with
1338 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1339 C.MutInd (uri',i',_) when U.eq uri' uri && i' = i ->
1341 (*CSC: for _ see comment below about the missing named_exp_subst ?????????? *)
1342 | C.Appl ((C.MutInd (uri',i',_)) :: _)
1343 when U.eq uri' uri && i' = i -> (false, 1)
1347 | _ -> raise (NotWellTyped "MutCase: outtype ill-formed")
1349 (*CSC whd non serve dopo type_of_aux ? *)
1350 let (b, k) = guess_args context outsort in
1351 if not b then (b, k - 1) else (b, k)
1353 let (parameters, arguments, exp_named_subst) =
1354 match R.whd context (type_of_aux context term) with
1355 (*CSC manca il caso dei CAST *)
1356 (*CSC: ma servono i parametri (uri,i)? Se si', perche' non serve anche il *)
1357 (*CSC: parametro exp_named_subst? Se no, perche' non li togliamo? *)
1358 (*CSC: Hint: nella DTD servono per gli stylesheet. *)
1359 C.MutInd (uri',i',exp_named_subst) as typ ->
1360 if U.eq uri uri' && i = i' then ([],[],exp_named_subst)
1361 else raise (NotWellTyped ("MutCase: the term is of type " ^
1363 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1364 string_of_int i ^ "{_}"))
1365 | C.Appl ((C.MutInd (uri',i',exp_named_subst) as typ):: tl) ->
1366 if U.eq uri uri' && i = i' then
1368 split tl (List.length tl - k)
1369 in params,args,exp_named_subst
1370 else raise (NotWellTyped ("MutCase: the term is of type " ^
1372 " instead of type " ^ (U.string_of_uri uri) ^ "#1/" ^
1373 string_of_int i ^ "{_}"))
1374 | _ -> raise (NotWellTyped "MutCase: the term is not an inductive one")
1376 (* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
1377 let sort_of_ind_type =
1378 if parameters = [] then
1379 C.MutInd (uri,i,exp_named_subst)
1381 C.Appl ((C.MutInd (uri,i,exp_named_subst))::parameters)
1383 if not (check_allowed_sort_elimination context uri i need_dummy
1384 sort_of_ind_type (type_of_aux context sort_of_ind_type) outsort)
1386 raise (NotWellTyped "MutCase: not allowed sort elimination") ;
1388 (* let's check if the type of branches are right *)
1390 match CicEnvironment.get_cooked_obj uri with
1391 C.InductiveDefinition (_,_,parsno) -> parsno
1393 raise (WrongUriToMutualInductiveDefinitions (U.string_of_uri uri))
1395 let (_,branches_ok) =
1399 if parameters = [] then
1400 (C.MutConstruct (uri,i,j,exp_named_subst))
1402 (C.Appl (C.MutConstruct (uri,i,j,exp_named_subst)::parameters))
1409 R.are_convertible context (type_of_aux context p)
1410 (type_of_branch context parsno need_dummy outtype cons
1411 (type_of_aux context cons))
1412 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
1416 if not branches_ok then
1417 raise (NotWellTyped "MutCase: wrong type of a branch") ;
1419 if not need_dummy then
1420 C.Appl ((outtype::arguments)@[term])
1421 else if arguments = [] then
1424 C.Appl (outtype::arguments)
1426 let types_times_kl =
1430 let _ = type_of_aux context ty in
1431 (Some (C.Name n,(C.Decl ty)),k)) fl)
1433 let (types,kl) = List.split types_times_kl in
1434 let len = List.length types in
1436 (fun (name,x,ty,bo) ->
1438 (R.are_convertible (types@context) (type_of_aux (types@context) bo)
1439 (CicSubstitution.lift len ty))
1442 let (m, eaten, context') =
1443 eat_lambdas (types @ context) (x + 1) bo
1445 (*let's control the guarded by destructors conditions D{f,k,x,M}*)
1448 (guarded_by_destructors context' eaten (len + eaten) kl 1 [] m)
1450 raise (NotWellTyped "Fix: not guarded by destructors")
1453 raise (NotWellTyped "Fix: ill-typed bodies")
1456 (*CSC: controlli mancanti solo su D{f,k,x,M} *)
1457 let (_,_,ty,_) = List.nth fl i in
1464 let _ = type_of_aux context ty in Some (C.Name n,(C.Decl ty))) fl)
1466 let len = List.length types in
1470 (R.are_convertible (types @ context)
1471 (type_of_aux (types @ context) bo) (CicSubstitution.lift len ty))
1474 (* let's control that the returned type is coinductive *)
1475 match returns_a_coinductive context ty with
1477 raise(NotWellTyped "CoFix: does not return a coinductive type")
1479 (*let's control the guarded by constructors conditions C{f,M}*)
1482 (guarded_by_constructors (types @ context) 0 len false bo
1485 raise (NotWellTyped "CoFix: not guarded by constructors")
1488 raise (NotWellTyped "CoFix: ill-typed bodies")
1491 let (_,ty,_) = List.nth fl i in
1494 and check_exp_named_subst context =
1495 let rec check_exp_named_subst_aux substs =
1498 | ((uri,t) as subst)::tl ->
1500 CicSubstitution.subst_vars substs (type_of_variable uri) in
1501 (match CicEnvironment.get_cooked_obj uri with
1502 Cic.Variable (_,Some bo,_,_) ->
1505 "A variable with a body can not be explicit substituted")
1506 | Cic.Variable (_,None,_,_) -> ()
1507 | _ -> raise (WrongUriToVariable (UriManager.string_of_uri uri))
1509 let typeoft = type_of_aux context t in
1510 if CicReduction.are_convertible context typeoft typeofvar then
1511 check_exp_named_subst_aux (substs@[subst]) tl
1514 CicReduction.fdebug := 0 ;
1515 ignore (CicReduction.are_convertible context typeoft typeofvar) ;
1517 debug typeoft [typeofvar] ;
1518 raise (NotWellTyped "Wrong Explicit Named Substitution")
1521 check_exp_named_subst_aux []
1523 and sort_of_prod context (name,s) (t1, t2) =
1524 let module C = Cic in
1525 let t1' = CicReduction.whd context t1 in
1526 let t2' = CicReduction.whd ((Some (name,C.Decl s))::context) t2 in
1527 match (t1', t2') with
1528 (C.Sort s1, C.Sort s2)
1529 when (s2 = C.Prop or s2 = C.Set) -> (* different from Coq manual!!! *)
1531 | (C.Sort s1, C.Sort s2) -> C.Sort C.Type (*CSC manca la gestione degli universi!!! *)
1535 ("Prod: sort1= " ^ CicPp.ppterm t1' ^ " ; sort2= " ^ CicPp.ppterm t2'))
1537 and eat_prods context hetype =
1538 (*CSC: siamo sicuri che le are_convertible non lavorino con termini non *)
1542 | (hete, hety)::tl ->
1543 (match (CicReduction.whd context hetype) with
1545 if CicReduction.are_convertible context s hety then
1546 (CicReduction.fdebug := -1 ;
1547 eat_prods context (CicSubstitution.subst hete t) tl
1551 CicReduction.fdebug := 0 ;
1552 ignore (CicReduction.are_convertible context s hety) ;
1555 raise (NotWellTyped "Appl: wrong parameter-type")
1557 | _ -> raise (NotWellTyped "Appl: wrong Prod-type")
1560 and returns_a_coinductive context ty =
1561 let module C = Cic in
1562 match CicReduction.whd context ty with
1563 C.MutInd (uri,i,_) ->
1564 (*CSC: definire una funzioncina per questo codice sempre replicato *)
1565 (match CicEnvironment.get_cooked_obj uri with
1566 C.InductiveDefinition (itl,_,_) ->
1567 let (_,is_inductive,_,_) = List.nth itl i in
1568 if is_inductive then None else (Some uri)
1570 raise (WrongUriToMutualInductiveDefinitions
1571 (UriManager.string_of_uri uri))
1573 | C.Appl ((C.MutInd (uri,i,_))::_) ->
1574 (match CicEnvironment.get_obj uri with
1575 C.InductiveDefinition (itl,_,_) ->
1576 let (_,is_inductive,_,_) = List.nth itl i in
1577 if is_inductive then None else (Some uri)
1579 raise (WrongUriToMutualInductiveDefinitions
1580 (UriManager.string_of_uri uri))
1582 | C.Prod (n,so,de) ->
1583 returns_a_coinductive ((Some (n,C.Decl so))::context) de
1588 prerr_endline ("INIZIO TYPE_OF_AUX " ^ CicPp.ppterm t) ; flush stderr ;
1591 type_of_aux context t
1593 in prerr_endline "FINE TYPE_OF_AUX" ; flush stderr ; res
1596 (* is a small constructor? *)
1597 (*CSC: ottimizzare calcolando staticamente *)
1598 and is_small context paramsno c =
1599 let rec is_small_aux context c =
1600 let module C = Cic in
1601 match CicReduction.whd context c with
1603 (*CSC: [] is an empty metasenv. Is it correct? *)
1604 let s = type_of_aux' [] context so in
1605 (s = C.Sort C.Prop || s = C.Sort C.Set) &&
1606 is_small_aux ((Some (n,(C.Decl so)))::context) de
1607 | _ -> true (*CSC: we trust the type-checker *)
1609 let (context',dx) = split_prods context paramsno c in
1610 is_small_aux context' dx
1614 prerr_endline ("INIZIO TYPE_OF_AUX' " ^ CicPp.ppterm t) ; flush stderr ;
1617 type_of_aux' [] [] t
1619 in prerr_endline "FINE TYPE_OF_AUX'" ; flush stderr ; res
1624 let module C = Cic in
1625 let module R = CicReduction in
1626 let module U = UriManager in
1627 match CicEnvironment.is_type_checked uri with
1628 CicEnvironment.CheckedObj _ -> ()
1629 | CicEnvironment.UncheckedObj uobj ->
1630 (* let's typecheck the uncooked object *)
1631 Logger.log (`Start_type_checking uri) ;
1633 C.Constant (_,Some te,ty,_) ->
1634 let _ = type_of ty in
1635 if not (R.are_convertible [] (type_of te ) ty) then
1636 raise (NotWellTyped ("Constant " ^ (U.string_of_uri uri)))
1637 | C.Constant (_,None,ty,_) ->
1638 (* only to check that ty is well-typed *)
1639 let _ = type_of ty in ()
1640 | C.CurrentProof (_,conjs,te,ty,_) ->
1641 (*CSC: bisogna controllare anche il metasenv!!! *)
1642 let _ = type_of_aux' conjs [] ty in
1643 debug (type_of_aux' conjs [] te) [] ;
1644 if not (R.are_convertible [] (type_of_aux' conjs [] te) ty) then
1645 raise (NotWellTyped ("CurrentProof" ^ (U.string_of_uri uri)))
1646 | C.Variable (_,bo,ty,_) ->
1647 (* only to check that ty is well-typed *)
1648 let _ = type_of ty in
1652 if not (R.are_convertible [] (type_of bo) ty) then
1653 raise (NotWellTyped ("Variable" ^ (U.string_of_uri uri)))
1655 | C.InductiveDefinition _ ->
1656 check_mutual_inductive_defs uri uobj
1658 CicEnvironment.set_type_checking_info uri ;
1659 Logger.log (`Type_checking_completed uri)