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/.
28 exception RefineFailure of string Lazy.t;;
29 exception Uncertain of string Lazy.t;;
30 exception AssertFailure of string Lazy.t;;
32 let debug_print = fun _ -> ()
34 let profiler = HExtlib.profile "CicRefine.fo_unif"
36 let fo_unif_subst subst context metasenv t1 t2 ugraph =
39 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
40 in profiler.HExtlib.profile foo ()
42 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
43 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
49 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
50 | (_,_) -> raise (AssertFailure (lazy "split: list too short"))
53 let exp_impl metasenv subst context term =
54 let rec aux metasenv context = function
55 | (Cic.Rel _) as t -> metasenv, t
56 | (Cic.Sort _) as t -> metasenv, t
57 | Cic.Const (uri, subst) ->
58 let metasenv', subst' = do_subst metasenv context subst in
59 metasenv', Cic.Const (uri, subst')
60 | Cic.Var (uri, subst) ->
61 let metasenv', subst' = do_subst metasenv context subst in
62 metasenv', Cic.Var (uri, subst')
63 | Cic.MutInd (uri, i, subst) ->
64 let metasenv', subst' = do_subst metasenv context subst in
65 metasenv', Cic.MutInd (uri, i, subst')
66 | Cic.MutConstruct (uri, i, j, subst) ->
67 let metasenv', subst' = do_subst metasenv context subst in
68 metasenv', Cic.MutConstruct (uri, i, j, subst')
70 let metasenv', l' = do_local_context metasenv context l in
71 metasenv', Cic.Meta (n, l')
72 | Cic.Implicit (Some `Type) ->
73 let (metasenv', idx) = CicMkImplicit.mk_implicit_type metasenv subst context in
74 let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
75 metasenv', Cic.Meta (idx, irl)
76 | Cic.Implicit (Some `Closed) ->
77 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst [] in
78 metasenv', Cic.Meta (idx, [])
79 | Cic.Implicit None ->
80 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst context in
81 let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
82 metasenv', Cic.Meta (idx, irl)
83 | Cic.Implicit _ -> assert false
84 | Cic.Cast (te, ty) ->
85 let metasenv', ty' = aux metasenv context ty in
86 let metasenv'', te' = aux metasenv' context te in
87 metasenv'', Cic.Cast (te', ty')
88 | Cic.Prod (name, s, t) ->
89 let metasenv', s' = aux metasenv context s in
90 metasenv', Cic.Prod (name, s', t)
91 | Cic.Lambda (name, s, t) ->
92 let metasenv', s' = aux metasenv context s in
93 metasenv', Cic.Lambda (name, s', t)
94 | Cic.LetIn (name, s, t) ->
95 let metasenv', s' = aux metasenv context s in
96 metasenv', Cic.LetIn (name, s', t)
97 | Cic.Appl l when List.length l > 1 ->
100 (fun term (metasenv, terms) ->
101 let new_metasenv, term = aux metasenv context term in
102 new_metasenv, term :: terms)
105 metasenv', Cic.Appl l'
106 | Cic.Appl _ -> assert false
107 | Cic.MutCase (uri, i, outtype, term, patterns) ->
110 (fun term (metasenv, terms) ->
111 let new_metasenv, term = aux metasenv context term in
112 new_metasenv, term :: terms)
113 (outtype :: term :: patterns) (metasenv, [])
115 let outtype', term', patterns' =
117 | outtype' :: term' :: patterns' -> outtype', term', patterns'
120 metasenv', Cic.MutCase (uri, i, outtype', term', patterns')
121 | Cic.Fix (i, funs) ->
122 let metasenv', types =
124 (fun (name, _, typ, _) (metasenv, types) ->
125 let new_metasenv, new_type = aux metasenv context typ in
126 (new_metasenv, (name, new_type) :: types))
129 let rec combine = function
130 | ((name, index, _, body) :: funs_tl),
131 ((_, typ) :: typ_tl) ->
132 (name, index, typ, body) :: combine (funs_tl, typ_tl)
136 let funs' = combine (funs, types) in
137 metasenv', Cic.Fix (i, funs')
138 | Cic.CoFix (i, funs) ->
139 let metasenv', types =
141 (fun (name, typ, _) (metasenv, types) ->
142 let new_metasenv, new_type = aux metasenv context typ in
143 (new_metasenv, (name, new_type) :: types))
146 let rec combine = function
147 | ((name, _, body) :: funs_tl),
148 ((_, typ) :: typ_tl) ->
149 (name, typ, body) :: combine (funs_tl, typ_tl)
153 let funs' = combine (funs, types) in
154 metasenv', Cic.CoFix (i, funs')
155 | term -> metasenv,term
156 and do_subst metasenv context subst =
158 (fun (uri, term) (metasenv, substs) ->
159 let metasenv', term' = aux metasenv context term in
160 (metasenv', (uri, term') :: substs))
162 and do_local_context metasenv context local_context =
164 (fun term (metasenv, local_context) ->
165 let metasenv', term' =
167 | None -> metasenv, None
169 let metasenv', term' = aux metasenv context term in
170 metasenv', Some term'
172 metasenv', term' :: local_context)
173 local_context (metasenv, [])
175 aux metasenv context term
178 let rec type_of_constant uri ugraph =
179 let module C = Cic in
180 let module R = CicReduction in
181 let module U = UriManager in
182 let _ = CicTypeChecker.typecheck uri in
185 CicEnvironment.get_cooked_obj ugraph uri
186 with Not_found -> assert false
189 C.Constant (_,_,ty,_,_) -> ty,u
190 | C.CurrentProof (_,_,_,ty,_,_) -> ty,u
193 (RefineFailure (lazy ("Unknown constant definition " ^ U.string_of_uri uri)))
195 and type_of_variable uri ugraph =
196 let module C = Cic in
197 let module R = CicReduction in
198 let module U = UriManager in
199 let _ = CicTypeChecker.typecheck uri in
202 CicEnvironment.get_cooked_obj ugraph uri
203 with Not_found -> assert false
206 C.Variable (_,_,ty,_,_) -> ty,u
210 (lazy ("Unknown variable definition " ^ UriManager.string_of_uri uri)))
212 and type_of_mutual_inductive_defs uri i ugraph =
213 let module C = Cic in
214 let module R = CicReduction in
215 let module U = UriManager in
216 let _ = CicTypeChecker.typecheck uri in
219 CicEnvironment.get_cooked_obj ugraph uri
220 with Not_found -> assert false
223 C.InductiveDefinition (dl,_,_,_) ->
224 let (_,_,arity,_) = List.nth dl i in
229 (lazy ("Unknown mutual inductive definition " ^ U.string_of_uri uri)))
231 and type_of_mutual_inductive_constr uri i j ugraph =
232 let module C = Cic in
233 let module R = CicReduction in
234 let module U = UriManager in
235 let _ = CicTypeChecker.typecheck uri in
238 CicEnvironment.get_cooked_obj ugraph uri
239 with Not_found -> assert false
242 C.InductiveDefinition (dl,_,_,_) ->
243 let (_,_,_,cl) = List.nth dl i in
244 let (_,ty) = List.nth cl (j-1) in
250 ("Unkown mutual inductive definition " ^ U.string_of_uri uri)))
253 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
255 (* the check_branch function checks if a branch of a case is refinable.
256 It returns a pair (outype_instance,args), a subst and a metasenv.
257 outype_instance is the expected result of applying the case outtype
259 The problem is that outype is in general unknown, and we should
260 try to synthesize it from the above information, that is in general
261 a second order unification problem. *)
263 and check_branch n context metasenv subst left_args_no actualtype term expectedtype ugraph =
264 let module C = Cic in
265 (* let module R = CicMetaSubst in *)
266 let module R = CicReduction in
267 match R.whd ~subst context expectedtype with
269 (n,context,actualtype, [term]), subst, metasenv, ugraph
270 | C.Appl (C.MutInd (_,_,_)::tl) ->
271 let (_,arguments) = split tl left_args_no in
272 (n,context,actualtype, arguments@[term]), subst, metasenv, ugraph
273 | C.Prod (name,so,de) ->
274 (* we expect that the actual type of the branch has the due
276 (match R.whd ~subst context actualtype with
277 C.Prod (name',so',de') ->
278 let subst, metasenv, ugraph1 =
279 fo_unif_subst subst context metasenv so so' ugraph in
281 (match CicSubstitution.lift 1 term with
282 C.Appl l -> C.Appl (l@[C.Rel 1])
283 | t -> C.Appl [t ; C.Rel 1]) in
284 (* we should also check that the name variable is anonymous in
285 the actual type de' ?? *)
287 ((Some (name,(C.Decl so)))::context)
288 metasenv subst left_args_no de' term' de ugraph1
289 | _ -> raise (AssertFailure (lazy "Wrong number of arguments")))
290 | _ -> raise (AssertFailure (lazy "Prod or MutInd expected"))
292 and type_of_aux' metasenv context t ugraph =
293 let metasenv, t = exp_impl metasenv [] context t in
294 let rec type_of_aux subst metasenv context t ugraph =
295 let module C = Cic in
296 let module S = CicSubstitution in
297 let module U = UriManager in
298 (* this stops on binders, so we have to call it every time *)
303 match List.nth context (n - 1) with
304 Some (_,C.Decl ty) ->
305 t,S.lift n ty,subst,metasenv, ugraph
306 | Some (_,C.Def (_,Some ty)) ->
307 t,S.lift n ty,subst,metasenv, ugraph
308 | Some (_,C.Def (bo,None)) ->
310 (* if it is in the context it must be already well-typed*)
311 CicTypeChecker.type_of_aux' ~subst metasenv context
314 t,ty,subst,metasenv,ugraph
315 | None -> raise (RefineFailure (lazy "Rel to hidden hypothesis"))
317 _ -> raise (RefineFailure (lazy "Not a close term")))
318 | C.Var (uri,exp_named_subst) ->
319 let exp_named_subst',subst',metasenv',ugraph1 =
320 check_exp_named_subst
321 subst metasenv context exp_named_subst ugraph
323 let ty_uri,ugraph1 = type_of_variable uri ugraph in
325 CicSubstitution.subst_vars exp_named_subst' ty_uri
327 C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
330 let (canonical_context, term,ty) =
331 CicUtil.lookup_subst n subst
333 let l',subst',metasenv',ugraph1 =
334 check_metasenv_consistency n subst metasenv context
335 canonical_context l ugraph
337 (* trust or check ??? *)
338 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
339 subst', metasenv', ugraph1
340 (* type_of_aux subst metasenv
341 context (CicSubstitution.subst_meta l term) *)
342 with CicUtil.Subst_not_found _ ->
343 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
344 let l',subst',metasenv', ugraph1 =
345 check_metasenv_consistency n subst metasenv context
346 canonical_context l ugraph
348 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
349 subst', metasenv',ugraph1)
350 | C.Sort (C.Type tno) ->
351 let tno' = CicUniv.fresh() in
352 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
353 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
355 t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
356 | C.Implicit _ -> raise (AssertFailure (lazy "21"))
358 let ty',_,subst',metasenv',ugraph1 =
359 type_of_aux subst metasenv context ty ugraph
361 let te',inferredty,subst'',metasenv'',ugraph2 =
362 type_of_aux subst' metasenv' context te ugraph1
365 let subst''',metasenv''',ugraph3 =
366 fo_unif_subst subst'' context metasenv''
367 inferredty ty ugraph2
369 C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
371 | _ -> raise (RefineFailure (lazy "Cast")))
372 | C.Prod (name,s,t) ->
373 let carr t subst context = CicMetaSubst.apply_subst subst t in
375 in_source tgt_sort t type_to_coerce subst ctx metasenv uragph
377 let coercion_src = carr type_to_coerce subst ctx in
378 match coercion_src with
380 t,type_to_coerce,subst,metasenv,ugraph
382 | Cic.Meta _ as meta when not in_source ->
383 let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
384 let subst, metasenv, ugraph =
386 subst ctx metasenv meta coercion_tgt ugraph
388 t, Cic.Sort tgt_sort, subst, metasenv, ugraph
390 | Cic.Meta _ as meta ->
391 t, meta, subst, metasenv, ugraph
392 | Cic.Cast _ as cast ->
393 t, cast, subst, metasenv, ugraph
395 let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
396 let search = CoercGraph.look_for_coercion in
397 let boh = search coercion_src coercion_tgt in
399 | CoercGraph.NoCoercion ->
400 raise (RefineFailure (lazy "no coercion"))
401 | CoercGraph.NotHandled _ ->
402 raise (RefineFailure (lazy "not a sort in PI"))
403 | CoercGraph.NotMetaClosed ->
404 raise (Uncertain (lazy "Coercions on metas 1"))
405 | CoercGraph.SomeCoercion c ->
406 Cic.Appl [c;t],Cic.Sort tgt_sort,subst, metasenv, ugraph)
408 let s',sort1,subst',metasenv',ugraph1 =
409 type_of_aux subst metasenv context s ugraph
411 let s',sort1,subst', metasenv',ugraph1 =
412 coerce_to_sort true (Cic.Type(CicUniv.fresh()))
413 s' sort1 subst' context metasenv' ugraph1
415 let context_for_t = ((Some (name,(C.Decl s')))::context) in
416 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
417 let t',sort2,subst'',metasenv'',ugraph2 =
418 type_of_aux subst' metasenv'
419 context_for_t t ugraph1
421 let t',sort2,subst'',metasenv'',ugraph2 =
422 coerce_to_sort false (Cic.Type(CicUniv.fresh()))
423 t' sort2 subst'' context_for_t metasenv'' ugraph2
425 let sop,subst''',metasenv''',ugraph3 =
426 sort_of_prod subst'' metasenv''
427 context (name,s') (sort1,sort2) ugraph2
429 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
430 | C.Lambda (n,s,t) ->
432 let s',sort1,subst',metasenv',ugraph1 =
433 type_of_aux subst metasenv context s ugraph
435 (match CicReduction.whd ~subst:subst' context sort1 with
439 raise (RefineFailure (lazy (sprintf
440 "Not well-typed lambda-abstraction: the source %s should be a type;
441 instead it is a term of type %s" (CicPp.ppterm s)
442 (CicPp.ppterm sort1))))
444 let context_for_t = ((Some (n,(C.Decl s')))::context) in
445 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
446 let t',type2,subst'',metasenv'',ugraph2 =
447 type_of_aux subst' metasenv'
448 context_for_t t ugraph1
450 C.Lambda (n,s',t'),C.Prod (n,s',type2),
451 subst'',metasenv'',ugraph2
453 (* only to check if s is well-typed *)
454 let s',ty,subst',metasenv',ugraph1 =
455 type_of_aux subst metasenv context s ugraph
457 let context_for_t = ((Some (n,(C.Def (s',Some ty))))::context) in
458 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
460 let t',inferredty,subst'',metasenv'',ugraph2 =
461 type_of_aux subst' metasenv'
462 context_for_t t ugraph1
464 (* One-step LetIn reduction.
465 * Even faster than the previous solution.
466 * Moreover the inferred type is closer to the expected one.
468 C.LetIn (n,s',t'),CicSubstitution.subst s' inferredty,
469 subst'',metasenv'',ugraph2
470 | C.Appl (he::((_::_) as tl)) ->
471 let he',hetype,subst',metasenv',ugraph1 =
472 type_of_aux subst metasenv context he ugraph
474 let tlbody_and_type,subst'',metasenv'',ugraph2 =
476 (fun x (res,subst,metasenv,ugraph) ->
477 let x',ty,subst',metasenv',ugraph1 =
478 type_of_aux subst metasenv context x ugraph
480 (x', ty)::res,subst',metasenv',ugraph1
481 ) tl ([],subst',metasenv',ugraph1)
483 let tl',applty,subst''',metasenv''',ugraph3 =
484 eat_prods subst'' metasenv'' context
485 hetype tlbody_and_type ugraph2
487 C.Appl (he'::tl'), applty,subst''',metasenv''',ugraph3
488 | C.Appl _ -> raise (RefineFailure (lazy "Appl: no arguments"))
489 | C.Const (uri,exp_named_subst) ->
490 let exp_named_subst',subst',metasenv',ugraph1 =
491 check_exp_named_subst subst metasenv context
492 exp_named_subst ugraph in
493 let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
495 CicSubstitution.subst_vars exp_named_subst' ty_uri
497 C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
498 | C.MutInd (uri,i,exp_named_subst) ->
499 let exp_named_subst',subst',metasenv',ugraph1 =
500 check_exp_named_subst subst metasenv context
501 exp_named_subst ugraph
503 let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
505 CicSubstitution.subst_vars exp_named_subst' ty_uri in
506 C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
507 | C.MutConstruct (uri,i,j,exp_named_subst) ->
508 let exp_named_subst',subst',metasenv',ugraph1 =
509 check_exp_named_subst subst metasenv context
510 exp_named_subst ugraph
513 type_of_mutual_inductive_constr uri i j ugraph1
516 CicSubstitution.subst_vars exp_named_subst' ty_uri
518 C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
520 | C.MutCase (uri, i, outtype, term, pl) ->
521 (* first, get the inductive type (and noparams)
522 * in the environment *)
523 let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
524 let _ = CicTypeChecker.typecheck uri in
525 let obj,u = CicEnvironment.get_cooked_obj ugraph uri in
527 C.InductiveDefinition (l,expl_params,parsno,_) ->
528 List.nth l i , expl_params, parsno, u
532 (lazy ("Unkown mutual inductive definition " ^
533 U.string_of_uri uri)))
535 let rec count_prod t =
536 match CicReduction.whd ~subst context t with
537 C.Prod (_, _, t) -> 1 + (count_prod t)
540 let no_args = count_prod arity in
541 (* now, create a "generic" MutInd *)
542 let metasenv,left_args =
543 CicMkImplicit.n_fresh_metas metasenv subst context no_left_params
545 let metasenv,right_args =
546 let no_right_params = no_args - no_left_params in
547 if no_right_params < 0 then assert false
548 else CicMkImplicit.n_fresh_metas
549 metasenv subst context no_right_params
551 let metasenv,exp_named_subst =
552 CicMkImplicit.fresh_subst metasenv subst context expl_params in
555 C.MutInd (uri,i,exp_named_subst)
558 (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
560 (* check consistency with the actual type of term *)
561 let term',actual_type,subst,metasenv,ugraph1 =
562 type_of_aux subst metasenv context term ugraph in
563 let expected_type',_, subst, metasenv,ugraph2 =
564 type_of_aux subst metasenv context expected_type ugraph1
566 let actual_type = CicReduction.whd ~subst context actual_type in
567 let subst,metasenv,ugraph3 =
568 fo_unif_subst subst context metasenv
569 expected_type' actual_type ugraph2
571 let rec instantiate_prod t =
575 match CicReduction.whd ~subst context t with
577 instantiate_prod (CicSubstitution.subst he t') tl
580 let arity_instantiated_with_left_args =
581 instantiate_prod arity left_args in
582 (* TODO: check if the sort elimination
583 * is allowed: [(I q1 ... qr)|B] *)
584 let (pl',_,outtypeinstances,subst,metasenv,ugraph4) =
586 (fun (pl,j,outtypeinstances,subst,metasenv,ugraph) p ->
588 if left_args = [] then
589 (C.MutConstruct (uri,i,j,exp_named_subst))
592 (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
594 let p',actual_type,subst,metasenv,ugraph1 =
595 type_of_aux subst metasenv context p ugraph
597 let constructor',expected_type, subst, metasenv,ugraph2 =
598 type_of_aux subst metasenv context constructor ugraph1
600 let outtypeinstance,subst,metasenv,ugraph3 =
601 check_branch 0 context metasenv subst no_left_params
602 actual_type constructor' expected_type ugraph2
605 outtypeinstance::outtypeinstances,subst,metasenv,ugraph3))
606 ([],1,[],subst,metasenv,ugraph3) pl
609 (* we are left to check that the outype matches his instances.
610 The easy case is when the outype is specified, that amount
611 to a trivial check. Otherwise, we should guess a type from
617 (let candidate,ugraph5,metasenv,subst =
618 let exp_name_subst, metasenv =
620 CicEnvironment.get_cooked_obj CicUniv.empty_ugraph uri
622 let uris = CicUtil.params_of_obj o in
624 fun uri (acc,metasenv) ->
625 let metasenv',new_meta =
626 CicMkImplicit.mk_implicit metasenv subst context
629 CicMkImplicit.identity_relocation_list_for_metavariable
632 (uri, Cic.Meta(new_meta,irl))::acc, metasenv'
636 match left_args,right_args with
637 [],[] -> Cic.MutInd(uri, i, exp_name_subst)
639 let rec mk_right_args =
642 | n -> (Cic.Rel n)::(mk_right_args (n - 1))
644 let right_args_no = List.length right_args in
645 let lifted_left_args =
646 List.map (CicSubstitution.lift right_args_no) left_args
648 Cic.Appl (Cic.MutInd(uri,i,exp_name_subst)::
649 (lifted_left_args @ mk_right_args right_args_no))
652 FreshNamesGenerator.mk_fresh_name ~subst metasenv
653 context Cic.Anonymous ~typ:ty
655 match outtypeinstances with
657 let extended_context =
658 let rec add_right_args =
660 Cic.Prod (name,ty,t) ->
661 Some (name,Cic.Decl ty)::(add_right_args t)
664 (Some (fresh_name,Cic.Decl ty))::
666 (add_right_args arity_instantiated_with_left_args))@
669 let metasenv,new_meta =
670 CicMkImplicit.mk_implicit metasenv subst extended_context
673 CicMkImplicit.identity_relocation_list_for_metavariable
676 let rec add_lambdas b =
678 Cic.Prod (name,ty,t) ->
679 Cic.Lambda (name,ty,(add_lambdas b t))
680 | _ -> Cic.Lambda (fresh_name, ty, b)
683 add_lambdas (Cic.Meta (new_meta,irl))
684 arity_instantiated_with_left_args
686 (Some candidate),ugraph4,metasenv,subst
687 | (constructor_args_no,_,instance,_)::tl ->
689 let instance',subst,metasenv =
690 CicMetaSubst.delift_rels subst metasenv
691 constructor_args_no instance
693 let candidate,ugraph,metasenv,subst =
695 fun (candidate_oty,ugraph,metasenv,subst)
696 (constructor_args_no,_,instance,_) ->
697 match candidate_oty with
698 | None -> None,ugraph,metasenv,subst
701 let instance',subst,metasenv =
702 CicMetaSubst.delift_rels subst metasenv
703 constructor_args_no instance
705 let subst,metasenv,ugraph =
706 fo_unif_subst subst context metasenv
709 candidate_oty,ugraph,metasenv,subst
711 CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable
712 | CicUnification.UnificationFailure _
713 | CicUnification.Uncertain _ ->
714 None,ugraph,metasenv,subst
715 ) (Some instance',ugraph4,metasenv,subst) tl
718 | None -> None, ugraph,metasenv,subst
720 let rec add_lambdas n b =
722 Cic.Prod (name,ty,t) ->
723 Cic.Lambda (name,ty,(add_lambdas (n + 1) b t))
725 Cic.Lambda (fresh_name, ty,
726 CicSubstitution.lift (n + 1) t)
729 (add_lambdas 0 t arity_instantiated_with_left_args),
730 ugraph,metasenv,subst
731 with CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
732 None,ugraph4,metasenv,subst
735 | None -> raise (Uncertain (lazy "can't solve an higher order unification problem"))
737 let subst,metasenv,ugraph =
738 fo_unif_subst subst context metasenv
739 candidate outtype ugraph5
741 C.MutCase (uri, i, outtype, term', pl'),
742 CicReduction.head_beta_reduce
743 (CicMetaSubst.apply_subst subst
744 (Cic.Appl (outtype::right_args@[term']))),
745 subst,metasenv,ugraph)
746 | _ -> (* easy case *)
747 let _,_, subst, metasenv,ugraph5 =
748 type_of_aux subst metasenv context
749 (C.Appl ((outtype :: right_args) @ [term'])) ugraph4
751 let (subst,metasenv,ugraph6) =
753 (fun (subst,metasenv,ugraph)
754 (constructor_args_no,context,instance,args) ->
758 CicSubstitution.lift constructor_args_no outtype
760 C.Appl (outtype'::args)
762 CicReduction.whd ~subst context appl
764 fo_unif_subst subst context metasenv
765 instance instance' ugraph)
766 (subst,metasenv,ugraph5) outtypeinstances
768 C.MutCase (uri, i, outtype, term', pl'),
769 CicReduction.head_beta_reduce
770 (CicMetaSubst.apply_subst subst
771 (C.Appl(outtype::right_args@[term]))),
772 subst,metasenv,ugraph6)
774 let fl_ty',subst,metasenv,types,ugraph1 =
776 (fun (fl,subst,metasenv,types,ugraph) (n,_,ty,_) ->
777 let ty',_,subst',metasenv',ugraph1 =
778 type_of_aux subst metasenv context ty ugraph
780 fl @ [ty'],subst',metasenv',
781 Some (C.Name n,(C.Decl ty')) :: types, ugraph
782 ) ([],subst,metasenv,[],ugraph) fl
784 let len = List.length types in
785 let context' = types@context in
786 let fl_bo',subst,metasenv,ugraph2 =
788 (fun (fl,subst,metasenv,ugraph) ((name,x,_,bo),ty) ->
789 let metasenv, bo = exp_impl metasenv subst context' bo in
790 let bo',ty_of_bo,subst,metasenv,ugraph1 =
791 type_of_aux subst metasenv context' bo ugraph
793 let subst',metasenv',ugraph' =
794 fo_unif_subst subst context' metasenv
795 ty_of_bo (CicSubstitution.lift len ty) ugraph1
797 fl @ [bo'] , subst',metasenv',ugraph'
798 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
800 let ty = List.nth fl_ty' i in
801 (* now we have the new ty in fl_ty', the new bo in fl_bo',
802 * and we want the new fl with bo' and ty' injected in the right
805 let rec map3 f l1 l2 l3 =
808 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
811 let fl'' = map3 (fun ty' bo' (name,x,ty,bo) -> (name,x,ty',bo') )
814 C.Fix (i,fl''),ty,subst,metasenv,ugraph2
816 let fl_ty',subst,metasenv,types,ugraph1 =
818 (fun (fl,subst,metasenv,types,ugraph) (n,ty,_) ->
819 let ty',_,subst',metasenv',ugraph1 =
820 type_of_aux subst metasenv context ty ugraph
822 fl @ [ty'],subst',metasenv',
823 Some (C.Name n,(C.Decl ty')) :: types, ugraph1
824 ) ([],subst,metasenv,[],ugraph) fl
826 let len = List.length types in
827 let context' = types@context in
828 let fl_bo',subst,metasenv,ugraph2 =
830 (fun (fl,subst,metasenv,ugraph) ((name,_,bo),ty) ->
831 let metasenv, bo = exp_impl metasenv subst context' bo in
832 let bo',ty_of_bo,subst,metasenv,ugraph1 =
833 type_of_aux subst metasenv context' bo ugraph
835 let subst',metasenv',ugraph' =
836 fo_unif_subst subst context' metasenv
837 ty_of_bo (CicSubstitution.lift len ty) ugraph1
839 fl @ [bo'],subst',metasenv',ugraph'
840 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
842 let ty = List.nth fl_ty' i in
843 (* now we have the new ty in fl_ty', the new bo in fl_bo',
844 * and we want the new fl with bo' and ty' injected in the right
847 let rec map3 f l1 l2 l3 =
850 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
853 let fl'' = map3 (fun ty' bo' (name,ty,bo) -> (name,ty',bo') )
856 C.CoFix (i,fl''),ty,subst,metasenv,ugraph2
858 (* check_metasenv_consistency checks that the "canonical" context of a
859 metavariable is consitent - up to relocation via the relocation list l -
860 with the actual context *)
861 and check_metasenv_consistency
862 metano subst metasenv context canonical_context l ugraph
864 let module C = Cic in
865 let module R = CicReduction in
866 let module S = CicSubstitution in
867 let lifted_canonical_context =
871 | (Some (n,C.Decl t))::tl ->
872 (Some (n,C.Decl (S.subst_meta l (S.lift i t))))::(aux (i+1) tl)
873 | (Some (n,C.Def (t,None)))::tl ->
874 (Some (n,C.Def ((S.subst_meta l (S.lift i t)),None)))::(aux (i+1) tl)
875 | None::tl -> None::(aux (i+1) tl)
876 | (Some (n,C.Def (t,Some ty)))::tl ->
878 C.Def ((S.subst_meta l (S.lift i t)),
879 Some (S.subst_meta l (S.lift i ty))))) :: (aux (i+1) tl)
881 aux 1 canonical_context
885 (fun (l,subst,metasenv,ugraph) t ct ->
888 l @ [None],subst,metasenv,ugraph
889 | Some t,Some (_,C.Def (ct,_)) ->
890 let subst',metasenv',ugraph' =
892 fo_unif_subst subst context metasenv t ct ugraph
893 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 subst t) (CicMetaSubst.ppterm subst ct) (match e with AssertFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
895 l @ [Some t],subst',metasenv',ugraph'
896 | Some t,Some (_,C.Decl ct) ->
897 let t',inferredty,subst',metasenv',ugraph1 =
898 type_of_aux subst metasenv context t ugraph
900 let subst'',metasenv'',ugraph2 =
903 subst' context metasenv' inferredty ct ugraph1
904 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 subst' inferredty) (CicMetaSubst.ppterm subst' t) (CicMetaSubst.ppterm subst' ct) (match e with AssertFailure msg -> Lazy.force msg | RefineFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
906 l @ [Some t'], subst'',metasenv'',ugraph2
908 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 subst (Cic.Meta (metano, l))) (CicMetaSubst.ppcontext subst canonical_context))))) ([],subst,metasenv,ugraph) l lifted_canonical_context
910 Invalid_argument _ ->
914 "Not well typed metavariable instance %s: the length of the local context does not match the length of the canonical context %s"
915 (CicMetaSubst.ppterm subst (Cic.Meta (metano, l)))
916 (CicMetaSubst.ppcontext subst canonical_context))))
918 and check_exp_named_subst metasubst metasenv context tl ugraph =
919 let rec check_exp_named_subst_aux metasubst metasenv substs tl ugraph =
921 [] -> [],metasubst,metasenv,ugraph
922 | ((uri,t) as subst)::tl ->
923 let ty_uri,ugraph1 = type_of_variable uri ugraph in
925 CicSubstitution.subst_vars substs ty_uri in
926 (* CSC: why was this code here? it is wrong
927 (match CicEnvironment.get_cooked_obj ~trust:false uri with
928 Cic.Variable (_,Some bo,_,_) ->
931 "A variable with a body can not be explicit substituted"))
932 | Cic.Variable (_,None,_,_) -> ()
936 ("Unkown variable definition " ^ UriManager.string_of_uri uri)))
939 let t',typeoft,metasubst',metasenv',ugraph2 =
940 type_of_aux metasubst metasenv context t ugraph1
942 let metasubst'',metasenv'',ugraph3 =
945 metasubst' context metasenv' typeoft typeofvar ugraph2
947 raise (RefineFailure (lazy
948 ("Wrong Explicit Named Substitution: " ^
949 CicMetaSubst.ppterm metasubst' typeoft ^
950 " not unifiable with " ^
951 CicMetaSubst.ppterm metasubst' typeofvar)))
953 (* FIXME: no mere tail recursive! *)
954 let exp_name_subst, metasubst''', metasenv''', ugraph4 =
955 check_exp_named_subst_aux
956 metasubst'' metasenv'' (substs@[subst]) tl ugraph3
958 ((uri,t')::exp_name_subst), metasubst''', metasenv''', ugraph4
960 check_exp_named_subst_aux metasubst metasenv [] tl ugraph
963 and sort_of_prod subst metasenv context (name,s) (t1, t2) ugraph =
964 let module C = Cic in
965 let context_for_t2 = (Some (name,C.Decl s))::context in
966 let t1'' = CicReduction.whd ~subst context t1 in
967 let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
968 match (t1'', t2'') with
969 (C.Sort s1, C.Sort s2)
970 when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) ->
971 (* different than Coq manual!!! *)
972 C.Sort s2,subst,metasenv,ugraph
973 | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
974 let t' = CicUniv.fresh() in
975 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
976 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
977 C.Sort (C.Type t'),subst,metasenv,ugraph2
978 | (C.Sort _,C.Sort (C.Type t1)) ->
979 C.Sort (C.Type t1),subst,metasenv,ugraph
980 | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
981 | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
982 (* TODO how can we force the meta to become a sort? If we don't we
983 * brake the invariant that refine produce only well typed terms *)
984 (* TODO if we check the non meta term and if it is a sort then we
985 * are likely to know the exact value of the result e.g. if the rhs
986 * is a Sort (Prop | Set | CProp) then the result is the rhs *)
988 CicMkImplicit.mk_implicit_sort metasenv subst in
989 let (subst, metasenv,ugraph1) =
990 fo_unif_subst subst context_for_t2 metasenv
991 (C.Meta (idx,[])) t2'' ugraph
993 t2'',subst,metasenv,ugraph1
999 ("Two sorts were expected, found %s " ^^
1000 "(that reduces to %s) and %s (that reduces to %s)")
1001 (CicPp.ppterm t1) (CicPp.ppterm t1'') (CicPp.ppterm t2)
1002 (CicPp.ppterm t2''))))
1004 and eat_prods subst metasenv context hetype tlbody_and_type ugraph =
1005 let rec mk_prod metasenv context =
1008 let (metasenv, idx) =
1009 CicMkImplicit.mk_implicit_type metasenv subst context
1012 CicMkImplicit.identity_relocation_list_for_metavariable context
1014 metasenv,Cic.Meta (idx, irl)
1016 let (metasenv, idx) =
1017 CicMkImplicit.mk_implicit_type metasenv subst context
1020 CicMkImplicit.identity_relocation_list_for_metavariable context
1022 let meta = Cic.Meta (idx,irl) in
1024 (* The name must be fresh for context. *)
1025 (* Nevertheless, argty is well-typed only in context. *)
1026 (* Thus I generate a name (name_hint) in context and *)
1027 (* then I generate a name --- using the hint name_hint *)
1028 (* --- that is fresh in (context'@context). *)
1030 (* Cic.Name "pippo" *)
1031 FreshNamesGenerator.mk_fresh_name ~subst metasenv
1032 (* (CicMetaSubst.apply_subst_metasenv subst metasenv) *)
1033 (CicMetaSubst.apply_subst_context subst context)
1035 ~typ:(CicMetaSubst.apply_subst subst argty)
1037 (* [] and (Cic.Sort Cic.prop) are dummy: they will not be used *)
1038 FreshNamesGenerator.mk_fresh_name ~subst
1039 [] context name_hint ~typ:(Cic.Sort Cic.Prop)
1041 let metasenv,target =
1042 mk_prod metasenv ((Some (name, Cic.Decl meta))::context) tl
1044 metasenv,Cic.Prod (name,meta,target)
1046 let metasenv,hetype' = mk_prod metasenv context tlbody_and_type in
1047 let (subst, metasenv,ugraph1) =
1049 fo_unif_subst subst context metasenv hetype hetype' ugraph
1051 debug_print (lazy (Printf.sprintf "hetype=%s\nhetype'=%s\nmetasenv=%s\nsubst=%s"
1052 (CicPp.ppterm hetype)
1053 (CicPp.ppterm hetype')
1054 (CicMetaSubst.ppmetasenv [] metasenv)
1055 (CicMetaSubst.ppsubst subst)));
1059 let rec eat_prods metasenv subst context hetype ugraph =
1061 | [] -> [],metasenv,subst,hetype,ugraph
1062 | (hete, hety)::tl ->
1065 let arg,subst,metasenv,ugraph1 =
1067 let subst,metasenv,ugraph1 =
1068 fo_unif_subst subst context metasenv hety s ugraph
1070 hete,subst,metasenv,ugraph1
1072 (* we search a coercion from hety to s *)
1074 let carr t subst context =
1075 CicMetaSubst.apply_subst subst t
1077 let c_hety = carr hety subst context in
1078 let c_s = carr s subst context in
1079 CoercGraph.look_for_coercion c_hety c_s
1082 | CoercGraph.NoCoercion
1083 | CoercGraph.NotHandled _ -> raise exn
1084 | CoercGraph.NotMetaClosed ->
1085 raise (Uncertain (lazy "Coercions on meta"))
1086 | CoercGraph.SomeCoercion c ->
1087 (Cic.Appl [ c ; hete ]), subst, metasenv, ugraph
1089 let coerced_args,metasenv',subst',t',ugraph2 =
1090 eat_prods metasenv subst context
1091 (* (CicMetaSubst.subst subst hete t) tl *)
1092 (CicSubstitution.subst hete t) ugraph1 tl
1094 arg::coerced_args,metasenv',subst',t',ugraph2
1098 let coerced_args,metasenv,subst,t,ugraph2 =
1099 eat_prods metasenv subst context hetype' ugraph1 tlbody_and_type
1101 coerced_args,t,subst,metasenv,ugraph2
1104 (* eat prods ends here! *)
1106 let t',ty,subst',metasenv',ugraph1 =
1107 type_of_aux [] metasenv context t ugraph
1109 let substituted_t = CicMetaSubst.apply_subst subst' t' in
1110 let substituted_ty = CicMetaSubst.apply_subst subst' ty in
1111 (* Andrea: ho rimesso qui l'applicazione della subst al
1112 metasenv dopo che ho droppato l'invariante che il metsaenv
1113 e' sempre istanziato *)
1114 let substituted_metasenv =
1115 CicMetaSubst.apply_subst_metasenv subst' metasenv' in
1117 (* substituted_t,substituted_ty,substituted_metasenv *)
1118 (* ANDREA: spostare tutta questa robaccia da un altra parte *)
1120 FreshNamesGenerator.clean_dummy_dependent_types substituted_t in
1122 FreshNamesGenerator.clean_dummy_dependent_types substituted_ty in
1123 let cleaned_metasenv =
1125 (function (n,context,ty) ->
1126 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty in
1131 | Some (n, Cic.Decl t) ->
1133 Cic.Decl (FreshNamesGenerator.clean_dummy_dependent_types t))
1134 | Some (n, Cic.Def (bo,ty)) ->
1135 let bo' = FreshNamesGenerator.clean_dummy_dependent_types bo in
1140 Some (FreshNamesGenerator.clean_dummy_dependent_types ty)
1142 Some (n, Cic.Def (bo',ty'))
1146 ) substituted_metasenv
1148 (cleaned_t,cleaned_ty,cleaned_metasenv,ugraph1)
1151 let type_of_aux' metasenv context term ugraph =
1153 type_of_aux' metasenv context term ugraph
1155 CicUniv.UniverseInconsistency msg -> raise (RefineFailure (lazy msg))
1157 let undebrujin uri typesno tys t =
1160 (fun (name,_,_,_) (i,t) ->
1161 (* here the explicit_named_substituion is assumed to be *)
1163 let t' = Cic.MutInd (uri,i,[]) in
1164 let t = CicSubstitution.subst t' t in
1166 ) tys (typesno - 1,t))
1168 let map_first_n n start f g l =
1169 let rec aux acc k l =
1172 | [] -> raise (Invalid_argument "map_first_n")
1173 | hd :: tl -> f hd k (aux acc (k+1) tl)
1179 (*CSC: this is a very rough approximation; to be finished *)
1180 let are_all_occurrences_positive metasenv ugraph uri tys leftno =
1181 let number_of_types = List.length tys in
1182 let subst,metasenv,ugraph,tys =
1184 (fun (name,ind,arity,cl) (subst,metasenv,ugraph,acc) ->
1185 let subst,metasenv,ugraph,cl =
1187 (fun (name,ty) (subst,metasenv,ugraph,acc) ->
1188 let rec aux ctx k subst = function
1189 | Cic.Appl((Cic.MutInd (uri',_,_)as hd)::tl) when uri = uri'->
1190 let subst,metasenv,ugraph,tl =
1192 (subst,metasenv,ugraph,[])
1193 (fun t n (subst,metasenv,ugraph,acc) ->
1194 let subst,metasenv,ugraph =
1196 subst ctx metasenv t (Cic.Rel (k-n)) ugraph
1198 subst,metasenv,ugraph,(t::acc))
1199 (fun (s,m,g,acc) tl -> assert(acc=[]);(s,m,g,tl))
1202 subst,metasenv,ugraph,(Cic.Appl (hd::tl))
1203 | Cic.MutInd(uri',_,_) as t when uri = uri'->
1204 subst,metasenv,ugraph,t
1205 | Cic.Prod (name,s,t) ->
1206 let ctx = (Some (name,Cic.Decl s))::ctx in
1207 let subst,metasenv,ugraph,t = aux ctx (k+1) subst t in
1208 subst,metasenv,ugraph,Cic.Prod (name,s,t)
1212 (lazy "not well formed constructor type"))
1214 let subst,metasenv,ugraph,ty = aux [] 0 subst ty in
1215 subst,metasenv,ugraph,(name,ty) :: acc)
1216 cl (subst,metasenv,ugraph,[])
1218 subst,metasenv,ugraph,(name,ind,arity,cl)::acc)
1219 tys ([],metasenv,ugraph,[])
1221 let substituted_tys =
1223 (fun (name,ind,arity,cl) ->
1225 List.map (fun (name, ty) -> name,CicMetaSubst.apply_subst subst ty) cl
1227 name,ind,CicMetaSubst.apply_subst subst arity,cl)
1230 metasenv,ugraph,substituted_tys
1232 let typecheck metasenv uri obj =
1233 let ugraph = CicUniv.empty_ugraph in
1235 Cic.Constant (name,Some bo,ty,args,attrs) ->
1236 let bo',boty,metasenv,ugraph = type_of_aux' metasenv [] bo ugraph in
1237 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1238 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1239 let bo' = CicMetaSubst.apply_subst subst bo' in
1240 let ty' = CicMetaSubst.apply_subst subst ty' in
1241 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1242 Cic.Constant (name,Some bo',ty',args,attrs),metasenv,ugraph
1243 | Cic.Constant (name,None,ty,args,attrs) ->
1244 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1245 Cic.Constant (name,None,ty',args,attrs),metasenv,ugraph
1246 | Cic.CurrentProof (name,metasenv',bo,ty,args,attrs) ->
1247 assert (metasenv' = metasenv);
1248 (* Here we do not check the metasenv for correctness *)
1249 let bo',boty,metasenv,ugraph = type_of_aux' metasenv [] bo ugraph in
1250 let ty',sort,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1254 (* instead of raising Uncertain, let's hope that the meta will become
1257 | _ -> raise (RefineFailure (lazy "The term provided is not a type"))
1259 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1260 let bo' = CicMetaSubst.apply_subst subst bo' in
1261 let ty' = CicMetaSubst.apply_subst subst ty' in
1262 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1263 Cic.CurrentProof (name,metasenv,bo',ty',args,attrs),metasenv,ugraph
1264 | Cic.Variable _ -> assert false (* not implemented *)
1265 | Cic.InductiveDefinition (tys,args,paramsno,attrs) ->
1266 (*CSC: this code is greately simplified and many many checks are missing *)
1267 (*CSC: e.g. the constructors are not required to build their own types, *)
1268 (*CSC: the arities are not required to have as type a sort, etc. *)
1269 let uri = match uri with Some uri -> uri | None -> assert false in
1270 let typesno = List.length tys in
1271 (* first phase: we fix only the types *)
1272 let metasenv,ugraph,tys =
1274 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
1275 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1276 metasenv,ugraph,(name,b,ty',cl)::res
1277 ) tys (metasenv,ugraph,[]) in
1279 List.rev_map (fun (name,_,ty,_)-> Some (Cic.Name name,Cic.Decl ty)) tys in
1280 (* second phase: we fix only the constructors *)
1281 let metasenv,ugraph,tys =
1283 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
1284 let metasenv,ugraph,cl' =
1286 (fun (name,ty) (metasenv,ugraph,res) ->
1287 let ty = CicTypeChecker.debrujin_constructor uri typesno ty in
1288 let ty',_,metasenv,ugraph =
1289 type_of_aux' metasenv con_context ty ugraph in
1290 let ty' = undebrujin uri typesno tys ty' in
1291 metasenv,ugraph,(name,ty')::res
1292 ) cl (metasenv,ugraph,[])
1294 metasenv,ugraph,(name,b,ty,cl')::res
1295 ) tys (metasenv,ugraph,[]) in
1296 (* third phase: we check the positivity condition *)
1297 let metasenv,ugraph,tys =
1298 are_all_occurrences_positive metasenv ugraph uri tys paramsno
1300 Cic.InductiveDefinition (tys,args,paramsno,attrs),metasenv,ugraph
1303 let type_of_aux' metasenv context term =
1306 type_of_aux' metasenv context term in
1308 ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty));
1310 ("@@@ REFINE SUCCESSFUL (metasenv):\n" ^ CicMetaSubst.ppmetasenv ~sep:";" m []));
1313 | RefineFailure msg as e ->
1314 debug_print (lazy ("@@@ REFINE FAILED: " ^ msg));
1316 | Uncertain msg as e ->
1317 debug_print (lazy ("@@@ REFINE UNCERTAIN: " ^ msg));
1321 let profiler2 = HExtlib.profile "CicRefine"
1323 let type_of_aux' metasenv context term ugraph =
1324 profiler2.HExtlib.profile (type_of_aux' metasenv context term) ugraph
1326 let typecheck metasenv uri obj =
1327 profiler2.HExtlib.profile (typecheck metasenv uri) obj