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 and do_subst metasenv context subst =
157 (fun (uri, term) (metasenv, substs) ->
158 let metasenv', term' = aux metasenv context term in
159 (metasenv', (uri, term') :: substs))
161 and do_local_context metasenv context local_context =
163 (fun term (metasenv, local_context) ->
164 let metasenv', term' =
166 | None -> metasenv, None
168 let metasenv', term' = aux metasenv context term in
169 metasenv', Some term'
171 metasenv', term' :: local_context)
172 local_context (metasenv, [])
174 aux metasenv context term
177 let rec type_of_constant uri ugraph =
178 let module C = Cic in
179 let module R = CicReduction in
180 let module U = UriManager in
181 let _ = CicTypeChecker.typecheck uri in
184 CicEnvironment.get_cooked_obj ugraph uri
185 with Not_found -> assert false
188 C.Constant (_,_,ty,_,_) -> ty,u
189 | C.CurrentProof (_,_,_,ty,_,_) -> ty,u
192 (RefineFailure (lazy ("Unknown constant definition " ^ U.string_of_uri uri)))
194 and type_of_variable uri ugraph =
195 let module C = Cic in
196 let module R = CicReduction in
197 let module U = UriManager in
198 let _ = CicTypeChecker.typecheck uri in
201 CicEnvironment.get_cooked_obj ugraph uri
202 with Not_found -> assert false
205 C.Variable (_,_,ty,_,_) -> ty,u
209 (lazy ("Unknown variable definition " ^ UriManager.string_of_uri uri)))
211 and type_of_mutual_inductive_defs uri i ugraph =
212 let module C = Cic in
213 let module R = CicReduction in
214 let module U = UriManager in
215 let _ = CicTypeChecker.typecheck uri in
218 CicEnvironment.get_cooked_obj ugraph uri
219 with Not_found -> assert false
222 C.InductiveDefinition (dl,_,_,_) ->
223 let (_,_,arity,_) = List.nth dl i in
228 (lazy ("Unknown mutual inductive definition " ^ U.string_of_uri uri)))
230 and type_of_mutual_inductive_constr uri i j ugraph =
231 let module C = Cic in
232 let module R = CicReduction in
233 let module U = UriManager in
234 let _ = CicTypeChecker.typecheck uri in
237 CicEnvironment.get_cooked_obj ugraph uri
238 with Not_found -> assert false
241 C.InductiveDefinition (dl,_,_,_) ->
242 let (_,_,_,cl) = List.nth dl i in
243 let (_,ty) = List.nth cl (j-1) in
249 ("Unkown mutual inductive definition " ^ U.string_of_uri uri)))
252 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
254 (* the check_branch function checks if a branch of a case is refinable.
255 It returns a pair (outype_instance,args), a subst and a metasenv.
256 outype_instance is the expected result of applying the case outtype
258 The problem is that outype is in general unknown, and we should
259 try to synthesize it from the above information, that is in general
260 a second order unification problem. *)
262 and check_branch n context metasenv subst left_args_no actualtype term expectedtype ugraph =
263 let module C = Cic in
264 (* let module R = CicMetaSubst in *)
265 let module R = CicReduction in
266 match R.whd ~subst context expectedtype with
268 (n,context,actualtype, [term]), subst, metasenv, ugraph
269 | C.Appl (C.MutInd (_,_,_)::tl) ->
270 let (_,arguments) = split tl left_args_no in
271 (n,context,actualtype, arguments@[term]), subst, metasenv, ugraph
272 | C.Prod (name,so,de) ->
273 (* we expect that the actual type of the branch has the due
275 (match R.whd ~subst context actualtype with
276 C.Prod (name',so',de') ->
277 let subst, metasenv, ugraph1 =
278 fo_unif_subst subst context metasenv so so' ugraph in
280 (match CicSubstitution.lift 1 term with
281 C.Appl l -> C.Appl (l@[C.Rel 1])
282 | t -> C.Appl [t ; C.Rel 1]) in
283 (* we should also check that the name variable is anonymous in
284 the actual type de' ?? *)
286 ((Some (name,(C.Decl so)))::context)
287 metasenv subst left_args_no de' term' de ugraph1
288 | _ -> raise (AssertFailure (lazy "Wrong number of arguments")))
289 | _ -> raise (AssertFailure (lazy "Prod or MutInd expected"))
291 and type_of_aux' metasenv context t ugraph =
292 let metasenv, t = exp_impl metasenv [] context t in
293 let rec type_of_aux subst metasenv context t ugraph =
294 let module C = Cic in
295 let module S = CicSubstitution in
296 let module U = UriManager in
297 (* this stops on binders, so we have to call it every time *)
302 match List.nth context (n - 1) with
303 Some (_,C.Decl ty) ->
304 t,S.lift n ty,subst,metasenv, ugraph
305 | Some (_,C.Def (_,Some ty)) ->
306 t,S.lift n ty,subst,metasenv, ugraph
307 | Some (_,C.Def (bo,None)) ->
309 (* if it is in the context it must be already well-typed*)
310 CicTypeChecker.type_of_aux' ~subst metasenv context
313 t,ty,subst,metasenv,ugraph
314 | None -> raise (RefineFailure (lazy "Rel to hidden hypothesis"))
316 _ -> raise (RefineFailure (lazy "Not a close term")))
317 | C.Var (uri,exp_named_subst) ->
318 let exp_named_subst',subst',metasenv',ugraph1 =
319 check_exp_named_subst
320 subst metasenv context exp_named_subst ugraph
322 let ty_uri,ugraph1 = type_of_variable uri ugraph in
324 CicSubstitution.subst_vars exp_named_subst' ty_uri
326 C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
329 let (canonical_context, term,ty) =
330 CicUtil.lookup_subst n subst
332 let l',subst',metasenv',ugraph1 =
333 check_metasenv_consistency n subst metasenv context
334 canonical_context l ugraph
336 (* trust or check ??? *)
337 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
338 subst', metasenv', ugraph1
339 (* type_of_aux subst metasenv
340 context (CicSubstitution.subst_meta l term) *)
341 with CicUtil.Subst_not_found _ ->
342 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
343 let l',subst',metasenv', ugraph1 =
344 check_metasenv_consistency n subst metasenv context
345 canonical_context l ugraph
347 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
348 subst', metasenv',ugraph1)
349 | C.Sort (C.Type tno) ->
350 let tno' = CicUniv.fresh() in
351 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
352 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
354 t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
355 | C.Implicit _ -> raise (AssertFailure (lazy "21"))
357 let ty',_,subst',metasenv',ugraph1 =
358 type_of_aux subst metasenv context ty ugraph
360 let te',inferredty,subst'',metasenv'',ugraph2 =
361 type_of_aux subst' metasenv' context te ugraph1
364 let subst''',metasenv''',ugraph3 =
365 fo_unif_subst subst'' context metasenv''
366 inferredty ty ugraph2
368 C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
370 | _ -> raise (RefineFailure (lazy "Cast")))
371 | C.Prod (name,s,t) ->
372 let carr t subst context = CicMetaSubst.apply_subst subst t in
374 in_source tgt_sort t type_to_coerce subst ctx metasenv uragph
376 let coercion_src = carr type_to_coerce subst ctx in
377 match coercion_src with
379 t,type_to_coerce,subst,metasenv,ugraph
381 | Cic.Meta _ as meta when not in_source ->
382 let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
383 let subst, metasenv, ugraph =
385 subst ctx metasenv meta coercion_tgt ugraph
387 t, Cic.Sort tgt_sort, subst, metasenv, ugraph
389 | Cic.Meta _ as meta ->
390 t, meta, subst, metasenv, ugraph
391 | Cic.Cast _ as cast ->
392 t, cast, subst, metasenv, ugraph
394 let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
395 let search = CoercGraph.look_for_coercion in
396 let boh = search coercion_src coercion_tgt in
398 | CoercGraph.NoCoercion ->
399 raise (RefineFailure (lazy "no coercion"))
400 | CoercGraph.NotHandled _ ->
401 raise (RefineFailure (lazy "not a sort in PI"))
402 | CoercGraph.NotMetaClosed ->
403 raise (Uncertain (lazy "Coercions on metas 1"))
404 | CoercGraph.SomeCoercion c ->
405 Cic.Appl [c;t],Cic.Sort tgt_sort,subst, metasenv, ugraph)
407 let s',sort1,subst',metasenv',ugraph1 =
408 type_of_aux subst metasenv context s ugraph
410 let s',sort1,subst', metasenv',ugraph1 =
411 coerce_to_sort true (Cic.Type(CicUniv.fresh()))
412 s' sort1 subst' context metasenv' ugraph1
414 let context_for_t = ((Some (name,(C.Decl s')))::context) in
415 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
416 let t',sort2,subst'',metasenv'',ugraph2 =
417 type_of_aux subst' metasenv'
418 context_for_t t ugraph1
420 let t',sort2,subst'',metasenv'',ugraph2 =
421 coerce_to_sort false (Cic.Type(CicUniv.fresh()))
422 t' sort2 subst'' context_for_t metasenv'' ugraph2
424 let sop,subst''',metasenv''',ugraph3 =
425 sort_of_prod subst'' metasenv''
426 context (name,s') (sort1,sort2) ugraph2
428 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
429 | C.Lambda (n,s,t) ->
431 let s',sort1,subst',metasenv',ugraph1 =
432 type_of_aux subst metasenv context s ugraph
434 (match CicReduction.whd ~subst:subst' context sort1 with
438 raise (RefineFailure (lazy (sprintf
439 "Not well-typed lambda-abstraction: the source %s should be a type;
440 instead it is a term of type %s" (CicPp.ppterm s)
441 (CicPp.ppterm sort1))))
443 let context_for_t = ((Some (n,(C.Decl s')))::context) in
444 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
445 let t',type2,subst'',metasenv'',ugraph2 =
446 type_of_aux subst' metasenv'
447 context_for_t t ugraph1
449 C.Lambda (n,s',t'),C.Prod (n,s',type2),
450 subst'',metasenv'',ugraph2
452 (* only to check if s is well-typed *)
453 let s',ty,subst',metasenv',ugraph1 =
454 type_of_aux subst metasenv context s ugraph
456 let context_for_t = ((Some (n,(C.Def (s',Some ty))))::context) in
457 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
459 let t',inferredty,subst'',metasenv'',ugraph2 =
460 type_of_aux subst' metasenv'
461 context_for_t t ugraph1
463 (* One-step LetIn reduction.
464 * Even faster than the previous solution.
465 * Moreover the inferred type is closer to the expected one.
467 C.LetIn (n,s',t'),CicSubstitution.subst s' inferredty,
468 subst'',metasenv'',ugraph2
469 | C.Appl (he::((_::_) as tl)) ->
470 let he',hetype,subst',metasenv',ugraph1 =
471 type_of_aux subst metasenv context he ugraph
473 let tlbody_and_type,subst'',metasenv'',ugraph2 =
475 (fun x (res,subst,metasenv,ugraph) ->
476 let x',ty,subst',metasenv',ugraph1 =
477 type_of_aux subst metasenv context x ugraph
479 (x', ty)::res,subst',metasenv',ugraph1
480 ) tl ([],subst',metasenv',ugraph1)
482 let tl',applty,subst''',metasenv''',ugraph3 =
483 eat_prods true subst'' metasenv'' context
484 hetype tlbody_and_type ugraph2
486 C.Appl (he'::tl'), applty,subst''',metasenv''',ugraph3
487 | C.Appl _ -> raise (RefineFailure (lazy "Appl: no arguments"))
488 | C.Const (uri,exp_named_subst) ->
489 let exp_named_subst',subst',metasenv',ugraph1 =
490 check_exp_named_subst subst metasenv context
491 exp_named_subst ugraph in
492 let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
494 CicSubstitution.subst_vars exp_named_subst' ty_uri
496 C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
497 | C.MutInd (uri,i,exp_named_subst) ->
498 let exp_named_subst',subst',metasenv',ugraph1 =
499 check_exp_named_subst subst metasenv context
500 exp_named_subst ugraph
502 let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
504 CicSubstitution.subst_vars exp_named_subst' ty_uri in
505 C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
506 | C.MutConstruct (uri,i,j,exp_named_subst) ->
507 let exp_named_subst',subst',metasenv',ugraph1 =
508 check_exp_named_subst subst metasenv context
509 exp_named_subst ugraph
512 type_of_mutual_inductive_constr uri i j ugraph1
515 CicSubstitution.subst_vars exp_named_subst' ty_uri
517 C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
519 | C.MutCase (uri, i, outtype, term, pl) ->
520 (* first, get the inductive type (and noparams)
521 * in the environment *)
522 let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
523 let _ = CicTypeChecker.typecheck uri in
524 let obj,u = CicEnvironment.get_cooked_obj ugraph uri in
526 C.InductiveDefinition (l,expl_params,parsno,_) ->
527 List.nth l i , expl_params, parsno, u
531 (lazy ("Unkown mutual inductive definition " ^
532 U.string_of_uri uri)))
534 let rec count_prod t =
535 match CicReduction.whd ~subst context t with
536 C.Prod (_, _, t) -> 1 + (count_prod t)
539 let no_args = count_prod arity in
540 (* now, create a "generic" MutInd *)
541 let metasenv,left_args =
542 CicMkImplicit.n_fresh_metas metasenv subst context no_left_params
544 let metasenv,right_args =
545 let no_right_params = no_args - no_left_params in
546 if no_right_params < 0 then assert false
547 else CicMkImplicit.n_fresh_metas
548 metasenv subst context no_right_params
550 let metasenv,exp_named_subst =
551 CicMkImplicit.fresh_subst metasenv subst context expl_params in
554 C.MutInd (uri,i,exp_named_subst)
557 (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
559 (* check consistency with the actual type of term *)
560 let term',actual_type,subst,metasenv,ugraph1 =
561 type_of_aux subst metasenv context term ugraph in
562 let expected_type',_, subst, metasenv,ugraph2 =
563 type_of_aux subst metasenv context expected_type ugraph1
565 let actual_type = CicReduction.whd ~subst context actual_type in
566 let subst,metasenv,ugraph3 =
567 fo_unif_subst subst context metasenv
568 expected_type' actual_type ugraph2
570 let rec instantiate_prod t =
574 match CicReduction.whd ~subst context t with
576 instantiate_prod (CicSubstitution.subst he t') tl
579 let arity_instantiated_with_left_args =
580 instantiate_prod arity left_args in
581 (* TODO: check if the sort elimination
582 * is allowed: [(I q1 ... qr)|B] *)
583 let (pl',_,outtypeinstances,subst,metasenv,ugraph4) =
585 (fun (pl,j,outtypeinstances,subst,metasenv,ugraph) p ->
587 if left_args = [] then
588 (C.MutConstruct (uri,i,j,exp_named_subst))
591 (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
593 let p',actual_type,subst,metasenv,ugraph1 =
594 type_of_aux subst metasenv context p ugraph
596 let constructor',expected_type, subst, metasenv,ugraph2 =
597 type_of_aux subst metasenv context constructor ugraph1
599 let outtypeinstance,subst,metasenv,ugraph3 =
600 check_branch 0 context metasenv subst no_left_params
601 actual_type constructor' expected_type ugraph2
604 outtypeinstance::outtypeinstances,subst,metasenv,ugraph3))
605 ([],1,[],subst,metasenv,ugraph3) pl
608 (* we are left to check that the outype matches his instances.
609 The easy case is when the outype is specified, that amount
610 to a trivial check. Otherwise, we should guess a type from
616 (let candidate,ugraph5,metasenv,subst =
617 let exp_name_subst, metasenv =
619 CicEnvironment.get_cooked_obj CicUniv.empty_ugraph uri
621 let uris = CicUtil.params_of_obj o in
623 fun uri (acc,metasenv) ->
624 let metasenv',new_meta =
625 CicMkImplicit.mk_implicit metasenv subst context
628 CicMkImplicit.identity_relocation_list_for_metavariable
631 (uri, Cic.Meta(new_meta,irl))::acc, metasenv'
635 match left_args,right_args with
636 [],[] -> Cic.MutInd(uri, i, exp_name_subst)
638 let rec mk_right_args =
641 | n -> (Cic.Rel n)::(mk_right_args (n - 1))
643 let right_args_no = List.length right_args in
644 let lifted_left_args =
645 List.map (CicSubstitution.lift right_args_no) left_args
647 Cic.Appl (Cic.MutInd(uri,i,exp_name_subst)::
648 (lifted_left_args @ mk_right_args right_args_no))
651 FreshNamesGenerator.mk_fresh_name ~subst metasenv
652 context Cic.Anonymous ~typ:ty
654 match outtypeinstances with
656 let extended_context =
657 let rec add_right_args =
659 Cic.Prod (name,ty,t) ->
660 Some (name,Cic.Decl ty)::(add_right_args t)
663 (Some (fresh_name,Cic.Decl ty))::
665 (add_right_args arity_instantiated_with_left_args))@
668 let metasenv,new_meta =
669 CicMkImplicit.mk_implicit metasenv subst extended_context
672 CicMkImplicit.identity_relocation_list_for_metavariable
675 let rec add_lambdas b =
677 Cic.Prod (name,ty,t) ->
678 Cic.Lambda (name,ty,(add_lambdas b t))
679 | _ -> Cic.Lambda (fresh_name, ty, b)
682 add_lambdas (Cic.Meta (new_meta,irl))
683 arity_instantiated_with_left_args
685 (Some candidate),ugraph4,metasenv,subst
686 | (constructor_args_no,_,instance,_)::tl ->
688 let instance',subst,metasenv =
689 CicMetaSubst.delift_rels subst metasenv
690 constructor_args_no instance
692 let candidate,ugraph,metasenv,subst =
694 fun (candidate_oty,ugraph,metasenv,subst)
695 (constructor_args_no,_,instance,_) ->
696 match candidate_oty with
697 | None -> None,ugraph,metasenv,subst
700 let instance',subst,metasenv =
701 CicMetaSubst.delift_rels subst metasenv
702 constructor_args_no instance
704 let subst,metasenv,ugraph =
705 fo_unif_subst subst context metasenv
708 candidate_oty,ugraph,metasenv,subst
710 CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable
711 | CicUnification.UnificationFailure _
712 | CicUnification.Uncertain _ ->
713 None,ugraph,metasenv,subst
714 ) (Some instance',ugraph4,metasenv,subst) tl
717 | None -> None, ugraph,metasenv,subst
719 let rec add_lambdas n b =
721 Cic.Prod (name,ty,t) ->
722 Cic.Lambda (name,ty,(add_lambdas (n + 1) b t))
724 Cic.Lambda (fresh_name, ty,
725 CicSubstitution.lift (n + 1) t)
728 (add_lambdas 0 t arity_instantiated_with_left_args),
729 ugraph,metasenv,subst
730 with CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
731 None,ugraph4,metasenv,subst
734 | None -> raise (Uncertain (lazy "can't solve an higher order unification problem"))
736 let subst,metasenv,ugraph =
737 fo_unif_subst subst context metasenv
738 candidate outtype ugraph5
740 C.MutCase (uri, i, outtype, term', pl'),
741 CicReduction.head_beta_reduce
742 (CicMetaSubst.apply_subst subst
743 (Cic.Appl (outtype::right_args@[term']))),
744 subst,metasenv,ugraph)
745 | _ -> (* easy case *)
746 let outtype,outtypety, subst, metasenv,ugraph4 =
747 type_of_aux subst metasenv context outtype ugraph4
749 let tlbody_and_type,subst,metasenv,ugraph4 =
751 (fun x (res,subst,metasenv,ugraph) ->
752 let x',ty,subst',metasenv',ugraph1 =
753 type_of_aux subst metasenv context x ugraph
755 (x', ty)::res,subst',metasenv',ugraph1
756 ) (right_args @ [term']) ([],subst,metasenv,ugraph4)
758 let _,_,subst,metasenv,ugraph4 =
759 eat_prods false subst metasenv context
760 outtypety tlbody_and_type ugraph4
762 let _,_, subst, metasenv,ugraph5 =
763 type_of_aux subst metasenv context
764 (C.Appl ((outtype :: right_args) @ [term'])) ugraph4
766 let (subst,metasenv,ugraph6) =
768 (fun (subst,metasenv,ugraph)
769 (constructor_args_no,context,instance,args) ->
773 CicSubstitution.lift constructor_args_no outtype
775 C.Appl (outtype'::args)
777 CicReduction.whd ~subst context appl
779 fo_unif_subst subst context metasenv
780 instance instance' ugraph)
781 (subst,metasenv,ugraph5) outtypeinstances
783 C.MutCase (uri, i, outtype, term', pl'),
784 CicReduction.head_beta_reduce
785 (CicMetaSubst.apply_subst subst
786 (C.Appl(outtype::right_args@[term]))),
787 subst,metasenv,ugraph6)
789 let fl_ty',subst,metasenv,types,ugraph1 =
791 (fun (fl,subst,metasenv,types,ugraph) (n,_,ty,_) ->
792 let ty',_,subst',metasenv',ugraph1 =
793 type_of_aux subst metasenv context ty ugraph
795 fl @ [ty'],subst',metasenv',
796 Some (C.Name n,(C.Decl ty')) :: types, ugraph
797 ) ([],subst,metasenv,[],ugraph) fl
799 let len = List.length types in
800 let context' = types@context in
801 let fl_bo',subst,metasenv,ugraph2 =
803 (fun (fl,subst,metasenv,ugraph) ((name,x,_,bo),ty) ->
804 let metasenv, bo = exp_impl metasenv subst context' bo in
805 let bo',ty_of_bo,subst,metasenv,ugraph1 =
806 type_of_aux subst metasenv context' bo ugraph
808 let subst',metasenv',ugraph' =
809 fo_unif_subst subst context' metasenv
810 ty_of_bo (CicSubstitution.lift len ty) ugraph1
812 fl @ [bo'] , subst',metasenv',ugraph'
813 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
815 let ty = List.nth fl_ty' i in
816 (* now we have the new ty in fl_ty', the new bo in fl_bo',
817 * and we want the new fl with bo' and ty' injected in the right
820 let rec map3 f l1 l2 l3 =
823 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
826 let fl'' = map3 (fun ty' bo' (name,x,ty,bo) -> (name,x,ty',bo') )
829 C.Fix (i,fl''),ty,subst,metasenv,ugraph2
831 let fl_ty',subst,metasenv,types,ugraph1 =
833 (fun (fl,subst,metasenv,types,ugraph) (n,ty,_) ->
834 let ty',_,subst',metasenv',ugraph1 =
835 type_of_aux subst metasenv context ty ugraph
837 fl @ [ty'],subst',metasenv',
838 Some (C.Name n,(C.Decl ty')) :: types, ugraph1
839 ) ([],subst,metasenv,[],ugraph) fl
841 let len = List.length types in
842 let context' = types@context in
843 let fl_bo',subst,metasenv,ugraph2 =
845 (fun (fl,subst,metasenv,ugraph) ((name,_,bo),ty) ->
846 let metasenv, bo = exp_impl metasenv subst context' bo in
847 let bo',ty_of_bo,subst,metasenv,ugraph1 =
848 type_of_aux subst metasenv context' bo ugraph
850 let subst',metasenv',ugraph' =
851 fo_unif_subst subst context' metasenv
852 ty_of_bo (CicSubstitution.lift len ty) ugraph1
854 fl @ [bo'],subst',metasenv',ugraph'
855 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
857 let ty = List.nth fl_ty' i in
858 (* now we have the new ty in fl_ty', the new bo in fl_bo',
859 * and we want the new fl with bo' and ty' injected in the right
862 let rec map3 f l1 l2 l3 =
865 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
868 let fl'' = map3 (fun ty' bo' (name,ty,bo) -> (name,ty',bo') )
871 C.CoFix (i,fl''),ty,subst,metasenv,ugraph2
873 (* check_metasenv_consistency checks that the "canonical" context of a
874 metavariable is consitent - up to relocation via the relocation list l -
875 with the actual context *)
876 and check_metasenv_consistency
877 metano subst metasenv context canonical_context l ugraph
879 let module C = Cic in
880 let module R = CicReduction in
881 let module S = CicSubstitution in
882 let lifted_canonical_context =
886 | (Some (n,C.Decl t))::tl ->
887 (Some (n,C.Decl (S.subst_meta l (S.lift i t))))::(aux (i+1) tl)
888 | (Some (n,C.Def (t,None)))::tl ->
889 (Some (n,C.Def ((S.subst_meta l (S.lift i t)),None)))::(aux (i+1) tl)
890 | None::tl -> None::(aux (i+1) tl)
891 | (Some (n,C.Def (t,Some ty)))::tl ->
893 C.Def ((S.subst_meta l (S.lift i t)),
894 Some (S.subst_meta l (S.lift i ty))))) :: (aux (i+1) tl)
896 aux 1 canonical_context
900 (fun (l,subst,metasenv,ugraph) t ct ->
903 l @ [None],subst,metasenv,ugraph
904 | Some t,Some (_,C.Def (ct,_)) ->
905 let subst',metasenv',ugraph' =
907 fo_unif_subst subst context metasenv t ct ugraph
908 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))))))
910 l @ [Some t],subst',metasenv',ugraph'
911 | Some t,Some (_,C.Decl ct) ->
912 let t',inferredty,subst',metasenv',ugraph1 =
913 type_of_aux subst metasenv context t ugraph
915 let subst'',metasenv'',ugraph2 =
918 subst' context metasenv' inferredty ct ugraph1
919 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))))))
921 l @ [Some t'], subst'',metasenv'',ugraph2
923 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
925 Invalid_argument _ ->
929 "Not well typed metavariable instance %s: the length of the local context does not match the length of the canonical context %s"
930 (CicMetaSubst.ppterm subst (Cic.Meta (metano, l)))
931 (CicMetaSubst.ppcontext subst canonical_context))))
933 and check_exp_named_subst metasubst metasenv context tl ugraph =
934 let rec check_exp_named_subst_aux metasubst metasenv substs tl ugraph =
936 [] -> [],metasubst,metasenv,ugraph
937 | ((uri,t) as subst)::tl ->
938 let ty_uri,ugraph1 = type_of_variable uri ugraph in
940 CicSubstitution.subst_vars substs ty_uri in
941 (* CSC: why was this code here? it is wrong
942 (match CicEnvironment.get_cooked_obj ~trust:false uri with
943 Cic.Variable (_,Some bo,_,_) ->
946 "A variable with a body can not be explicit substituted"))
947 | Cic.Variable (_,None,_,_) -> ()
951 ("Unkown variable definition " ^ UriManager.string_of_uri uri)))
954 let t',typeoft,metasubst',metasenv',ugraph2 =
955 type_of_aux metasubst metasenv context t ugraph1
957 let metasubst'',metasenv'',ugraph3 =
960 metasubst' context metasenv' typeoft typeofvar ugraph2
962 raise (RefineFailure (lazy
963 ("Wrong Explicit Named Substitution: " ^
964 CicMetaSubst.ppterm metasubst' typeoft ^
965 " not unifiable with " ^
966 CicMetaSubst.ppterm metasubst' typeofvar)))
968 (* FIXME: no mere tail recursive! *)
969 let exp_name_subst, metasubst''', metasenv''', ugraph4 =
970 check_exp_named_subst_aux
971 metasubst'' metasenv'' (substs@[subst]) tl ugraph3
973 ((uri,t')::exp_name_subst), metasubst''', metasenv''', ugraph4
975 check_exp_named_subst_aux metasubst metasenv [] tl ugraph
978 and sort_of_prod subst metasenv context (name,s) (t1, t2) ugraph =
979 let module C = Cic in
980 let context_for_t2 = (Some (name,C.Decl s))::context in
981 let t1'' = CicReduction.whd ~subst context t1 in
982 let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
983 match (t1'', t2'') with
984 (C.Sort s1, C.Sort s2)
985 when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) ->
986 (* different than Coq manual!!! *)
987 C.Sort s2,subst,metasenv,ugraph
988 | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
989 let t' = CicUniv.fresh() in
990 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
991 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
992 C.Sort (C.Type t'),subst,metasenv,ugraph2
993 | (C.Sort _,C.Sort (C.Type t1)) ->
994 C.Sort (C.Type t1),subst,metasenv,ugraph
995 | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
996 | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
997 (* TODO how can we force the meta to become a sort? If we don't we
998 * brake the invariant that refine produce only well typed terms *)
999 (* TODO if we check the non meta term and if it is a sort then we
1000 * are likely to know the exact value of the result e.g. if the rhs
1001 * is a Sort (Prop | Set | CProp) then the result is the rhs *)
1002 let (metasenv,idx) =
1003 CicMkImplicit.mk_implicit_sort metasenv subst in
1004 let (subst, metasenv,ugraph1) =
1005 fo_unif_subst subst context_for_t2 metasenv
1006 (C.Meta (idx,[])) t2'' ugraph
1008 t2'',subst,metasenv,ugraph1
1014 ("Two sorts were expected, found %s " ^^
1015 "(that reduces to %s) and %s (that reduces to %s)")
1016 (CicPp.ppterm t1) (CicPp.ppterm t1'') (CicPp.ppterm t2)
1017 (CicPp.ppterm t2''))))
1020 allow_coercions subst metasenv context hetype tlbody_and_type ugraph
1022 let rec mk_prod metasenv context =
1025 let (metasenv, idx) =
1026 CicMkImplicit.mk_implicit_type metasenv subst context
1029 CicMkImplicit.identity_relocation_list_for_metavariable context
1031 metasenv,Cic.Meta (idx, irl)
1033 let (metasenv, idx) =
1034 CicMkImplicit.mk_implicit_type metasenv subst context
1037 CicMkImplicit.identity_relocation_list_for_metavariable context
1039 let meta = Cic.Meta (idx,irl) in
1041 (* The name must be fresh for context. *)
1042 (* Nevertheless, argty is well-typed only in context. *)
1043 (* Thus I generate a name (name_hint) in context and *)
1044 (* then I generate a name --- using the hint name_hint *)
1045 (* --- that is fresh in (context'@context). *)
1047 (* Cic.Name "pippo" *)
1048 FreshNamesGenerator.mk_fresh_name ~subst metasenv
1049 (* (CicMetaSubst.apply_subst_metasenv subst metasenv) *)
1050 (CicMetaSubst.apply_subst_context subst context)
1052 ~typ:(CicMetaSubst.apply_subst subst argty)
1054 (* [] and (Cic.Sort Cic.prop) are dummy: they will not be used *)
1055 FreshNamesGenerator.mk_fresh_name ~subst
1056 [] context name_hint ~typ:(Cic.Sort Cic.Prop)
1058 let metasenv,target =
1059 mk_prod metasenv ((Some (name, Cic.Decl meta))::context) tl
1061 metasenv,Cic.Prod (name,meta,target)
1063 let metasenv,hetype' = mk_prod metasenv context tlbody_and_type in
1064 let (subst, metasenv,ugraph1) =
1066 fo_unif_subst subst context metasenv hetype hetype' ugraph
1068 debug_print (lazy (Printf.sprintf "hetype=%s\nhetype'=%s\nmetasenv=%s\nsubst=%s"
1069 (CicPp.ppterm hetype)
1070 (CicPp.ppterm hetype')
1071 (CicMetaSubst.ppmetasenv [] metasenv)
1072 (CicMetaSubst.ppsubst subst)));
1076 let rec eat_prods metasenv subst context hetype ugraph =
1078 | [] -> [],metasenv,subst,hetype,ugraph
1079 | (hete, hety)::tl ->
1082 let arg,subst,metasenv,ugraph1 =
1084 let subst,metasenv,ugraph1 =
1085 fo_unif_subst subst context metasenv hety s ugraph
1087 hete,subst,metasenv,ugraph1
1088 with exn when allow_coercions ->
1089 (* we search a coercion from hety to s *)
1091 let carr t subst context =
1092 CicMetaSubst.apply_subst subst t
1094 let c_hety = carr hety subst context in
1095 let c_s = carr s subst context in
1096 CoercGraph.look_for_coercion c_hety c_s
1099 | CoercGraph.NoCoercion
1100 | CoercGraph.NotHandled _ -> raise exn
1101 | CoercGraph.NotMetaClosed ->
1102 raise (Uncertain (lazy "Coercions on meta"))
1103 | CoercGraph.SomeCoercion c ->
1104 (Cic.Appl [ c ; hete ]), subst, metasenv, ugraph
1106 let coerced_args,metasenv',subst',t',ugraph2 =
1107 eat_prods metasenv subst context
1108 (* (CicMetaSubst.subst subst hete t) tl *)
1109 (CicSubstitution.subst hete t) ugraph1 tl
1111 arg::coerced_args,metasenv',subst',t',ugraph2
1115 let coerced_args,metasenv,subst,t,ugraph2 =
1116 eat_prods metasenv subst context hetype' ugraph1 tlbody_and_type
1118 coerced_args,t,subst,metasenv,ugraph2
1121 (* eat prods ends here! *)
1123 let t',ty,subst',metasenv',ugraph1 =
1124 type_of_aux [] metasenv context t ugraph
1126 let substituted_t = CicMetaSubst.apply_subst subst' t' in
1127 let substituted_ty = CicMetaSubst.apply_subst subst' ty in
1128 (* Andrea: ho rimesso qui l'applicazione della subst al
1129 metasenv dopo che ho droppato l'invariante che il metsaenv
1130 e' sempre istanziato *)
1131 let substituted_metasenv =
1132 CicMetaSubst.apply_subst_metasenv subst' metasenv' in
1134 (* substituted_t,substituted_ty,substituted_metasenv *)
1135 (* ANDREA: spostare tutta questa robaccia da un altra parte *)
1137 FreshNamesGenerator.clean_dummy_dependent_types substituted_t in
1139 FreshNamesGenerator.clean_dummy_dependent_types substituted_ty in
1140 let cleaned_metasenv =
1142 (function (n,context,ty) ->
1143 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty in
1148 | Some (n, Cic.Decl t) ->
1150 Cic.Decl (FreshNamesGenerator.clean_dummy_dependent_types t))
1151 | Some (n, Cic.Def (bo,ty)) ->
1152 let bo' = FreshNamesGenerator.clean_dummy_dependent_types bo in
1157 Some (FreshNamesGenerator.clean_dummy_dependent_types ty)
1159 Some (n, Cic.Def (bo',ty'))
1163 ) substituted_metasenv
1165 (cleaned_t,cleaned_ty,cleaned_metasenv,ugraph1)
1168 let type_of_aux' metasenv context term ugraph =
1170 type_of_aux' metasenv context term ugraph
1172 CicUniv.UniverseInconsistency msg -> raise (RefineFailure (lazy msg))
1174 let undebrujin uri typesno tys t =
1177 (fun (name,_,_,_) (i,t) ->
1178 (* here the explicit_named_substituion is assumed to be *)
1180 let t' = Cic.MutInd (uri,i,[]) in
1181 let t = CicSubstitution.subst t' t in
1183 ) tys (typesno - 1,t))
1185 let map_first_n n start f g l =
1186 let rec aux acc k l =
1189 | [] -> raise (Invalid_argument "map_first_n")
1190 | hd :: tl -> f hd k (aux acc (k+1) tl)
1196 (*CSC: this is a very rough approximation; to be finished *)
1197 let are_all_occurrences_positive metasenv ugraph uri tys leftno =
1198 let number_of_types = List.length tys in
1199 let subst,metasenv,ugraph,tys =
1201 (fun (name,ind,arity,cl) (subst,metasenv,ugraph,acc) ->
1202 let subst,metasenv,ugraph,cl =
1204 (fun (name,ty) (subst,metasenv,ugraph,acc) ->
1205 let rec aux ctx k subst = function
1206 | Cic.Appl((Cic.MutInd (uri',_,_)as hd)::tl) when uri = uri'->
1207 let subst,metasenv,ugraph,tl =
1209 (subst,metasenv,ugraph,[])
1210 (fun t n (subst,metasenv,ugraph,acc) ->
1211 let subst,metasenv,ugraph =
1213 subst ctx metasenv t (Cic.Rel (k-n)) ugraph
1215 subst,metasenv,ugraph,(t::acc))
1216 (fun (s,m,g,acc) tl -> assert(acc=[]);(s,m,g,tl))
1219 subst,metasenv,ugraph,(Cic.Appl (hd::tl))
1220 | Cic.MutInd(uri',_,_) as t when uri = uri'->
1221 subst,metasenv,ugraph,t
1222 | Cic.Prod (name,s,t) ->
1223 let ctx = (Some (name,Cic.Decl s))::ctx in
1224 let subst,metasenv,ugraph,t = aux ctx (k+1) subst t in
1225 subst,metasenv,ugraph,Cic.Prod (name,s,t)
1229 (lazy "not well formed constructor type"))
1231 let subst,metasenv,ugraph,ty = aux [] 0 subst ty in
1232 subst,metasenv,ugraph,(name,ty) :: acc)
1233 cl (subst,metasenv,ugraph,[])
1235 subst,metasenv,ugraph,(name,ind,arity,cl)::acc)
1236 tys ([],metasenv,ugraph,[])
1238 let substituted_tys =
1240 (fun (name,ind,arity,cl) ->
1242 List.map (fun (name, ty) -> name,CicMetaSubst.apply_subst subst ty) cl
1244 name,ind,CicMetaSubst.apply_subst subst arity,cl)
1247 metasenv,ugraph,substituted_tys
1249 let typecheck metasenv uri obj =
1250 let ugraph = CicUniv.empty_ugraph in
1252 Cic.Constant (name,Some bo,ty,args,attrs) ->
1253 let bo',boty,metasenv,ugraph = type_of_aux' metasenv [] bo ugraph in
1254 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1255 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1256 let bo' = CicMetaSubst.apply_subst subst bo' in
1257 let ty' = CicMetaSubst.apply_subst subst ty' in
1258 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1259 Cic.Constant (name,Some bo',ty',args,attrs),metasenv,ugraph
1260 | Cic.Constant (name,None,ty,args,attrs) ->
1261 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1262 Cic.Constant (name,None,ty',args,attrs),metasenv,ugraph
1263 | Cic.CurrentProof (name,metasenv',bo,ty,args,attrs) ->
1264 assert (metasenv' = metasenv);
1265 (* Here we do not check the metasenv for correctness *)
1266 let bo',boty,metasenv,ugraph = type_of_aux' metasenv [] bo ugraph in
1267 let ty',sort,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1271 (* instead of raising Uncertain, let's hope that the meta will become
1274 | _ -> raise (RefineFailure (lazy "The term provided is not a type"))
1276 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1277 let bo' = CicMetaSubst.apply_subst subst bo' in
1278 let ty' = CicMetaSubst.apply_subst subst ty' in
1279 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1280 Cic.CurrentProof (name,metasenv,bo',ty',args,attrs),metasenv,ugraph
1281 | Cic.Variable _ -> assert false (* not implemented *)
1282 | Cic.InductiveDefinition (tys,args,paramsno,attrs) ->
1283 (*CSC: this code is greately simplified and many many checks are missing *)
1284 (*CSC: e.g. the constructors are not required to build their own types, *)
1285 (*CSC: the arities are not required to have as type a sort, etc. *)
1286 let uri = match uri with Some uri -> uri | None -> assert false in
1287 let typesno = List.length tys in
1288 (* first phase: we fix only the types *)
1289 let metasenv,ugraph,tys =
1291 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
1292 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1293 metasenv,ugraph,(name,b,ty',cl)::res
1294 ) tys (metasenv,ugraph,[]) in
1296 List.rev_map (fun (name,_,ty,_)-> Some (Cic.Name name,Cic.Decl ty)) tys in
1297 (* second phase: we fix only the constructors *)
1298 let metasenv,ugraph,tys =
1300 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
1301 let metasenv,ugraph,cl' =
1303 (fun (name,ty) (metasenv,ugraph,res) ->
1304 let ty = CicTypeChecker.debrujin_constructor uri typesno ty in
1305 let ty',_,metasenv,ugraph =
1306 type_of_aux' metasenv con_context ty ugraph in
1307 let ty' = undebrujin uri typesno tys ty' in
1308 metasenv,ugraph,(name,ty')::res
1309 ) cl (metasenv,ugraph,[])
1311 metasenv,ugraph,(name,b,ty,cl')::res
1312 ) tys (metasenv,ugraph,[]) in
1313 (* third phase: we check the positivity condition *)
1314 let metasenv,ugraph,tys =
1315 are_all_occurrences_positive metasenv ugraph uri tys paramsno
1317 Cic.InductiveDefinition (tys,args,paramsno,attrs),metasenv,ugraph
1320 let type_of_aux' metasenv context term =
1323 type_of_aux' metasenv context term in
1325 ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty));
1327 ("@@@ REFINE SUCCESSFUL (metasenv):\n" ^ CicMetaSubst.ppmetasenv ~sep:";" m []));
1330 | RefineFailure msg as e ->
1331 debug_print (lazy ("@@@ REFINE FAILED: " ^ msg));
1333 | Uncertain msg as e ->
1334 debug_print (lazy ("@@@ REFINE UNCERTAIN: " ^ msg));
1338 let profiler2 = HExtlib.profile "CicRefine"
1340 let type_of_aux' metasenv context term ugraph =
1341 profiler2.HExtlib.profile (type_of_aux' metasenv context term) ugraph
1343 let typecheck metasenv uri obj =
1344 profiler2.HExtlib.profile (typecheck metasenv uri) obj