2 ||M|| This file is part of HELM, an Hypertextual, Electronic
3 ||A|| Library of Mathematics, developed at the Computer Science
4 ||T|| Department, University of Bologna, Italy.
6 ||T|| HELM is free software; you can redistribute it and/or
7 ||A|| modify it under the terms of the GNU General Public License
8 \ / version 2 or (at your option) any later version.
9 \ / This software is distributed as is, NO WARRANTY.
10 V_______________________________________________________________ *)
14 let exp_implicit metasenv subst context expty =
16 | Some `Closed -> NCicMetaSubst.mk_meta metasenv [] expty
17 | Some `Type | None -> NCicMetaSubst.mk_meta metasenv context expty
21 let sort_of_prod localise metasenv subst context (name,s) t (t1, t2) =
22 let restrict metasenv subst = function
23 | NCic.Meta (i,(_,(NCic.Irl 0 | NCic.Ctx []))) as t ->
25 | NCic.Meta (i,(_,lc)) as t ->
26 let len = match lc with NCic.Irl len->len | NCic.Ctx l->List.lenght l in
27 let metasenv, subst, _ =
28 NCicMetaSubst.restrict metasenv subst i (HExtlib.seq 1 len)
31 | t -> metasenv, subst, t
33 let t1 = R.whd ~subst context t1 in
34 let t2 = R.whd ~subst ((name,C.Decl s)::context) t2 in
35 let metasenv, subst, t1 = restrict metasenv subst t1 in
36 let metasenv, subst, t2 = restrict metasenv subst t2 in
38 | C.Sort _, C.Sort C.Prop -> metasenv, subst, t2
39 | C.Sort (C.Type u1), C.Sort (C.Type u2) ->
40 metasenv, subst, C.Sort (C.Type (u1@u2))
41 | C.Sort C.Prop,C.Sort (C.Type _) -> metasenv, subst, t2
44 | C.Sort _, C.Meta _ -> metasenv, subst, t2
47 if x == t1 then s, context else t, ((name,C.Decl s)::context)
49 raise (TypeCheckerFailure (lazy (Printf.sprintf
50 "%s is expected to be a type, but its type is %s that is not a sort"
51 (PP.ppterm ~subst ~metasenv ~context y)
52 (PP.ppterm ~subst ~metasenv ~context x))))
56 ?(localize=fun _ -> Stdpp.dummy) metasenv subst context term expty
58 let force_ty metasenv subst context t infty = function
61 | NCic.Implicit _ -> metasenv, subst, t, expty
64 NCicUnification.unify metasenv subst context infty expty in
65 metasenv, subst, t, expty)
66 | None -> metasenv, subst, t, infty
68 let rec typeof_aux metasenv subst context expty =
69 fun t -> (*prerr_endline (PP.ppterm ~metasenv ~subst ~context t);*)
70 let metasenv, subst, t, infty =
75 match List.nth context (n - 1) with
76 | (_,C.Decl ty) -> S.lift n ty
77 | (_,C.Def (_,ty)) -> S.lift n ty
79 raise (RefineFailure (lazy (localize t,"unbound variable"))))
81 metasenv, subst, t, infty
82 | C.Sort (C.Type [false,u]) -> metasenv,subst,t,(C.Sort (C.Type [true, u]))
83 | C.Sort (C.Type _) ->
84 raise (AssertFailure (lazy ("Cannot type an inferred type: "^
85 NCicPp.ppterm ~subst ~metasenv ~context t)))
86 | C.Sort _ -> metasenv,subst,t,(C.Sort (C.Type NCicEnvironment.type0))
88 let metasenv,t,ty = exp_implicit metasenv subst context infos expty in
89 metasenv, subst, t, ty
90 | C.Meta (n,l) as t ->
93 let _,_,_,ty = U.lookup_subst n subst in
94 with U.Subst_not_found _ -> try
95 let _,_,ty = U.lookup_meta n metasenv in
96 match ty with C.Implicit _ -> assert false | _ -> c,ty
97 with U.Meta_not_found _ ->
98 raise (AssertFailure (lazy (Printf.sprintf
99 "%s not found" (PP.ppterm ~subst ~metasenv ~context t))))
101 metasenv, subst, t, S.subst_meta l ty
103 metasenv, subst, t, NCicTypeChecker.typeof ~subst ~metasenv context t
104 | C.Prod (name,s,t) as orig ->
105 let metasenv, subst, s, s1 = typeof_aux metasenv subst context None s in
106 let context = (name,(NCic.Decl s))::context in
107 let metasenv, subst, t, s2 = typeof_aux metasenv subst context None t in
108 let metasenv, subst, ty =
109 sort_of_prod localize metasenv subst context (name,s) t (s1,s2)
111 metasenv, subst, orig, ty
112 | C.Lambda (n,s,t) ->
113 let sort = typeof_aux context s in
114 (match R.whd ~subst context sort with
115 | C.Meta _ | C.Sort _ -> ()
118 (TypeCheckerFailure (lazy (Printf.sprintf
119 ("Not well-typed lambda-abstraction: " ^^
120 "the source %s should be a type; instead it is a term " ^^
121 "of type %s") (PP.ppterm ~subst ~metasenv ~context s)
122 (PP.ppterm ~subst ~metasenv ~context sort)))));
123 let ty = typeof_aux ((n,(C.Decl s))::context) t in
125 | C.LetIn (n,ty,t,bo) ->
126 let ty_t = typeof_aux context t in
127 let _ = typeof_aux context ty in
128 if not (R.are_convertible ~subst context ty_t ty) then
131 (lazy (Printf.sprintf
132 "The type of %s is %s but it is expected to be %s"
133 (PP.ppterm ~subst ~metasenv ~context t)
134 (PP.ppterm ~subst ~metasenv ~context ty_t)
135 (PP.ppterm ~subst ~metasenv ~context ty))))
137 let ty_bo = typeof_aux ((n,C.Def (t,ty))::context) bo in
138 S.subst ~avoid_beta_redexes:true t ty_bo
139 | C.Appl (he::(_::_ as args)) ->
140 let ty_he = typeof_aux context he in
141 let args_with_ty = List.map (fun t -> t, typeof_aux context t) args in
142 eat_prods ~subst ~metasenv context he ty_he args_with_ty
143 | C.Appl _ -> raise (AssertFailure (lazy "Appl of length < 2"))
144 | C.Match (Ref.Ref (_,Ref.Ind (_,tyno,_)) as r,outtype,term,pl) ->
145 let outsort = typeof_aux context outtype in
146 let _,leftno,itl,_,_ = E.get_checked_indtys r in
148 let _,_,_,cl = List.nth itl tyno in List.length cl
150 let parameters, arguments =
151 let ty = R.whd ~subst context (typeof_aux context term) in
154 C.Const (Ref.Ref (_,Ref.Ind _) as r') -> r',[]
155 | C.Appl (C.Const (Ref.Ref (_,Ref.Ind _) as r') :: tl) -> r',tl
158 (TypeCheckerFailure (lazy (Printf.sprintf
159 "Case analysis: analysed term %s is not an inductive one"
160 (PP.ppterm ~subst ~metasenv ~context term)))) in
161 if not (Ref.eq r r') then
163 (TypeCheckerFailure (lazy (Printf.sprintf
164 ("Case analysys: analysed term type is %s, but is expected " ^^
165 "to be (an application of) %s")
166 (PP.ppterm ~subst ~metasenv ~context ty)
167 (PP.ppterm ~subst ~metasenv ~context (C.Const r')))))
169 try HExtlib.split_nth leftno tl
172 raise (TypeCheckerFailure (lazy (Printf.sprintf
173 "%s is partially applied"
174 (PP.ppterm ~subst ~metasenv ~context ty)))) in
175 (* let's control if the sort elimination is allowed: [(I q1 ... qr)|B] *)
176 let sort_of_ind_type =
177 if parameters = [] then C.Const r
178 else C.Appl ((C.Const r)::parameters) in
179 let type_of_sort_of_ind_ty = typeof_aux context sort_of_ind_type in
180 check_allowed_sort_elimination ~subst ~metasenv r context
181 sort_of_ind_type type_of_sort_of_ind_ty outsort;
182 (* let's check if the type of branches are right *)
183 if List.length pl <> constructorsno then
184 raise (TypeCheckerFailure (lazy ("Wrong number of cases in a match")));
185 let j,branches_ok,p_ty, exp_p_ty =
187 (fun (j,b,old_p_ty,old_exp_p_ty) p ->
190 let cons = Ref.mk_constructor j r in
191 if parameters = [] then C.Const cons
192 else C.Appl (C.Const cons::parameters)
194 let ty_p = typeof_aux context p in
195 let ty_cons = typeof_aux context cons in
197 type_of_branch ~subst context leftno outtype cons ty_cons 0
199 j+1, R.are_convertible ~subst context ty_p ty_branch,
202 j,false,old_p_ty,old_exp_p_ty
203 ) (1,true,C.Sort C.Prop,C.Sort C.Prop) pl
205 if not branches_ok then
208 (lazy (Printf.sprintf ("Branch for constructor %s :=\n%s\n"^^
209 "has type %s\nnot convertible with %s")
210 (PP.ppterm ~subst ~metasenv ~context
211 (C.Const (Ref.mk_constructor (j-1) r)))
212 (PP.ppterm ~metasenv ~subst ~context (List.nth pl (j-2)))
213 (PP.ppterm ~metasenv ~subst ~context p_ty)
214 (PP.ppterm ~metasenv ~subst ~context exp_p_ty))));
215 let res = outtype::arguments@[term] in
216 R.head_beta_reduce (C.Appl res)
217 | C.Match _ -> assert false
219 and type_of_branch ~subst context leftno outty cons tycons liftno =
220 match R.whd ~subst context tycons with
221 | C.Const (Ref.Ref (_,Ref.Ind _)) -> C.Appl [S.lift liftno outty ; cons]
222 | C.Appl (C.Const (Ref.Ref (_,Ref.Ind _))::tl) ->
223 let _,arguments = HExtlib.split_nth leftno tl in
224 C.Appl (S.lift liftno outty::arguments@[cons])
225 | C.Prod (name,so,de) ->
227 match S.lift 1 cons with
228 | C.Appl l -> C.Appl (l@[C.Rel 1])
229 | t -> C.Appl [t ; C.Rel 1]
232 type_of_branch ~subst ((name,(C.Decl so))::context)
233 leftno outty cons de (liftno+1))
234 | _ -> raise (AssertFailure (lazy "type_of_branch"))
236 (* check_metasenv_consistency checks that the "canonical" context of a
237 metavariable is consitent - up to relocation via the relocation list l -
238 with the actual context *)
239 and check_metasenv_consistency
240 ~subst ~metasenv term context canonical_context l
244 let context = snd (HExtlib.split_nth shift context) in
245 let rec compare = function
249 raise (AssertFailure (lazy (Printf.sprintf
250 "Local and canonical context %s have different lengths"
251 (PP.ppterm ~subst ~context ~metasenv term))))
253 raise (TypeCheckerFailure (lazy (Printf.sprintf
254 "Unbound variable -%d in %s" m
255 (PP.ppterm ~subst ~metasenv ~context term))))
258 (_,C.Decl t1), (_,C.Decl t2)
259 | (_,C.Def (t1,_)), (_,C.Def (t2,_))
260 | (_,C.Def (_,t1)), (_,C.Decl t2) ->
261 if not (R.are_convertible ~subst tl t1 t2) then
264 (lazy (Printf.sprintf
265 ("Not well typed metavariable local context for %s: " ^^
266 "%s expected, which is not convertible with %s")
267 (PP.ppterm ~subst ~metasenv ~context term)
268 (PP.ppterm ~subst ~metasenv ~context t2)
269 (PP.ppterm ~subst ~metasenv ~context t1))))
272 (TypeCheckerFailure (lazy (Printf.sprintf
273 ("Not well typed metavariable local context for %s: " ^^
274 "a definition expected, but a declaration found")
275 (PP.ppterm ~subst ~metasenv ~context term)))));
276 compare (m - 1,tl,ctl)
278 compare (n,context,canonical_context)
280 (* we avoid useless lifting by shortening the context*)
281 let l,context = (0,lc_kind), snd (HExtlib.split_nth shift context) in
282 let lifted_canonical_context =
283 let rec lift_metas i = function
285 | (n,C.Decl t)::tl ->
286 (n,C.Decl (S.subst_meta l (S.lift i t)))::(lift_metas (i+1) tl)
287 | (n,C.Def (t,ty))::tl ->
288 (n,C.Def ((S.subst_meta l (S.lift i t)),
289 S.subst_meta l (S.lift i ty)))::(lift_metas (i+1) tl)
291 lift_metas 1 canonical_context in
292 let l = U.expand_local_context lc_kind in
297 | t, (_,C.Def (ct,_)) ->
298 (*CSC: the following optimization is to avoid a possibly expensive
299 reduction that can be easily avoided and that is quite
300 frequent. However, this is better handled using levels to
306 match List.nth context (n - 1) with
307 | (_,C.Def (te,_)) -> S.lift n te
312 if not (R.are_convertible ~subst context optimized_t ct)
316 (lazy (Printf.sprintf
317 ("Not well typed metavariable local context: " ^^
318 "expected a term convertible with %s, found %s")
319 (PP.ppterm ~subst ~metasenv ~context ct)
320 (PP.ppterm ~subst ~metasenv ~context t))))
321 | t, (_,C.Decl ct) ->
322 let type_t = typeof_aux context t in
323 if not (R.are_convertible ~subst context type_t ct) then
324 raise (TypeCheckerFailure
325 (lazy (Printf.sprintf
326 ("Not well typed metavariable local context: "^^
327 "expected a term of type %s, found %s of type %s")
328 (PP.ppterm ~subst ~metasenv ~context ct)
329 (PP.ppterm ~subst ~metasenv ~context t)
330 (PP.ppterm ~subst ~metasenv ~context type_t))))
331 ) l lifted_canonical_context
333 Invalid_argument _ ->
334 raise (AssertFailure (lazy (Printf.sprintf
335 "Local and canonical context %s have different lengths"
336 (PP.ppterm ~subst ~metasenv ~context term))))
338 and check_allowed_sort_elimination ~subst ~metasenv r =
341 | C.Appl l -> C.Appl (l @ [arg])
342 | t -> C.Appl [t;arg] in
343 let rec aux context ind arity1 arity2 =
344 let arity1 = R.whd ~subst context arity1 in
345 let arity2 = R.whd ~subst context arity2 in
346 match arity1,arity2 with
347 | C.Prod (name,so1,de1), C.Prod (_,so2,de2) ->
348 if not (R.are_convertible ~subst context so1 so2) then
349 raise (TypeCheckerFailure (lazy (Printf.sprintf
350 "In outtype: expected %s, found %s"
351 (PP.ppterm ~subst ~metasenv ~context so1)
352 (PP.ppterm ~subst ~metasenv ~context so2)
354 aux ((name, C.Decl so1)::context)
355 (mkapp (S.lift 1 ind) (C.Rel 1)) de1 de2
356 | C.Sort _, C.Prod (name,so,ta) ->
357 if not (R.are_convertible ~subst context so ind) then
358 raise (TypeCheckerFailure (lazy (Printf.sprintf
359 "In outtype: expected %s, found %s"
360 (PP.ppterm ~subst ~metasenv ~context ind)
361 (PP.ppterm ~subst ~metasenv ~context so)
363 (match arity1, R.whd ~subst ((name,C.Decl so)::context) ta with
364 | (C.Sort C.Type _, C.Sort _)
365 | (C.Sort C.Prop, C.Sort C.Prop) -> ()
366 | (C.Sort C.Prop, C.Sort C.Type _) ->
367 (* TODO: we should pass all these parameters since we
368 * have them already *)
369 let _,leftno,itl,_,i = E.get_checked_indtys r in
370 let itl_len = List.length itl in
371 let _,itname,ittype,cl = List.nth itl i in
372 let cl_len = List.length cl in
373 (* is it a singleton, non recursive and non informative
374 definition or an empty one? *)
377 (itl_len = 1 && cl_len = 1 &&
378 let _,_,constrty = List.hd cl in
379 is_non_recursive_singleton r itname ittype constrty &&
380 is_non_informative leftno constrty))
382 raise (TypeCheckerFailure (lazy
383 ("Sort elimination not allowed")));
390 typeof_aux context term
392 and eat_prods ~subst ~metasenv context he ty_he args_with_ty =
393 let rec aux ty_he = function
395 | (arg, ty_arg)::tl ->
396 match R.whd ~subst context ty_he with
398 if R.are_convertible ~subst context ty_arg s then
399 aux (S.subst ~avoid_beta_redexes:true arg t) tl
403 (lazy (Printf.sprintf
404 ("Appl: wrong application of %s: the parameter %s has type"^^
405 "\n%s\nbut it should have type \n%s\nContext:\n%s\n")
406 (PP.ppterm ~subst ~metasenv ~context he)
407 (PP.ppterm ~subst ~metasenv ~context arg)
408 (PP.ppterm ~subst ~metasenv ~context ty_arg)
409 (PP.ppterm ~subst ~metasenv ~context s)
410 (PP.ppcontext ~subst ~metasenv context))))
414 (lazy (Printf.sprintf
415 "Appl: %s is not a function, it cannot be applied"
416 (PP.ppterm ~subst ~metasenv ~context
417 (let res = List.length tl in
418 let eaten = List.length args_with_ty - res in
421 (fst (HExtlib.split_nth eaten args_with_ty)))))))))
423 aux ty_he args_with_ty
429 exception RefineFailure of string Lazy.t;;
430 exception Uncertain of string Lazy.t;;
431 exception AssertFailure of string Lazy.t;;
433 (* for internal use only; the integer is the number of surplus arguments *)
434 exception MoreArgsThanExpected of int * exn;;
436 let insert_coercions = ref true
437 let pack_coercions = ref true
442 if debug then (fun x -> prerr_endline (Lazy.force x)) else (fun _ -> ());;
444 let profiler_eat_prods2 = HExtlib.profile "CicRefine.fo_unif_eat_prods2"
446 let fo_unif_subst_eat_prods2 subst context metasenv t1 t2 ugraph =
449 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
450 in profiler_eat_prods2.HExtlib.profile foo ()
452 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
453 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
456 let profiler_eat_prods = HExtlib.profile "CicRefine.fo_unif_eat_prods"
458 let fo_unif_subst_eat_prods subst context metasenv t1 t2 ugraph =
461 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
462 in profiler_eat_prods.HExtlib.profile foo ()
464 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
465 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
468 let profiler = HExtlib.profile "CicRefine.fo_unif"
470 let fo_unif_subst subst context metasenv t1 t2 ugraph =
473 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
474 in profiler.HExtlib.profile foo ()
476 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
477 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
480 let enrich localization_tbl t ?(f = fun msg -> msg) exn =
483 RefineFailure msg -> RefineFailure (f msg)
484 | Uncertain msg -> Uncertain (f msg)
485 | AssertFailure msg -> prerr_endline (Lazy.force msg); AssertFailure (f msg)
486 | Sys.Break -> raise exn
487 | _ -> prerr_endline (Printexc.to_string exn); assert false
491 Cic.CicHash.find localization_tbl t
493 HLog.debug ("!!! NOT LOCALIZED: " ^ CicPp.ppterm t);
496 raise (HExtlib.Localized (loc,exn'))
498 let relocalize localization_tbl oldt newt =
500 let infos = Cic.CicHash.find localization_tbl oldt in
501 Cic.CicHash.remove localization_tbl oldt;
502 Cic.CicHash.add localization_tbl newt infos;
510 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
511 | (_,_) -> raise (AssertFailure (lazy "split: list too short"))
514 let exp_impl metasenv subst context =
517 let (metasenv', idx) =
518 CicMkImplicit.mk_implicit_type metasenv subst context in
520 CicMkImplicit.identity_relocation_list_for_metavariable context in
521 metasenv', Cic.Meta (idx, irl)
523 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst [] in
524 metasenv', Cic.Meta (idx, [])
526 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst context in
528 CicMkImplicit.identity_relocation_list_for_metavariable context in
529 metasenv', Cic.Meta (idx, irl)
533 let is_a_double_coercion t =
534 let rec subst_nth n x l =
537 | 0, _::tl -> x :: tl
538 | n, hd::tl -> hd :: subst_nth (n-1) x tl
540 let imp = Cic.Implicit None in
541 let dummyres = false,imp, imp,imp,imp in
544 (match CoercGraph.coerced_arg l1 with
545 | Some (Cic.Appl l2, pos1) ->
546 (match CoercGraph.coerced_arg l2 with
548 true, List.hd l1, List.hd l2, x,
549 Cic.Appl (subst_nth (pos1 + 1)
550 (Cic.Appl (subst_nth (pos2+1) imp l2)) l1)
556 let more_args_than_expected localization_tbl metasenv subst he context hetype' residuals tlbody_and_type exn
558 let len = List.length tlbody_and_type in
561 CicMetaSubst.ppterm_in_context ~metasenv subst he context ^
562 " (that has type "^ CicMetaSubst.ppterm_in_context ~metasenv subst hetype' context ^
563 ") is here applied to " ^ string_of_int len ^
564 " arguments but here it can handle only up to " ^
565 string_of_int (len - residuals) ^ " arguments")
567 enrich localization_tbl he ~f:(fun _-> msg) exn
570 let mk_prod_of_metas metasenv context subst args =
571 let rec mk_prod metasenv context' = function
573 let (metasenv, idx) =
574 CicMkImplicit.mk_implicit_type metasenv subst context'
577 CicMkImplicit.identity_relocation_list_for_metavariable context'
579 metasenv,Cic.Meta (idx, irl)
581 let (metasenv, idx) =
582 CicMkImplicit.mk_implicit_type metasenv subst context'
585 CicMkImplicit.identity_relocation_list_for_metavariable context'
587 let meta = Cic.Meta (idx,irl) in
589 (* The name must be fresh for context. *)
590 (* Nevertheless, argty is well-typed only in context. *)
591 (* Thus I generate a name (name_hint) in context and *)
592 (* then I generate a name --- using the hint name_hint *)
593 (* --- that is fresh in context'. *)
595 FreshNamesGenerator.mk_fresh_name ~subst metasenv
596 (CicMetaSubst.apply_subst_context subst context)
598 ~typ:(CicMetaSubst.apply_subst subst argty)
600 FreshNamesGenerator.mk_fresh_name ~subst
601 [] context' name_hint ~typ:(Cic.Sort Cic.Prop)
603 let metasenv,target =
604 mk_prod metasenv ((Some (name, Cic.Decl meta))::context') tl
606 metasenv,Cic.Prod (name,meta,target)
608 mk_prod metasenv context args
611 let rec type_of_constant uri ugraph =
612 let module C = Cic in
613 let module R = CicReduction in
614 let module U = UriManager in
615 let _ = CicTypeChecker.typecheck uri in
618 CicEnvironment.get_cooked_obj ugraph uri
619 with Not_found -> assert false
622 C.Constant (_,_,ty,_,_) -> ty,u
623 | C.CurrentProof (_,_,_,ty,_,_) -> ty,u
627 (lazy ("Unknown constant definition " ^ U.string_of_uri uri)))
629 and type_of_variable uri ugraph =
630 let module C = Cic in
631 let module R = CicReduction in
632 let module U = UriManager in
633 let _ = CicTypeChecker.typecheck uri in
636 CicEnvironment.get_cooked_obj ugraph uri
637 with Not_found -> assert false
640 C.Variable (_,_,ty,_,_) -> ty,u
644 (lazy ("Unknown variable definition " ^ UriManager.string_of_uri uri)))
646 and type_of_mutual_inductive_defs uri i ugraph =
647 let module C = Cic in
648 let module R = CicReduction in
649 let module U = UriManager in
650 let _ = CicTypeChecker.typecheck uri in
653 CicEnvironment.get_cooked_obj ugraph uri
654 with Not_found -> assert false
657 C.InductiveDefinition (dl,_,_,_) ->
658 let (_,_,arity,_) = List.nth dl i in
663 (lazy ("Unknown mutual inductive definition " ^ U.string_of_uri uri)))
665 and type_of_mutual_inductive_constr uri i j ugraph =
666 let module C = Cic in
667 let module R = CicReduction in
668 let module U = UriManager in
669 let _ = CicTypeChecker.typecheck uri in
672 CicEnvironment.get_cooked_obj ugraph uri
673 with Not_found -> assert false
676 C.InductiveDefinition (dl,_,_,_) ->
677 let (_,_,_,cl) = List.nth dl i in
678 let (_,ty) = List.nth cl (j-1) in
684 ("Unkown mutual inductive definition " ^ U.string_of_uri uri)))
687 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
689 (* the check_branch function checks if a branch of a case is refinable.
690 It returns a pair (outype_instance,args), a subst and a metasenv.
691 outype_instance is the expected result of applying the case outtype
693 The problem is that outype is in general unknown, and we should
694 try to synthesize it from the above information, that is in general
695 a second order unification problem. *)
697 and check_branch n context metasenv subst left_args_no actualtype term expectedtype ugraph =
698 let module C = Cic in
699 let module R = CicReduction in
700 match R.whd ~subst context expectedtype with
702 (n,context,actualtype, [term]), subst, metasenv, ugraph
703 | C.Appl (C.MutInd (_,_,_)::tl) ->
704 let (_,arguments) = split tl left_args_no in
705 (n,context,actualtype, arguments@[term]), subst, metasenv, ugraph
706 | C.Prod (_,so,de) ->
707 (* we expect that the actual type of the branch has the due
709 (match R.whd ~subst context actualtype with
710 C.Prod (name',so',de') ->
711 let subst, metasenv, ugraph1 =
712 fo_unif_subst subst context metasenv so so' ugraph in
714 (match CicSubstitution.lift 1 term with
715 C.Appl l -> C.Appl (l@[C.Rel 1])
716 | t -> C.Appl [t ; C.Rel 1]) in
717 (* we should also check that the name variable is anonymous in
718 the actual type de' ?? *)
720 ((Some (name',(C.Decl so)))::context)
721 metasenv subst left_args_no de' term' de ugraph1
722 | _ -> raise (AssertFailure (lazy "Wrong number of arguments")))
723 | _ -> raise (AssertFailure (lazy "Prod or MutInd expected"))
725 and type_of_aux' ?(clean_dummy_dependent_types=true) ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
728 let rec type_of_aux subst metasenv context t ugraph =
729 let module C = Cic in
730 let module S = CicSubstitution in
731 let module U = UriManager in
732 let (t',_,_,_,_) as res =
737 match List.nth context (n - 1) with
738 Some (_,C.Decl ty) ->
739 t,S.lift n ty,subst,metasenv, ugraph
740 | Some (_,C.Def (_,ty)) ->
741 t,S.lift n ty,subst,metasenv, ugraph
743 enrich localization_tbl t
744 (RefineFailure (lazy "Rel to hidden hypothesis"))
747 enrich localization_tbl t
748 (RefineFailure (lazy "Not a closed term")))
749 | C.Var (uri,exp_named_subst) ->
750 let exp_named_subst',subst',metasenv',ugraph1 =
751 check_exp_named_subst
752 subst metasenv context exp_named_subst ugraph
754 let ty_uri,ugraph1 = type_of_variable uri ugraph in
756 CicSubstitution.subst_vars exp_named_subst' ty_uri
758 C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
761 let (canonical_context, term,ty) =
762 CicUtil.lookup_subst n subst
764 let l',subst',metasenv',ugraph1 =
765 check_metasenv_consistency n subst metasenv context
766 canonical_context l ugraph
768 (* trust or check ??? *)
769 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
770 subst', metasenv', ugraph1
771 (* type_of_aux subst metasenv
772 context (CicSubstitution.subst_meta l term) *)
773 with CicUtil.Subst_not_found _ ->
774 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
775 let l',subst',metasenv', ugraph1 =
776 check_metasenv_consistency n subst metasenv context
777 canonical_context l ugraph
779 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
780 subst', metasenv',ugraph1)
781 | C.Sort (C.Type tno) ->
782 let tno' = CicUniv.fresh() in
784 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
785 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
787 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
788 | C.Sort (C.CProp tno) ->
789 let tno' = CicUniv.fresh() in
791 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
792 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
794 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
795 | C.Sort (C.Prop|C.Set) ->
796 t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
797 | C.Implicit infos ->
798 let metasenv',t' = exp_impl metasenv subst context infos in
799 type_of_aux subst metasenv' context t' ugraph
801 let ty',_,subst',metasenv',ugraph1 =
802 type_of_aux subst metasenv context ty ugraph
804 let te',inferredty,subst'',metasenv'',ugraph2 =
805 type_of_aux subst' metasenv' context te ugraph1
807 let (te', ty'), subst''',metasenv''',ugraph3 =
808 coerce_to_something true localization_tbl te' inferredty ty'
809 subst'' metasenv'' context ugraph2
811 C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
812 | C.Prod (name,s,t) ->
813 let s',sort1,subst',metasenv',ugraph1 =
814 type_of_aux subst metasenv context s ugraph
816 let s',sort1,subst', metasenv',ugraph1 =
817 coerce_to_sort localization_tbl
818 s' sort1 subst' context metasenv' ugraph1
820 let context_for_t = ((Some (name,(C.Decl s')))::context) in
821 let t',sort2,subst'',metasenv'',ugraph2 =
822 type_of_aux subst' metasenv'
823 context_for_t t ugraph1
825 let t',sort2,subst'',metasenv'',ugraph2 =
826 coerce_to_sort localization_tbl
827 t' sort2 subst'' context_for_t metasenv'' ugraph2
829 let sop,subst''',metasenv''',ugraph3 =
830 sort_of_prod localization_tbl subst'' metasenv''
831 context (name,s') t' (sort1,sort2) ugraph2
833 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
834 | C.Lambda (n,s,t) ->
835 let s',sort1,subst',metasenv',ugraph1 =
836 type_of_aux subst metasenv context s ugraph
838 let s',sort1,subst',metasenv',ugraph1 =
839 coerce_to_sort localization_tbl
840 s' sort1 subst' context metasenv' ugraph1
842 let context_for_t = ((Some (n,(C.Decl s')))::context) in
843 let t',type2,subst'',metasenv'',ugraph2 =
844 type_of_aux subst' metasenv' context_for_t t ugraph1
846 C.Lambda (n,s',t'),C.Prod (n,s',type2),
847 subst'',metasenv'',ugraph2
848 | C.LetIn (n,s,ty,t) ->
849 (* only to check if s is well-typed *)
850 let s',ty',subst',metasenv',ugraph1 =
851 type_of_aux subst metasenv context s ugraph in
852 let ty,_,subst',metasenv',ugraph1 =
853 type_of_aux subst' metasenv' context ty ugraph1 in
854 let subst',metasenv',ugraph1 =
856 fo_unif_subst subst' context metasenv'
860 enrich localization_tbl s' exn
863 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' s'
864 context ^ " has type " ^
865 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' ty'
866 context ^ " but is here used with type " ^
867 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' ty
870 let context_for_t = ((Some (n,(C.Def (s',ty))))::context) in
872 let t',inferredty,subst'',metasenv'',ugraph2 =
873 type_of_aux subst' metasenv'
874 context_for_t t ugraph1
876 (* One-step LetIn reduction.
877 * Even faster than the previous solution.
878 * Moreover the inferred type is closer to the expected one.
880 C.LetIn (n,s',ty,t'),
881 CicSubstitution.subst ~avoid_beta_redexes:true s' inferredty,
882 subst'',metasenv'',ugraph2
883 | C.Appl (he::((_::_) as tl)) ->
884 let he',hetype,subst',metasenv',ugraph1 =
885 type_of_aux subst metasenv context he ugraph
887 let tlbody_and_type,subst'',metasenv'',ugraph2 =
888 typeof_list subst' metasenv' context ugraph1 tl
890 let coerced_he,coerced_args,applty,subst''',metasenv''',ugraph3 =
891 eat_prods true subst'' metasenv'' context
892 he' hetype tlbody_and_type ugraph2
894 let newappl = (C.Appl (coerced_he::coerced_args)) in
895 avoid_double_coercion
896 context subst''' metasenv''' ugraph3 newappl applty
897 | C.Appl _ -> assert false
898 | C.Const (uri,exp_named_subst) ->
899 let exp_named_subst',subst',metasenv',ugraph1 =
900 check_exp_named_subst subst metasenv context
901 exp_named_subst ugraph in
902 let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
904 CicSubstitution.subst_vars exp_named_subst' ty_uri
906 C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
907 | C.MutInd (uri,i,exp_named_subst) ->
908 let exp_named_subst',subst',metasenv',ugraph1 =
909 check_exp_named_subst subst metasenv context
910 exp_named_subst ugraph
912 let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
914 CicSubstitution.subst_vars exp_named_subst' ty_uri in
915 C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
916 | C.MutConstruct (uri,i,j,exp_named_subst) ->
917 let exp_named_subst',subst',metasenv',ugraph1 =
918 check_exp_named_subst subst metasenv context
919 exp_named_subst ugraph
922 type_of_mutual_inductive_constr uri i j ugraph1
925 CicSubstitution.subst_vars exp_named_subst' ty_uri
927 C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
929 | C.MutCase (uri, i, outtype, term, pl) ->
930 (* first, get the inductive type (and noparams)
931 * in the environment *)
932 let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
933 let _ = CicTypeChecker.typecheck uri in
934 let obj,u = CicEnvironment.get_cooked_obj ugraph uri in
936 C.InductiveDefinition (l,expl_params,parsno,_) ->
937 List.nth l i , expl_params, parsno, u
939 enrich localization_tbl t
941 (lazy ("Unkown mutual inductive definition " ^
942 U.string_of_uri uri)))
944 if List.length constructors <> List.length pl then
945 enrich localization_tbl t
947 (lazy "Wrong number of cases")) ;
948 let rec count_prod t =
949 match CicReduction.whd ~subst context t with
950 C.Prod (_, _, t) -> 1 + (count_prod t)
953 let no_args = count_prod arity in
954 (* now, create a "generic" MutInd *)
955 let metasenv,left_args =
956 CicMkImplicit.n_fresh_metas metasenv subst context no_left_params
958 let metasenv,right_args =
959 let no_right_params = no_args - no_left_params in
960 if no_right_params < 0 then assert false
961 else CicMkImplicit.n_fresh_metas
962 metasenv subst context no_right_params
964 let metasenv,exp_named_subst =
965 CicMkImplicit.fresh_subst metasenv subst context expl_params in
968 C.MutInd (uri,i,exp_named_subst)
971 (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
973 (* check consistency with the actual type of term *)
974 let term',actual_type,subst,metasenv,ugraph1 =
975 type_of_aux subst metasenv context term ugraph in
976 let expected_type',_, subst, metasenv,ugraph2 =
977 type_of_aux subst metasenv context expected_type ugraph1
979 let actual_type = CicReduction.whd ~subst context actual_type in
980 let subst,metasenv,ugraph3 =
982 fo_unif_subst subst context metasenv
983 expected_type' actual_type ugraph2
986 enrich localization_tbl term' exn
989 CicMetaSubst.ppterm_in_context ~metasenv subst term'
990 context ^ " has type " ^
991 CicMetaSubst.ppterm_in_context ~metasenv subst actual_type
992 context ^ " but is here used with type " ^
993 CicMetaSubst.ppterm_in_context ~metasenv subst expected_type'
996 let rec instantiate_prod t =
1000 match CicReduction.whd ~subst context t with
1002 instantiate_prod (CicSubstitution.subst he t') tl
1005 let arity_instantiated_with_left_args =
1006 instantiate_prod arity left_args in
1007 (* TODO: check if the sort elimination
1008 * is allowed: [(I q1 ... qr)|B] *)
1009 let (pl',_,outtypeinstances,subst,metasenv,ugraph4) =
1011 (fun p (pl,j,outtypeinstances,subst,metasenv,ugraph) ->
1013 if left_args = [] then
1014 (C.MutConstruct (uri,i,j,exp_named_subst))
1017 (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
1019 let p',actual_type,subst,metasenv,ugraph1 =
1020 type_of_aux subst metasenv context p ugraph
1022 let constructor',expected_type, subst, metasenv,ugraph2 =
1023 type_of_aux subst metasenv context constructor ugraph1
1025 let outtypeinstance,subst,metasenv,ugraph3 =
1027 check_branch 0 context metasenv subst
1028 no_left_params actual_type constructor' expected_type
1032 enrich localization_tbl constructor'
1035 CicMetaSubst.ppterm_in_context metasenv subst p'
1036 context ^ " has type " ^
1037 CicMetaSubst.ppterm_in_context metasenv subst actual_type
1038 context ^ " but is here used with type " ^
1039 CicMetaSubst.ppterm_in_context metasenv subst expected_type
1043 outtypeinstance::outtypeinstances,subst,metasenv,ugraph3))
1044 pl ([],List.length pl,[],subst,metasenv,ugraph3)
1047 (* we are left to check that the outype matches his instances.
1048 The easy case is when the outype is specified, that amount
1049 to a trivial check. Otherwise, we should guess a type from
1053 let outtype,outtypety, subst, metasenv,ugraph4 =
1054 type_of_aux subst metasenv context outtype ugraph4 in
1057 (let candidate,ugraph5,metasenv,subst =
1058 let exp_name_subst, metasenv =
1060 CicEnvironment.get_cooked_obj CicUniv.oblivion_ugraph uri
1062 let uris = CicUtil.params_of_obj o in
1064 fun uri (acc,metasenv) ->
1065 let metasenv',new_meta =
1066 CicMkImplicit.mk_implicit metasenv subst context
1069 CicMkImplicit.identity_relocation_list_for_metavariable
1072 (uri, Cic.Meta(new_meta,irl))::acc, metasenv'
1073 ) uris ([],metasenv)
1076 match left_args,right_args with
1077 [],[] -> Cic.MutInd(uri, i, exp_name_subst)
1079 let rec mk_right_args =
1082 | n -> (Cic.Rel n)::(mk_right_args (n - 1))
1084 let right_args_no = List.length right_args in
1085 let lifted_left_args =
1086 List.map (CicSubstitution.lift right_args_no) left_args
1088 Cic.Appl (Cic.MutInd(uri,i,exp_name_subst)::
1089 (lifted_left_args @ mk_right_args right_args_no))
1092 FreshNamesGenerator.mk_fresh_name ~subst metasenv
1093 context Cic.Anonymous ~typ:ty
1095 match outtypeinstances with
1097 let extended_context =
1098 let rec add_right_args =
1100 Cic.Prod (name,ty,t) ->
1101 Some (name,Cic.Decl ty)::(add_right_args t)
1104 (Some (fresh_name,Cic.Decl ty))::
1106 (add_right_args arity_instantiated_with_left_args))@
1109 let metasenv,new_meta =
1110 CicMkImplicit.mk_implicit metasenv subst extended_context
1113 CicMkImplicit.identity_relocation_list_for_metavariable
1116 let rec add_lambdas b =
1118 Cic.Prod (name,ty,t) ->
1119 Cic.Lambda (name,ty,(add_lambdas b t))
1120 | _ -> Cic.Lambda (fresh_name, ty, b)
1123 add_lambdas (Cic.Meta (new_meta,irl))
1124 arity_instantiated_with_left_args
1126 (Some candidate),ugraph4,metasenv,subst
1127 | (constructor_args_no,_,instance,_)::tl ->
1129 let instance',subst,metasenv =
1130 CicMetaSubst.delift_rels subst metasenv
1131 constructor_args_no instance
1133 let candidate,ugraph,metasenv,subst =
1135 fun (candidate_oty,ugraph,metasenv,subst)
1136 (constructor_args_no,_,instance,_) ->
1137 match candidate_oty with
1138 | None -> None,ugraph,metasenv,subst
1141 let instance',subst,metasenv =
1142 CicMetaSubst.delift_rels subst metasenv
1143 constructor_args_no instance
1145 let subst,metasenv,ugraph =
1146 fo_unif_subst subst context metasenv
1149 candidate_oty,ugraph,metasenv,subst
1151 CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable
1152 | RefineFailure _ | Uncertain _ ->
1153 None,ugraph,metasenv,subst
1154 ) (Some instance',ugraph4,metasenv,subst) tl
1156 match candidate with
1157 | None -> None, ugraph,metasenv,subst
1159 let rec add_lambdas n b =
1161 Cic.Prod (name,ty,t) ->
1162 Cic.Lambda (name,ty,(add_lambdas (n + 1) b t))
1164 Cic.Lambda (fresh_name, ty,
1165 CicSubstitution.lift (n + 1) t)
1168 (add_lambdas 0 t arity_instantiated_with_left_args),
1169 ugraph,metasenv,subst
1170 with CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
1171 None,ugraph4,metasenv,subst
1173 match candidate with
1174 | None -> raise (Uncertain (lazy "can't solve an higher order unification problem"))
1176 let subst,metasenv,ugraph =
1178 fo_unif_subst subst context metasenv
1179 candidate outtype ugraph5
1181 exn -> assert false(* unification against a metavariable *)
1183 C.MutCase (uri, i, outtype, term', pl'),
1184 CicReduction.head_beta_reduce
1185 (CicMetaSubst.apply_subst subst
1186 (Cic.Appl (outtype::right_args@[term']))),
1187 subst,metasenv,ugraph)
1188 | _ -> (* easy case *)
1189 let tlbody_and_type,subst,metasenv,ugraph4 =
1190 typeof_list subst metasenv context ugraph4 (right_args @ [term'])
1192 let _,_,_,subst,metasenv,ugraph4 =
1193 eat_prods false subst metasenv context
1194 outtype outtypety tlbody_and_type ugraph4
1196 let _,_, subst, metasenv,ugraph5 =
1197 type_of_aux subst metasenv context
1198 (C.Appl ((outtype :: right_args) @ [term'])) ugraph4
1200 let (subst,metasenv,ugraph6) =
1202 (fun (subst,metasenv,ugraph)
1203 p (constructor_args_no,context,instance,args)
1208 CicSubstitution.lift constructor_args_no outtype
1210 C.Appl (outtype'::args)
1212 CicReduction.head_beta_reduce ~delta:false
1213 ~upto:(List.length args) appl
1216 fo_unif_subst subst context metasenv instance instance'
1220 enrich localization_tbl p exn
1223 CicMetaSubst.ppterm_in_context ~metasenv subst p
1224 context ^ " has type " ^
1225 CicMetaSubst.ppterm_in_context ~metasenv subst instance'
1226 context ^ " but is here used with type " ^
1227 CicMetaSubst.ppterm_in_context ~metasenv subst instance
1229 (subst,metasenv,ugraph5) pl' outtypeinstances
1231 C.MutCase (uri, i, outtype, term', pl'),
1232 CicReduction.head_beta_reduce
1233 (CicMetaSubst.apply_subst subst
1234 (C.Appl(outtype::right_args@[term']))),
1235 subst,metasenv,ugraph6)
1237 let fl_ty',subst,metasenv,types,ugraph1,len =
1239 (fun (fl,subst,metasenv,types,ugraph,len) (n,_,ty,_) ->
1240 let ty',_,subst',metasenv',ugraph1 =
1241 type_of_aux subst metasenv context ty ugraph
1243 fl @ [ty'],subst',metasenv',
1244 Some (C.Name n,(C.Decl (CicSubstitution.lift len ty')))
1245 :: types, ugraph, len+1
1246 ) ([],subst,metasenv,[],ugraph,0) fl
1248 let context' = types@context in
1249 let fl_bo',subst,metasenv,ugraph2 =
1251 (fun (fl,subst,metasenv,ugraph) ((name,x,_,bo),ty) ->
1252 let bo',ty_of_bo,subst,metasenv,ugraph1 =
1253 type_of_aux subst metasenv context' bo ugraph in
1254 let expected_ty = CicSubstitution.lift len ty in
1255 let subst',metasenv',ugraph' =
1257 fo_unif_subst subst context' metasenv
1258 ty_of_bo expected_ty ugraph1
1261 enrich localization_tbl bo exn
1264 CicMetaSubst.ppterm_in_context ~metasenv subst bo
1265 context' ^ " has type " ^
1266 CicMetaSubst.ppterm_in_context ~metasenv subst ty_of_bo
1267 context' ^ " but is here used with type " ^
1268 CicMetaSubst.ppterm_in_context ~metasenv subst expected_ty
1271 fl @ [bo'] , subst',metasenv',ugraph'
1272 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
1274 let ty = List.nth fl_ty' i in
1275 (* now we have the new ty in fl_ty', the new bo in fl_bo',
1276 * and we want the new fl with bo' and ty' injected in the right
1279 let rec map3 f l1 l2 l3 =
1282 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
1285 let fl'' = map3 (fun ty' bo' (name,x,ty,bo) -> (name,x,ty',bo') )
1288 C.Fix (i,fl''),ty,subst,metasenv,ugraph2
1290 let fl_ty',subst,metasenv,types,ugraph1,len =
1292 (fun (fl,subst,metasenv,types,ugraph,len) (n,ty,_) ->
1293 let ty',_,subst',metasenv',ugraph1 =
1294 type_of_aux subst metasenv context ty ugraph
1296 fl @ [ty'],subst',metasenv',
1297 Some (C.Name n,(C.Decl (CicSubstitution.lift len ty'))) ::
1298 types, ugraph1, len+1
1299 ) ([],subst,metasenv,[],ugraph,0) fl
1301 let context' = types@context in
1302 let fl_bo',subst,metasenv,ugraph2 =
1304 (fun (fl,subst,metasenv,ugraph) ((name,_,bo),ty) ->
1305 let bo',ty_of_bo,subst,metasenv,ugraph1 =
1306 type_of_aux subst metasenv context' bo ugraph in
1307 let expected_ty = CicSubstitution.lift len ty in
1308 let subst',metasenv',ugraph' =
1310 fo_unif_subst subst context' metasenv
1311 ty_of_bo expected_ty ugraph1
1314 enrich localization_tbl bo exn
1317 CicMetaSubst.ppterm_in_context ~metasenv subst bo
1318 context' ^ " has type " ^
1319 CicMetaSubst.ppterm_in_context ~metasenv subst ty_of_bo
1320 context' ^ " but is here used with type " ^
1321 CicMetaSubst.ppterm_in_context ~metasenv subst expected_ty
1324 fl @ [bo'],subst',metasenv',ugraph'
1325 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
1327 let ty = List.nth fl_ty' i in
1328 (* now we have the new ty in fl_ty', the new bo in fl_bo',
1329 * and we want the new fl with bo' and ty' injected in the right
1332 let rec map3 f l1 l2 l3 =
1335 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
1338 let fl'' = map3 (fun ty' bo' (name,ty,bo) -> (name,ty',bo') )
1341 C.CoFix (i,fl''),ty,subst,metasenv,ugraph2
1343 relocalize localization_tbl t t';
1346 (* check_metasenv_consistency checks that the "canonical" context of a
1347 metavariable is consitent - up to relocation via the relocation list l -
1348 with the actual context *)
1349 and check_metasenv_consistency
1350 metano subst metasenv context canonical_context l ugraph
1352 let module C = Cic in
1353 let module R = CicReduction in
1354 let module S = CicSubstitution in
1355 let lifted_canonical_context =
1359 | (Some (n,C.Decl t))::tl ->
1360 (Some (n,C.Decl (S.subst_meta l (S.lift i t))))::(aux (i+1) tl)
1361 | None::tl -> None::(aux (i+1) tl)
1362 | (Some (n,C.Def (t,ty)))::tl ->
1366 (S.subst_meta l (S.lift i t),
1367 S.subst_meta l (S.lift i ty)))) :: (aux (i+1) tl)
1369 aux 1 canonical_context
1373 (fun (l,subst,metasenv,ugraph) t ct ->
1376 l @ [None],subst,metasenv,ugraph
1377 | Some t,Some (_,C.Def (ct,_)) ->
1378 (*CSC: the following optimization is to avoid a possibly
1379 expensive reduction that can be easily avoided and
1380 that is quite frequent. However, this is better
1381 handled using levels to control reduction *)
1386 match List.nth context (n - 1) with
1387 Some (_,C.Def (te,_)) -> S.lift n te
1393 let subst',metasenv',ugraph' =
1395 (*prerr_endline ("poco geniale: nel caso di IRL basterebbe sapere che questo e'
1396 * il Rel corrispondente. Si puo' ottimizzare il caso t = rel.");*)
1397 fo_unif_subst subst context metasenv optimized_t ct ugraph
1398 with e -> raise (RefineFailure (lazy (sprintf "The local context is not consistent with the canonical context, since %s cannot be unified with %s. Reason: %s" (CicMetaSubst.ppterm ~metasenv subst optimized_t) (CicMetaSubst.ppterm ~metasenv subst ct) (match e with AssertFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
1400 l @ [Some t],subst',metasenv',ugraph'
1401 | Some t,Some (_,C.Decl ct) ->
1402 let t',inferredty,subst',metasenv',ugraph1 =
1403 type_of_aux subst metasenv context t ugraph
1405 let subst'',metasenv'',ugraph2 =
1408 subst' context metasenv' inferredty ct ugraph1
1409 with e -> raise (RefineFailure (lazy (sprintf "The local context is not consistent with the canonical context, since the type %s of %s cannot be unified with the expected type %s. Reason: %s" (CicMetaSubst.ppterm metasenv' subst' inferredty) (CicMetaSubst.ppterm metasenv' subst' t) (CicMetaSubst.ppterm metasenv' subst' ct) (match e with AssertFailure msg -> Lazy.force msg | RefineFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
1411 l @ [Some t'], subst'',metasenv'',ugraph2
1413 raise (RefineFailure (lazy (sprintf "Not well typed metavariable instance %s: the local context does not instantiate an hypothesis even if the hypothesis is not restricted in the canonical context %s" (CicMetaSubst.ppterm ~metasenv subst (Cic.Meta (metano, l))) (CicMetaSubst.ppcontext ~metasenv subst canonical_context))))) ([],subst,metasenv,ugraph) l lifted_canonical_context
1415 Invalid_argument _ ->
1419 "Not well typed metavariable instance %s: the length of the local context does not match the length of the canonical context %s"
1420 (CicMetaSubst.ppterm ~metasenv subst (Cic.Meta (metano, l)))
1421 (CicMetaSubst.ppcontext ~metasenv subst canonical_context))))
1423 and check_exp_named_subst metasubst metasenv context tl ugraph =
1424 let rec check_exp_named_subst_aux metasubst metasenv substs tl ugraph =
1426 [] -> [],metasubst,metasenv,ugraph
1428 let ty_uri,ugraph1 = type_of_variable uri ugraph in
1430 CicSubstitution.subst_vars substs ty_uri in
1431 (* CSC: why was this code here? it is wrong
1432 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1433 Cic.Variable (_,Some bo,_,_) ->
1435 (RefineFailure (lazy
1436 "A variable with a body can not be explicit substituted"))
1437 | Cic.Variable (_,None,_,_) -> ()
1440 (RefineFailure (lazy
1441 ("Unkown variable definition " ^ UriManager.string_of_uri uri)))
1444 let t',typeoft,metasubst',metasenv',ugraph2 =
1445 type_of_aux metasubst metasenv context t ugraph1 in
1446 let subst = uri,t' in
1447 let metasubst'',metasenv'',ugraph3 =
1450 metasubst' context metasenv' typeoft typeofvar ugraph2
1452 raise (RefineFailure (lazy
1453 ("Wrong Explicit Named Substitution: " ^
1454 CicMetaSubst.ppterm metasenv' metasubst' typeoft ^
1455 " not unifiable with " ^
1456 CicMetaSubst.ppterm metasenv' metasubst' typeofvar)))
1458 (* FIXME: no mere tail recursive! *)
1459 let exp_name_subst, metasubst''', metasenv''', ugraph4 =
1460 check_exp_named_subst_aux
1461 metasubst'' metasenv'' (substs@[subst]) tl ugraph3
1463 ((uri,t')::exp_name_subst), metasubst''', metasenv''', ugraph4
1465 check_exp_named_subst_aux metasubst metasenv [] tl ugraph
1468 and sort_of_prod localize subst metasenv context (name,s) t (t1, t2)
1471 let module C = Cic in
1472 let context_for_t2 = (Some (name,C.Decl s))::context in
1473 let t1'' = CicReduction.whd ~subst context t1 in
1474 let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
1475 match (t1'', t2'') with
1476 | (C.Sort s1, C.Sort s2) when (s2 = C.Prop || s2 = C.Set) ->
1477 (* different than Coq manual!!! *)
1478 C.Sort s2,subst,metasenv,ugraph
1479 | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
1480 let t' = CicUniv.fresh() in
1482 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1483 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1484 C.Sort (C.Type t'),subst,metasenv,ugraph2
1486 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1487 | (C.Sort (C.CProp t1), C.Sort (C.CProp t2)) ->
1488 let t' = CicUniv.fresh() in
1490 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1491 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1492 C.Sort (C.CProp t'),subst,metasenv,ugraph2
1494 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1495 | (C.Sort (C.Type t1), C.Sort (C.CProp t2)) ->
1496 let t' = CicUniv.fresh() in
1498 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1499 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1500 C.Sort (C.CProp t'),subst,metasenv,ugraph2
1502 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1503 | (C.Sort (C.CProp t1), C.Sort (C.Type t2)) ->
1504 let t' = CicUniv.fresh() in
1506 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1507 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1508 C.Sort (C.Type t'),subst,metasenv,ugraph2
1510 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1511 | (C.Sort _,C.Sort (C.Type t1)) ->
1512 C.Sort (C.Type t1),subst,metasenv,ugraph
1513 | (C.Sort _,C.Sort (C.CProp t1)) ->
1514 C.Sort (C.CProp t1),subst,metasenv,ugraph
1515 | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
1516 | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
1517 (* TODO how can we force the meta to become a sort? If we don't we
1518 * break the invariant that refine produce only well typed terms *)
1519 (* TODO if we check the non meta term and if it is a sort then we
1520 * are likely to know the exact value of the result e.g. if the rhs
1521 * is a Sort (Prop | Set | CProp) then the result is the rhs *)
1522 let (metasenv,idx) =
1523 CicMkImplicit.mk_implicit_sort metasenv subst in
1524 let (subst, metasenv,ugraph1) =
1526 fo_unif_subst subst context_for_t2 metasenv
1527 (C.Meta (idx,[])) t2'' ugraph
1528 with _ -> assert false (* unification against a metavariable *)
1530 t2'',subst,metasenv,ugraph1
1533 enrich localization_tbl s
1537 "%s is supposed to be a type, but its type is %s"
1538 (CicMetaSubst.ppterm_in_context ~metasenv subst t context)
1539 (CicMetaSubst.ppterm_in_context ~metasenv subst t2 context))))
1541 enrich localization_tbl t
1545 "%s is supposed to be a type, but its type is %s"
1546 (CicMetaSubst.ppterm_in_context ~metasenv subst s context)
1547 (CicMetaSubst.ppterm_in_context ~metasenv subst t1 context))))
1549 and avoid_double_coercion context subst metasenv ugraph t ty =
1550 if not !pack_coercions then
1551 t,ty,subst,metasenv,ugraph
1553 let b, c1, c2, head, c1_c2_implicit = is_a_double_coercion t in
1555 let source_carr = CoercGraph.source_of c2 in
1556 let tgt_carr = CicMetaSubst.apply_subst subst ty in
1557 (match CoercGraph.look_for_coercion metasenv subst context source_carr tgt_carr
1559 | CoercGraph.SomeCoercion candidates ->
1561 HExtlib.list_findopt
1562 (function (metasenv,last,c) ->
1564 | c when not (CoercGraph.is_composite c) ->
1565 debug_print (lazy ("\nNot a composite.."^CicPp.ppterm c));
1568 let subst,metasenv,ugraph =
1569 fo_unif_subst subst context metasenv last head ugraph in
1570 debug_print (lazy ("\nprovo" ^ CicPp.ppterm c));
1575 CicPp.ppterm t ^ " ==> " ^ CicPp.ppterm c));
1576 let newt,_,subst,metasenv,ugraph =
1577 type_of_aux subst metasenv context c ugraph in
1578 debug_print (lazy "tipa...");
1579 let subst, metasenv, ugraph =
1580 (* COME MAI C'ERA UN IF su !pack_coercions ??? *)
1581 fo_unif_subst subst context metasenv newt t ugraph
1583 debug_print (lazy "unifica...");
1584 Some (newt, ty, subst, metasenv, ugraph)
1586 | RefineFailure s | Uncertain s when not !pack_coercions->
1587 debug_print s; debug_print (lazy "stop\n");None
1588 | RefineFailure s | Uncertain s ->
1589 debug_print s;debug_print (lazy "goon\n");
1591 let old_pack_coercions = !pack_coercions in
1592 pack_coercions := false; (* to avoid diverging *)
1593 let refined_c1_c2_implicit,ty,subst,metasenv,ugraph =
1594 type_of_aux subst metasenv context c1_c2_implicit ugraph
1596 pack_coercions := old_pack_coercions;
1598 is_a_double_coercion refined_c1_c2_implicit
1604 match refined_c1_c2_implicit with
1605 | Cic.Appl l -> HExtlib.list_last l
1608 let subst, metasenv, ugraph =
1609 try fo_unif_subst subst context metasenv
1611 with RefineFailure s| Uncertain s->
1612 debug_print s;assert false
1614 let subst, metasenv, ugraph =
1615 fo_unif_subst subst context metasenv
1616 refined_c1_c2_implicit t ugraph
1618 Some (refined_c1_c2_implicit,ty,subst,metasenv,ugraph)
1620 | RefineFailure s | Uncertain s ->
1621 pack_coercions := true;debug_print s;None
1622 | exn -> pack_coercions := true; raise exn))
1625 (match selected with
1629 (lazy ("#### Coercion not packed: " ^ CicPp.ppterm t));
1630 t, ty, subst, metasenv, ugraph)
1631 | _ -> t, ty, subst, metasenv, ugraph)
1633 t, ty, subst, metasenv, ugraph
1635 and typeof_list subst metasenv context ugraph l =
1636 let tlbody_and_type,subst,metasenv,ugraph =
1638 (fun x (res,subst,metasenv,ugraph) ->
1639 let x',ty,subst',metasenv',ugraph1 =
1640 type_of_aux subst metasenv context x ugraph
1642 (x', ty)::res,subst',metasenv',ugraph1
1643 ) l ([],subst,metasenv,ugraph)
1645 tlbody_and_type,subst,metasenv,ugraph
1648 allow_coercions subst metasenv context he hetype args_bo_and_ty ugraph
1650 (* given he:hety, gives beack all (c he) such that (c e):?->? *)
1651 let fix_arity n metasenv context subst he hetype ugraph =
1652 let hetype = CicMetaSubst.apply_subst subst hetype in
1653 (* instead of a dummy functional type we may create the real product
1654 * using args_bo_and_ty, but since coercions lookup ignores the
1655 * actual ariety we opt for the simple solution *)
1656 let fty = Cic.Prod(Cic.Anonymous, Cic.Sort Cic.Prop, Cic.Sort Cic.Prop) in
1657 match CoercGraph.look_for_coercion metasenv subst context hetype fty with
1658 | CoercGraph.NoCoercion -> []
1659 | CoercGraph.NotHandled ->
1660 raise (MoreArgsThanExpected (n,Uncertain (lazy "")))
1661 | CoercGraph.SomeCoercionToTgt candidates
1662 | CoercGraph.SomeCoercion candidates ->
1664 (fun (metasenv,last,coerc) ->
1666 CicMetaSubst.ppterm_in_context ~metasenv subst t context in
1668 let subst,metasenv,ugraph =
1669 fo_unif_subst subst context metasenv last he ugraph in
1670 debug_print (lazy ("New head: "^ pp coerc));
1672 CicTypeChecker.type_of_aux' ~subst metasenv context coerc
1675 debug_print (lazy (" has type: "^ pp tty));
1676 Some (coerc,tty,subst,metasenv,ugraph)
1678 | Uncertain _ | RefineFailure _
1679 | HExtlib.Localized (_,Uncertain _)
1680 | HExtlib.Localized (_,RefineFailure _) -> None
1681 | exn -> assert false)
1684 (* aux function to process the type of the head and the args in parallel *)
1685 let rec eat_prods_and_args metasenv subst context he hetype ugraph newargs =
1687 | [] -> newargs,subst,metasenv,he,hetype,ugraph
1688 | (hete, hety)::tl as args ->
1689 match (CicReduction.whd ~subst context hetype) with
1690 | Cic.Prod (n,s,t) ->
1691 let arg,subst,metasenv,ugraph =
1692 coerce_to_something allow_coercions localization_tbl
1693 hete hety s subst metasenv context ugraph in
1695 metasenv subst context he (CicSubstitution.subst (fst arg) t)
1696 ugraph (newargs@[arg]) tl
1699 match he, newargs with
1701 | Cic.Appl l, _ -> Cic.Appl (l@List.map fst newargs)
1702 | _ -> Cic.Appl (he::List.map fst newargs)
1704 (*{{{*) debug_print (lazy
1706 CicMetaSubst.ppterm_in_context ~metasenv subst x context in
1707 "Fixing arity of: "^ pp he ^ "\n that has type: "^ pp hetype^
1708 "\n but is applyed to: " ^ String.concat ";"
1709 (List.map (fun (t,_)->pp t) args_bo_and_ty)); (*}}}*)
1710 let possible_fixes =
1711 fix_arity (List.length args) metasenv context subst he hetype
1714 HExtlib.list_findopt
1715 (fun (he,hetype,subst,metasenv,ugraph) ->
1716 (* {{{ *)debug_print (lazy ("Try fix: "^
1717 CicMetaSubst.ppterm_in_context ~metasenv subst he context));
1718 debug_print (lazy (" of type: "^
1719 CicMetaSubst.ppterm_in_context
1720 ~metasenv subst hetype context)); (* }}} *)
1722 Some (eat_prods_and_args
1723 metasenv subst context he hetype ugraph [] args)
1725 | RefineFailure _ | Uncertain _
1726 | HExtlib.Localized (_,RefineFailure _)
1727 | HExtlib.Localized (_,Uncertain _) -> None)
1733 (MoreArgsThanExpected
1734 (List.length args, RefineFailure (lazy "")))
1736 (* first we check if we are in the simple case of a meta closed term *)
1737 let subst,metasenv,ugraph1,hetype',he,args_bo_and_ty =
1738 if CicUtil.is_meta_closed (CicMetaSubst.apply_subst subst hetype) then
1739 (* this optimization is to postpone fix_arity (the most common case)*)
1740 subst,metasenv,ugraph,hetype,he,args_bo_and_ty
1742 (* this (says CSC) is also useful to infer dependent types *)
1743 let pristinemenv = metasenv in
1744 let metasenv,hetype' =
1745 mk_prod_of_metas metasenv context subst args_bo_and_ty
1748 let subst,metasenv,ugraph =
1749 fo_unif_subst_eat_prods subst context metasenv hetype hetype' ugraph
1751 subst,metasenv,ugraph,hetype',he,args_bo_and_ty
1752 with RefineFailure _ | Uncertain _ ->
1753 subst,pristinemenv,ugraph,hetype,he,args_bo_and_ty
1755 let coerced_args,subst,metasenv,he,t,ugraph =
1758 metasenv subst context he hetype' ugraph1 [] args_bo_and_ty
1760 MoreArgsThanExpected (residuals,exn) ->
1761 more_args_than_expected localization_tbl metasenv
1762 subst he context hetype' residuals args_bo_and_ty exn
1764 he,(List.map fst coerced_args),t,subst,metasenv,ugraph
1766 and coerce_to_something
1767 allow_coercions localization_tbl t infty expty subst metasenv context ugraph
1769 let module CS = CicSubstitution in
1770 let module CR = CicReduction in
1771 let cs_subst = CS.subst ~avoid_beta_redexes:true in
1772 let coerce_atom_to_something t infty expty subst metasenv context ugraph =
1773 debug_print (lazy ("COERCE_ATOM_TO_SOMETHING"));
1775 CoercGraph.look_for_coercion metasenv subst context infty expty
1778 | CoercGraph.NoCoercion
1779 | CoercGraph.SomeCoercionToTgt _ -> raise (RefineFailure (lazy
1780 "coerce_atom_to_something fails since no coercions found"))
1781 | CoercGraph.NotHandled when
1782 not (CicUtil.is_meta_closed infty) ||
1783 not (CicUtil.is_meta_closed expty) -> raise (Uncertain (lazy
1784 "coerce_atom_to_something fails since carriers have metas"))
1785 | CoercGraph.NotHandled -> raise (RefineFailure (lazy
1786 "coerce_atom_to_something fails since no coercions found"))
1787 | CoercGraph.SomeCoercion candidates ->
1788 debug_print (lazy (string_of_int (List.length candidates) ^
1789 " candidates found"));
1790 let uncertain = ref false in
1794 (fun (metasenv,last,c) ->
1796 (* {{{ *) debug_print (lazy ("FO_UNIF_SUBST: " ^
1797 CicMetaSubst.ppterm_in_context ~metasenv subst last context ^
1799 CicMetaSubst.ppterm_in_context ~metasenv subst t context ^
1800 "####" ^ CicMetaSubst.ppterm_in_context ~metasenv subst c
1802 debug_print (lazy ("FO_UNIF_SUBST: " ^
1803 CicPp.ppterm last ^ " <==> " ^ CicPp.ppterm t)); (* }}} *)
1804 let subst,metasenv,ugraph =
1805 fo_unif_subst subst context metasenv last t ugraph
1807 let newt,newhety,subst,metasenv,ugraph =
1808 type_of_aux subst metasenv context c ugraph in
1809 let newt, newty, subst, metasenv, ugraph =
1810 avoid_double_coercion context subst metasenv ugraph newt expty
1812 let subst,metasenv,ugraph =
1813 fo_unif_subst subst context metasenv newhety expty ugraph in
1814 Some ((newt,newty), subst, metasenv, ugraph)
1816 | Uncertain _ -> uncertain := true; None
1817 | RefineFailure _ -> None)
1822 (fun (_,_,m1,_) (_,_,m2,_) -> List.length m1 - List.length m2)
1830 | None when !uncertain -> raise (Uncertain (lazy "coerce_atom fails"))
1831 | None -> raise (RefineFailure (lazy "coerce_atom fails"))
1833 let rec coerce_to_something_aux
1834 t infty expty subst metasenv context ugraph
1837 let subst, metasenv, ugraph =
1838 fo_unif_subst subst context metasenv infty expty ugraph
1840 (t, expty), subst, metasenv, ugraph
1841 with (Uncertain _ | RefineFailure _ as exn)
1842 when allow_coercions && !insert_coercions ->
1843 let whd = CicReduction.whd ~delta:false in
1844 let clean t s c = whd c (CicMetaSubst.apply_subst s t) in
1845 let infty = clean infty subst context in
1846 let expty = clean expty subst context in
1847 let t = clean t subst context in
1848 (*{{{*) debug_print (lazy ("COERCE_TO_SOMETHING: " ^
1849 CicMetaSubst.ppterm_in_context ~metasenv subst t context ^ " : " ^
1850 CicMetaSubst.ppterm_in_context ~metasenv subst infty context ^" ==> "^
1851 CicMetaSubst.ppterm_in_context ~metasenv subst expty context));(*}}}*)
1852 let (coerced,_),subst,metasenv,_ as result =
1853 match infty, expty, t with
1854 | Cic.Prod (nameprod,src,ty), Cic.Prod (_,src2,ty2),Cic.Fix (n,fl) ->
1855 (*{{{*) debug_print (lazy "FIX");
1857 [name,i,_(* infty *),bo] ->
1859 Some (Cic.Name name,Cic.Decl expty)::context in
1860 let (rel1, _), subst, metasenv, ugraph =
1861 coerce_to_something_aux (Cic.Rel 1)
1862 (CS.lift 1 expty) (CS.lift 1 infty) subst
1863 metasenv context_bo ugraph in
1864 let bo = cs_subst rel1 (CS.lift_from 2 1 bo) in
1865 let (bo,_), subst, metasenv, ugraph =
1866 coerce_to_something_aux bo (CS.lift 1 infty) (CS.lift 1
1868 metasenv context_bo ugraph
1870 (Cic.Fix (n,[name,i,expty,bo]),expty),subst,metasenv,ugraph
1871 | _ -> assert false (* not implemented yet *)) (*}}}*)
1872 | _,_, Cic.MutCase (uri,tyno,outty,m,pl) ->
1873 (*{{{*) debug_print (lazy "CASE");
1874 (* {{{ helper functions *)
1875 let get_cl_and_left_p uri tyno outty ugraph =
1876 match CicEnvironment.get_obj ugraph uri with
1877 | Cic.InductiveDefinition (tl, _, leftno, _),ugraph ->
1880 match CicReduction.whd ~delta:false ctx t with
1881 | Cic.Prod (name,src,tgt) ->
1882 let ctx = Some (name, Cic.Decl src) :: ctx in
1888 let rec skip_lambda_delifting t n =
1891 | Cic.Lambda (_,_,t),n ->
1892 skip_lambda_delifting
1893 (CS.subst (Cic.Implicit None) t) (n - 1)
1896 let get_l_r_p n = function
1897 | Cic.Lambda (_,Cic.MutInd _,_) -> [],[]
1898 | Cic.Lambda (_,Cic.Appl (Cic.MutInd _ :: args),_) ->
1899 HExtlib.split_nth n args
1902 let _, _, ty, cl = List.nth tl tyno in
1903 let pis = count_pis ty in
1904 let rno = pis - leftno in
1905 let t = skip_lambda_delifting outty rno in
1906 let left_p, _ = get_l_r_p leftno t in
1907 let instantiale_with_left cl =
1911 (fun t p -> match t with
1912 | Cic.Prod (_,_,t) ->
1918 let cl = instantiale_with_left (List.map snd cl) in
1919 cl, left_p, leftno, rno, ugraph
1922 let rec keep_lambdas_and_put_expty ctx t bo right_p matched n =
1925 let rec mkr n = function
1926 | [] -> [] | _::tl -> Cic.Rel n :: mkr (n+1) tl
1929 CicReplace.replace_lifting
1930 ~equality:(fun _ -> CicUtil.alpha_equivalence)
1932 ~what:(matched::right_p)
1933 ~with_what:(Cic.Rel 1::List.rev (mkr 2 right_p))
1937 | Cic.Lambda (name, src, tgt),_ ->
1938 Cic.Lambda (name, src,
1939 keep_lambdas_and_put_expty
1940 (Some (name, Cic.Decl src)::ctx) tgt (CS.lift 1 bo)
1941 (List.map (CS.lift 1) right_p) (CS.lift 1 matched) (n-1))
1944 let eq_uri, eq, eq_refl =
1945 match LibraryObjects.eq_URI () with
1946 | None -> HLog.warn "no default equality"; raise exn
1947 | Some u -> u, Cic.MutInd(u,0,[]), Cic.MutConstruct (u,0,1,[])
1950 metasenv subst context uri tyno cty outty mty m leftno i
1952 let rec aux context outty par k mty m = function
1953 | Cic.Prod (name, src, tgt) ->
1956 (Some (name, Cic.Decl src) :: context)
1957 (CS.lift 1 outty) (Cic.Rel k::par) (k+1)
1958 (CS.lift 1 mty) (CS.lift 1 m) tgt
1960 Cic.Prod (name, src, t), k
1963 let k = Cic.MutConstruct (uri,tyno,i,[]) in
1964 if par <> [] then Cic.Appl (k::par) else k
1966 Cic.Prod (Cic.Name "p",
1967 Cic.Appl [eq; mty; m; k],
1969 (CR.head_beta_reduce ~delta:false
1970 (Cic.Appl [outty;k])))),k
1971 | Cic.Appl (Cic.MutInd _::pl) ->
1972 let left_p,right_p = HExtlib.split_nth leftno pl in
1973 let has_rights = right_p <> [] in
1975 let k = Cic.MutConstruct (uri,tyno,i,[]) in
1976 Cic.Appl (k::left_p@par)
1980 CicTypeChecker.type_of_aux' ~subst metasenv context k
1981 CicUniv.oblivion_ugraph
1983 | Cic.Appl (Cic.MutInd _::args),_ ->
1984 snd (HExtlib.split_nth leftno args)
1986 with CicTypeChecker.TypeCheckerFailure _-> assert false
1989 CR.head_beta_reduce ~delta:false
1990 (Cic.Appl (outty ::right_p @ [k])),k
1992 Cic.Prod (Cic.Name "p",
1993 Cic.Appl [eq; mty; m; k],
1995 (CR.head_beta_reduce ~delta:false
1996 (Cic.Appl (outty ::right_p @ [k]))))),k
1999 aux context outty [] 1 mty m cty
2001 let add_lambda_for_refl_m pbo rno mty m k cty =
2002 (* k lives in the right context *)
2003 if rno <> 0 then pbo else
2004 let rec aux mty m = function
2005 | Cic.Lambda (name,src,bo), Cic.Prod (_,_,ty) ->
2006 Cic.Lambda (name,src,
2007 (aux (CS.lift 1 mty) (CS.lift 1 m) (bo,ty)))
2009 Cic.Lambda (Cic.Name "p",
2010 Cic.Appl [eq; mty; m; k],CS.lift 1 t)
2014 let add_pi_for_refl_m new_outty mty m rno =
2015 if rno <> 0 then new_outty else
2016 let rec aux m mty = function
2017 | Cic.Lambda (name, src, tgt) ->
2018 Cic.Lambda (name, src,
2019 aux (CS.lift 1 m) (CS.lift 1 mty) tgt)
2022 (Cic.Anonymous, Cic.Appl [eq;mty;m;Cic.Rel 1],
2026 in (* }}} end helper functions *)
2027 (* constructors types with left params already instantiated *)
2028 let outty = CicMetaSubst.apply_subst subst outty in
2029 let cl, left_p, leftno,rno,ugraph =
2030 get_cl_and_left_p uri tyno outty ugraph
2035 CicTypeChecker.type_of_aux' ~subst metasenv context m
2036 CicUniv.oblivion_ugraph
2038 | (Cic.MutInd _ | Cic.Meta _) as mty,_ -> [], mty
2039 | Cic.Appl ((Cic.MutInd _|Cic.Meta _)::args) as mty,_ ->
2040 snd (HExtlib.split_nth leftno args), mty
2042 with CicTypeChecker.TypeCheckerFailure _ ->
2043 raise (AssertFailure(lazy "already ill-typed matched term"))
2046 keep_lambdas_and_put_expty context outty expty right_p m (rno+1)
2049 (lazy ("CASE: new_outty: " ^ CicMetaSubst.ppterm_in_context
2050 ~metasenv subst new_outty context));
2051 let _,pl,subst,metasenv,ugraph =
2053 (fun cty pbo (i, acc, s, menv, ugraph) ->
2054 (* Pi k_par, (Pi H:m=(K_i left_par k_par)),
2055 * (new_)outty right_par (K_i left_par k_par) *)
2057 add_params menv s context uri tyno
2058 cty outty mty m leftno i in
2060 (lazy ("CASE: infty_pbo: "^CicMetaSubst.ppterm_in_context
2061 ~metasenv subst infty_pbo context));
2062 let expty_pbo, k = (* k is (K_i left_par k_par) *)
2063 add_params menv s context uri tyno
2064 cty new_outty mty m leftno i in
2066 (lazy ("CASE: expty_pbo: "^CicMetaSubst.ppterm_in_context
2067 ~metasenv subst expty_pbo context));
2068 let pbo = add_lambda_for_refl_m pbo rno mty m k cty in
2070 (lazy ("CASE: pbo: " ^ CicMetaSubst.ppterm_in_context
2071 ~metasenv subst pbo context));
2072 let (pbo, _), subst, metasenv, ugraph =
2073 coerce_to_something_aux pbo infty_pbo expty_pbo
2074 s menv context ugraph
2077 (lazy ("CASE: pbo: " ^ CicMetaSubst.ppterm_in_context
2078 ~metasenv subst pbo context));
2079 (i-1, pbo::acc, subst, metasenv, ugraph))
2080 cl pl (List.length pl, [], subst, metasenv, ugraph)
2082 let new_outty = add_pi_for_refl_m new_outty mty m rno in
2084 (lazy ("CASE: new_outty: " ^ CicMetaSubst.ppterm_in_context
2085 ~metasenv subst new_outty context));
2088 let refl_m=Cic.Appl[eq_refl;mty;m]in
2089 Cic.Appl [Cic.MutCase(uri,tyno,new_outty,m,pl);refl_m]
2091 Cic.MutCase(uri,tyno,new_outty,m,pl)
2093 (t, expty), subst, metasenv, ugraph (*}}}*)
2094 | Cic.Prod (nameprod, src, ty),Cic.Prod (_, src2, ty2), _ ->
2095 (*{{{*) debug_print (lazy "LAM");
2097 FreshNamesGenerator.mk_fresh_name
2098 ~subst metasenv context ~typ:src2 Cic.Anonymous
2100 let context_src2 = (Some (name_con, Cic.Decl src2) :: context) in
2101 (* contravariant part: the argument of f:src->ty *)
2102 let (rel1, _), subst, metasenv, ugraph =
2103 coerce_to_something_aux
2104 (Cic.Rel 1) (CS.lift 1 src2)
2105 (CS.lift 1 src) subst metasenv context_src2 ugraph
2107 (* covariant part: the result of f(c x); x:src2; (c x):src *)
2110 | Cic.Lambda (n,_,bo) -> n, cs_subst rel1 (CS.lift_from 2 1 bo)
2111 | _ -> name_con, Cic.Appl[CS.lift 1 t;rel1]
2113 (* we fix the possible dependency problem in the source ty *)
2114 let ty = cs_subst rel1 (CS.lift_from 2 1 ty) in
2115 let (bo, _), subst, metasenv, ugraph =
2116 coerce_to_something_aux
2117 bo ty ty2 subst metasenv context_src2 ugraph
2119 let coerced = Cic.Lambda (name_t,src2, bo) in
2120 (coerced, expty), subst, metasenv, ugraph (*}}}*)
2122 (*{{{*)debug_print (lazy ("ATOM: "^CicMetaSubst.ppterm_in_context
2123 ~metasenv subst infty context ^ " ==> " ^
2124 CicMetaSubst.ppterm_in_context ~metasenv subst expty context));
2125 coerce_atom_to_something
2126 t infty expty subst metasenv context ugraph (*}}}*)
2128 debug_print (lazy ("COERCE TO SOMETHING END: "^
2129 CicMetaSubst.ppterm_in_context ~metasenv subst coerced context));
2133 coerce_to_something_aux t infty expty subst metasenv context ugraph
2134 with Uncertain _ | RefineFailure _ as exn ->
2137 CicMetaSubst.ppterm_in_context metasenv subst t context ^
2138 " has type " ^ CicMetaSubst.ppterm_in_context metasenv subst
2139 infty context ^ " but is here used with type " ^
2140 CicMetaSubst.ppterm_in_context metasenv subst expty context)
2142 enrich localization_tbl ~f t exn
2144 and coerce_to_sort localization_tbl t infty subst context metasenv uragph =
2145 match CicReduction.whd ~delta:false ~subst context infty with
2146 | Cic.Meta _ | Cic.Sort _ ->
2147 t,infty, subst, metasenv, ugraph
2149 debug_print (lazy ("COERCE TO SORT: "^CicMetaSubst.ppterm_in_context
2150 ~metasenv subst src context));
2151 let tgt = Cic.Sort (Cic.Type (CicUniv.fresh())) in
2153 let (t, ty_t), subst, metasenv, ugraph =
2154 coerce_to_something true
2155 localization_tbl t src tgt subst metasenv context ugraph
2157 debug_print (lazy ("COERCE TO SORT END: "^
2158 CicMetaSubst.ppterm_in_context ~metasenv subst t context));
2159 t, ty_t, subst, metasenv, ugraph
2160 with HExtlib.Localized (_, exn) ->
2162 lazy ("(7)The term " ^
2163 CicMetaSubst.ppterm_in_context ~metasenv subst t context
2164 ^ " is not a type since it has type " ^
2165 CicMetaSubst.ppterm_in_context ~metasenv subst src context
2166 ^ " that is not a sort")
2168 enrich localization_tbl ~f t exn
2171 (* eat prods ends here! *)
2173 let t',ty,subst',metasenv',ugraph1 =
2174 type_of_aux [] metasenv context t ugraph
2176 let substituted_t = CicMetaSubst.apply_subst subst' t' in
2177 let substituted_ty = CicMetaSubst.apply_subst subst' ty in
2178 (* Andrea: ho rimesso qui l'applicazione della subst al
2179 metasenv dopo che ho droppato l'invariante che il metsaenv
2180 e' sempre istanziato *)
2181 let substituted_metasenv =
2182 CicMetaSubst.apply_subst_metasenv subst' metasenv' in
2184 (* substituted_t,substituted_ty,substituted_metasenv *)
2185 (* ANDREA: spostare tutta questa robaccia da un altra parte *)
2187 if clean_dummy_dependent_types then
2188 FreshNamesGenerator.clean_dummy_dependent_types substituted_t
2189 else substituted_t in
2191 if clean_dummy_dependent_types then
2192 FreshNamesGenerator.clean_dummy_dependent_types substituted_ty
2193 else substituted_ty in
2194 let cleaned_metasenv =
2195 if clean_dummy_dependent_types then
2197 (function (n,context,ty) ->
2198 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty in
2203 | Some (n, Cic.Decl t) ->
2205 Cic.Decl (FreshNamesGenerator.clean_dummy_dependent_types t))
2206 | Some (n, Cic.Def (bo,ty)) ->
2207 let bo' = FreshNamesGenerator.clean_dummy_dependent_types bo in
2208 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty
2210 Some (n, Cic.Def (bo',ty'))
2214 ) substituted_metasenv
2216 substituted_metasenv
2218 (cleaned_t,cleaned_ty,cleaned_metasenv,ugraph1)
2221 let undebrujin uri typesno tys t =
2224 (fun (name,_,_,_) (i,t) ->
2225 (* here the explicit_named_substituion is assumed to be *)
2227 let t' = Cic.MutInd (uri,i,[]) in
2228 let t = CicSubstitution.subst t' t in
2230 ) tys (typesno - 1,t))
2232 let map_first_n n start f g l =
2233 let rec aux acc k l =
2236 | [] -> raise (Invalid_argument "map_first_n")
2237 | hd :: tl -> f hd k (aux acc (k+1) tl)
2243 (*CSC: this is a very rough approximation; to be finished *)
2244 let are_all_occurrences_positive metasenv ugraph uri tys leftno =
2245 let subst,metasenv,ugraph,tys =
2247 (fun (name,ind,arity,cl) (subst,metasenv,ugraph,acc) ->
2248 let subst,metasenv,ugraph,cl =
2250 (fun (name,ty) (subst,metasenv,ugraph,acc) ->
2251 let rec aux ctx k subst = function
2252 | Cic.Appl((Cic.MutInd (uri',_,_)as hd)::tl) when uri = uri'->
2253 let subst,metasenv,ugraph,tl =
2255 (subst,metasenv,ugraph,[])
2256 (fun t n (subst,metasenv,ugraph,acc) ->
2257 let subst,metasenv,ugraph =
2259 subst ctx metasenv t (Cic.Rel (k-n)) ugraph
2261 subst,metasenv,ugraph,(t::acc))
2262 (fun (s,m,g,acc) tl -> assert(acc=[]);(s,m,g,tl))
2265 subst,metasenv,ugraph,(Cic.Appl (hd::tl))
2266 | Cic.MutInd(uri',_,_) as t when uri = uri'->
2267 subst,metasenv,ugraph,t
2268 | Cic.Prod (name,s,t) ->
2269 let ctx = (Some (name,Cic.Decl s))::ctx in
2270 let subst,metasenv,ugraph,t = aux ctx (k+1) subst t in
2271 subst,metasenv,ugraph,Cic.Prod (name,s,t)
2275 (lazy "not well formed constructor type"))
2277 let subst,metasenv,ugraph,ty = aux [] 0 subst ty in
2278 subst,metasenv,ugraph,(name,ty) :: acc)
2279 cl (subst,metasenv,ugraph,[])
2281 subst,metasenv,ugraph,(name,ind,arity,cl)::acc)
2282 tys ([],metasenv,ugraph,[])
2284 let substituted_tys =
2286 (fun (name,ind,arity,cl) ->
2288 List.map (fun (name, ty) -> name,CicMetaSubst.apply_subst subst ty) cl
2290 name,ind,CicMetaSubst.apply_subst subst arity,cl)
2293 metasenv,ugraph,substituted_tys
2295 let typecheck metasenv uri obj ~localization_tbl =
2296 let ugraph = CicUniv.oblivion_ugraph in
2298 Cic.Constant (name,Some bo,ty,args,attrs) ->
2299 (* CSC: ugly code. Here I need to retrieve in advance the loc of bo
2300 since type_of_aux' destroys localization information (which are
2301 preserved by type_of_aux *)
2304 Cic.CicHash.find localization_tbl bo
2306 HLog.debug ("!!! NOT LOCALIZED: " ^ CicPp.ppterm bo);
2308 let bo',boty,metasenv,ugraph =
2309 type_of_aux' ~localization_tbl metasenv [] bo ugraph in
2310 let ty',_,metasenv,ugraph =
2311 type_of_aux' ~localization_tbl metasenv [] ty ugraph in
2312 let subst,metasenv,ugraph =
2314 fo_unif_subst [] [] metasenv boty ty' ugraph
2317 | Uncertain _ as exn ->
2320 CicMetaSubst.ppterm_in_context ~metasenv [] bo' [] ^
2322 CicMetaSubst.ppterm_in_context ~metasenv [] boty [] ^
2323 " but is here used with type " ^
2324 CicMetaSubst.ppterm_in_context ~metasenv [] ty' [])
2328 RefineFailure _ -> RefineFailure msg
2329 | Uncertain _ -> Uncertain msg
2332 raise (HExtlib.Localized (loc exn',exn'))
2334 let bo' = CicMetaSubst.apply_subst subst bo' in
2335 let ty' = CicMetaSubst.apply_subst subst ty' in
2336 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
2337 Cic.Constant (name,Some bo',ty',args,attrs),metasenv,ugraph
2338 | Cic.Constant (name,None,ty,args,attrs) ->
2339 let ty',_,metasenv,ugraph =
2340 type_of_aux' ~localization_tbl metasenv [] ty ugraph
2342 Cic.Constant (name,None,ty',args,attrs),metasenv,ugraph
2343 | Cic.CurrentProof (name,metasenv',bo,ty,args,attrs) ->
2344 assert (metasenv' = metasenv);
2345 (* Here we do not check the metasenv for correctness *)
2346 let bo',boty,metasenv,ugraph =
2347 type_of_aux' ~localization_tbl metasenv [] bo ugraph in
2348 let ty',sort,metasenv,ugraph =
2349 type_of_aux' ~localization_tbl metasenv [] ty ugraph in
2353 (* instead of raising Uncertain, let's hope that the meta will become
2356 | _ -> raise (RefineFailure (lazy "The term provided is not a type"))
2358 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
2359 let bo' = CicMetaSubst.apply_subst subst bo' in
2360 let ty' = CicMetaSubst.apply_subst subst ty' in
2361 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
2362 Cic.CurrentProof (name,metasenv,bo',ty',args,attrs),metasenv,ugraph
2363 | Cic.Variable _ -> assert false (* not implemented *)
2364 | Cic.InductiveDefinition (tys,args,paramsno,attrs) ->
2365 (*CSC: this code is greately simplified and many many checks are missing *)
2366 (*CSC: e.g. the constructors are not required to build their own types, *)
2367 (*CSC: the arities are not required to have as type a sort, etc. *)
2368 let uri = match uri with Some uri -> uri | None -> assert false in
2369 let typesno = List.length tys in
2370 (* first phase: we fix only the types *)
2371 let metasenv,ugraph,tys =
2373 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
2374 let ty',_,metasenv,ugraph =
2375 (* clean_dummy_dependent_types: false to avoid cleaning the names
2376 of the left products, that must be identical to those of the
2377 constructors; however, non-left products should probably be
2379 type_of_aux' ~clean_dummy_dependent_types:false ~localization_tbl
2380 metasenv [] ty ugraph
2382 metasenv,ugraph,(name,b,ty',cl)::res
2383 ) tys (metasenv,ugraph,[]) in
2385 List.rev_map (fun (name,_,ty,_)-> Some (Cic.Name name,Cic.Decl ty)) tys in
2386 (* second phase: we fix only the constructors *)
2387 let saved_menv = metasenv in
2388 let metasenv,ugraph,tys =
2390 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
2391 let metasenv,ugraph,cl' =
2393 (fun (name,ty) (metasenv,ugraph,res) ->
2395 CicTypeChecker.debrujin_constructor
2396 ~cb:(relocalize localization_tbl) uri typesno [] ty in
2397 let ty',_,metasenv,ugraph =
2398 type_of_aux' ~localization_tbl metasenv con_context ty ugraph in
2399 let ty' = undebrujin uri typesno tys ty' in
2400 metasenv@saved_menv,ugraph,(name,ty')::res
2401 ) cl (metasenv,ugraph,[])
2403 metasenv,ugraph,(name,b,ty,cl')::res
2404 ) tys (metasenv,ugraph,[]) in
2405 (* third phase: we check the positivity condition *)
2406 let metasenv,ugraph,tys =
2407 are_all_occurrences_positive metasenv ugraph uri tys paramsno
2409 Cic.InductiveDefinition (tys,args,paramsno,attrs),metasenv,ugraph
2412 (* sara' piu' veloce che raffinare da zero? mah.... *)
2413 let pack_coercion metasenv ctx t =
2414 let module C = Cic in
2415 let rec merge_coercions ctx =
2416 let aux = (fun (u,t) -> u,merge_coercions ctx t) in
2418 | C.Rel _ | C.Sort _ | C.Implicit _ as t -> t
2419 | C.Meta (n,subst) ->
2422 (function None -> None | Some t -> Some (merge_coercions ctx t)) subst
2425 | C.Cast (te,ty) -> C.Cast (merge_coercions ctx te, merge_coercions ctx ty)
2426 | C.Prod (name,so,dest) ->
2427 let ctx' = (Some (name,C.Decl so))::ctx in
2428 C.Prod (name, merge_coercions ctx so, merge_coercions ctx' dest)
2429 | C.Lambda (name,so,dest) ->
2430 let ctx' = (Some (name,C.Decl so))::ctx in
2431 C.Lambda (name, merge_coercions ctx so, merge_coercions ctx' dest)
2432 | C.LetIn (name,so,ty,dest) ->
2433 let ctx' = Some (name,(C.Def (so,ty)))::ctx in
2435 (name, merge_coercions ctx so, merge_coercions ctx ty,
2436 merge_coercions ctx' dest)
2438 let l = List.map (merge_coercions ctx) l in
2440 let b,_,_,_,_ = is_a_double_coercion t in
2442 let ugraph = CicUniv.oblivion_ugraph in
2443 let old_insert_coercions = !insert_coercions in
2444 insert_coercions := false;
2445 let newt, _, menv, _ =
2447 type_of_aux' metasenv ctx t ugraph
2448 with RefineFailure _ | Uncertain _ ->
2451 insert_coercions := old_insert_coercions;
2452 if metasenv <> [] || menv = [] then
2455 (prerr_endline "PUO' SUCCEDERE!!!!!";t)
2458 | C.Var (uri,exp_named_subst) ->
2459 let exp_named_subst = List.map aux exp_named_subst in
2460 C.Var (uri, exp_named_subst)
2461 | C.Const (uri,exp_named_subst) ->
2462 let exp_named_subst = List.map aux exp_named_subst in
2463 C.Const (uri, exp_named_subst)
2464 | C.MutInd (uri,tyno,exp_named_subst) ->
2465 let exp_named_subst = List.map aux exp_named_subst in
2466 C.MutInd (uri,tyno,exp_named_subst)
2467 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
2468 let exp_named_subst = List.map aux exp_named_subst in
2469 C.MutConstruct (uri,tyno,consno,exp_named_subst)
2470 | C.MutCase (uri,tyno,out,te,pl) ->
2471 let pl = List.map (merge_coercions ctx) pl in
2472 C.MutCase (uri,tyno,merge_coercions ctx out, merge_coercions ctx te, pl)
2473 | C.Fix (fno, fl) ->
2476 (fun l (n,_,ty,_) -> (Some (C.Name n,C.Decl ty))::l)
2481 (fun (name,idx,ty,bo) ->
2482 (name,idx,merge_coercions ctx ty,merge_coercions ctx' bo))
2486 | C.CoFix (fno, fl) ->
2489 (fun l (n,ty,_) -> (Some (C.Name n,C.Decl ty))::l)
2494 (fun (name,ty,bo) ->
2495 (name, merge_coercions ctx ty, merge_coercions ctx' bo))
2500 merge_coercions ctx t
2503 let pack_coercion_metasenv conjectures = conjectures (*
2505 TASSI: this code war written when coercions were a toy,
2506 now packing coercions involves unification thus
2507 the metasenv may change, and this pack coercion
2508 does not handle that.
2510 let module C = Cic in
2512 (fun (i, ctx, ty) ->
2518 Some (name, C.Decl t) ->
2519 Some (name, C.Decl (pack_coercion conjectures ctx t))
2520 | Some (name, C.Def (t,None)) ->
2521 Some (name,C.Def (pack_coercion conjectures ctx t,None))
2522 | Some (name, C.Def (t,Some ty)) ->
2523 Some (name, C.Def (pack_coercion conjectures ctx t,
2524 Some (pack_coercion conjectures ctx ty)))
2530 ((i,ctx,pack_coercion conjectures ctx ty))
2535 let pack_coercion_obj obj = obj (*
2537 TASSI: this code war written when coercions were a toy,
2538 now packing coercions involves unification thus
2539 the metasenv may change, and this pack coercion
2540 does not handle that.
2542 let module C = Cic in
2544 | C.Constant (id, body, ty, params, attrs) ->
2548 | Some body -> Some (pack_coercion [] [] body)
2550 let ty = pack_coercion [] [] ty in
2551 C.Constant (id, body, ty, params, attrs)
2552 | C.Variable (name, body, ty, params, attrs) ->
2556 | Some body -> Some (pack_coercion [] [] body)
2558 let ty = pack_coercion [] [] ty in
2559 C.Variable (name, body, ty, params, attrs)
2560 | C.CurrentProof (name, conjectures, body, ty, params, attrs) ->
2561 let conjectures = pack_coercion_metasenv conjectures in
2562 let body = pack_coercion conjectures [] body in
2563 let ty = pack_coercion conjectures [] ty in
2564 C.CurrentProof (name, conjectures, body, ty, params, attrs)
2565 | C.InductiveDefinition (indtys, params, leftno, attrs) ->
2568 (fun (name, ind, arity, cl) ->
2569 let arity = pack_coercion [] [] arity in
2571 List.map (fun (name, ty) -> (name,pack_coercion [] [] ty)) cl
2573 (name, ind, arity, cl))
2576 C.InductiveDefinition (indtys, params, leftno, attrs) *)
2581 let type_of_aux' metasenv context term =
2584 type_of_aux' metasenv context term in
2586 ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty));
2588 ("@@@ REFINE SUCCESSFUL (metasenv):\n" ^ CicMetaSubst.ppmetasenv ~sep:";" m []));
2591 | RefineFailure msg as e ->
2592 debug_print (lazy ("@@@ REFINE FAILED: " ^ msg));
2594 | Uncertain msg as e ->
2595 debug_print (lazy ("@@@ REFINE UNCERTAIN: " ^ msg));
2599 let profiler2 = HExtlib.profile "CicRefine"
2601 let type_of_aux' ?localization_tbl metasenv context term ugraph =
2602 profiler2.HExtlib.profile
2603 (type_of_aux' ?localization_tbl metasenv context term) ugraph
2605 let typecheck ~localization_tbl metasenv uri obj =
2606 profiler2.HExtlib.profile (typecheck ~localization_tbl metasenv uri) obj
2608 let _ = DoubleTypeInference.pack_coercion := pack_coercion;;
2609 (* vim:set foldmethod=marker: *)