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/.
30 exception RefineFailure of string Lazy.t;;
31 exception Uncertain of string Lazy.t;;
32 exception AssertFailure of string Lazy.t;;
34 (* for internal use only; the integer is the number of surplus arguments *)
35 exception MoreArgsThanExpected of int * exn;;
37 let insert_coercions = ref true
38 let pack_coercions = ref true
43 if debug then (fun x -> prerr_endline (Lazy.force x)) else (fun _ -> ());;
45 let profiler_eat_prods2 = HExtlib.profile "CicRefine.fo_unif_eat_prods2"
47 let fo_unif_subst_eat_prods2 subst context metasenv t1 t2 ugraph =
50 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
51 in profiler_eat_prods2.HExtlib.profile foo ()
53 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
54 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
57 let profiler_eat_prods = HExtlib.profile "CicRefine.fo_unif_eat_prods"
59 let fo_unif_subst_eat_prods subst context metasenv t1 t2 ugraph =
62 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
63 in profiler_eat_prods.HExtlib.profile foo ()
65 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
66 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
69 let profiler = HExtlib.profile "CicRefine.fo_unif"
71 let fo_unif_subst subst context metasenv t1 t2 ugraph =
74 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
75 in profiler.HExtlib.profile foo ()
77 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
78 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
81 let enrich localization_tbl t ?(f = fun msg -> msg) exn =
84 RefineFailure msg -> RefineFailure (f msg)
85 | Uncertain msg -> Uncertain (f msg)
86 | AssertFailure msg -> prerr_endline (Lazy.force msg); AssertFailure (f msg)
87 | Sys.Break -> raise exn
88 | _ -> prerr_endline (Printexc.to_string exn); assert false
92 Cic.CicHash.find localization_tbl t
94 HLog.debug ("!!! NOT LOCALIZED: " ^ CicPp.ppterm t);
97 raise (HExtlib.Localized (loc,exn'))
99 let relocalize localization_tbl oldt newt =
101 let infos = Cic.CicHash.find localization_tbl oldt in
102 Cic.CicHash.remove localization_tbl oldt;
103 Cic.CicHash.add localization_tbl newt infos;
111 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
112 | (_,_) -> raise (AssertFailure (lazy "split: list too short"))
115 let exp_impl metasenv subst context =
118 let (metasenv', idx) =
119 CicMkImplicit.mk_implicit_type metasenv subst context in
121 CicMkImplicit.identity_relocation_list_for_metavariable context in
122 metasenv', Cic.Meta (idx, irl)
124 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst [] in
125 metasenv', Cic.Meta (idx, [])
127 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst context in
129 CicMkImplicit.identity_relocation_list_for_metavariable context in
130 metasenv', Cic.Meta (idx, irl)
136 | Cic.Appl (hd::args) ->
137 let uri = CicUtil.uri_of_term hd in
139 CicEnvironment.get_obj CicUniv.oblivion_ugraph uri
141 | Cic.Constant (_,Some t,_,[],attrs),_
142 when List.exists ((=) (`Flavour `Variant)) attrs ->
148 let is_a_double_coercion t =
149 let rec subst_nth n x l =
152 | 0, _::tl -> x :: tl
153 | n, hd::tl -> hd :: subst_nth (n-1) x tl
155 let imp = Cic.Implicit None in
156 let dummyres = false,imp, imp,imp,imp in
159 (match CoercGraph.coerced_arg l1 with
160 | Some (Cic.Appl l2, pos1) ->
161 (match CoercGraph.coerced_arg l2 with
163 true, List.hd l1, List.hd l2, x,
164 Cic.Appl (subst_nth (pos1 + 1)
165 (Cic.Appl (subst_nth (pos2+1) imp l2)) l1)
171 let more_args_than_expected localization_tbl metasenv subst he context hetype' residuals tlbody_and_type exn
173 let len = List.length tlbody_and_type in
176 CicMetaSubst.ppterm_in_context ~metasenv subst he context ^
177 " (that has type "^ CicMetaSubst.ppterm_in_context ~metasenv subst hetype' context ^
178 ") is here applied to " ^ string_of_int len ^
179 " arguments but here it can handle only up to " ^
180 string_of_int (len - residuals) ^ " arguments")
182 enrich localization_tbl he ~f:(fun _-> msg) exn
185 let mk_prod_of_metas metasenv context subst args =
186 let rec mk_prod metasenv context' = function
188 let (metasenv, idx) =
189 CicMkImplicit.mk_implicit_type metasenv subst context'
192 CicMkImplicit.identity_relocation_list_for_metavariable context'
194 metasenv,Cic.Meta (idx, irl)
196 let (metasenv, idx) =
197 CicMkImplicit.mk_implicit_type metasenv subst context'
200 CicMkImplicit.identity_relocation_list_for_metavariable context'
202 let meta = Cic.Meta (idx,irl) in
204 (* The name must be fresh for context. *)
205 (* Nevertheless, argty is well-typed only in context. *)
206 (* Thus I generate a name (name_hint) in context and *)
207 (* then I generate a name --- using the hint name_hint *)
208 (* --- that is fresh in context'. *)
210 FreshNamesGenerator.mk_fresh_name ~subst metasenv
211 (CicMetaSubst.apply_subst_context subst context)
213 ~typ:(CicMetaSubst.apply_subst subst argty)
215 FreshNamesGenerator.mk_fresh_name ~subst
216 [] context' name_hint ~typ:(Cic.Sort Cic.Prop)
218 let metasenv,target =
219 mk_prod metasenv ((Some (name, Cic.Decl meta))::context') tl
221 metasenv,Cic.Prod (name,meta,target)
223 mk_prod metasenv context args
226 let rec type_of_constant uri ugraph =
227 let module C = Cic in
228 let module R = CicReduction in
229 let module U = UriManager in
230 let _ = CicTypeChecker.typecheck uri in
233 CicEnvironment.get_cooked_obj ugraph uri
234 with Not_found -> assert false
237 C.Constant (_,_,ty,_,_) -> ty,u
238 | C.CurrentProof (_,_,_,ty,_,_) -> ty,u
242 (lazy ("Unknown constant definition " ^ U.string_of_uri uri)))
244 and type_of_variable uri ugraph =
245 let module C = Cic in
246 let module R = CicReduction in
247 let module U = UriManager in
248 let _ = CicTypeChecker.typecheck uri in
251 CicEnvironment.get_cooked_obj ugraph uri
252 with Not_found -> assert false
255 C.Variable (_,_,ty,_,_) -> ty,u
259 (lazy ("Unknown variable definition " ^ UriManager.string_of_uri uri)))
261 and type_of_mutual_inductive_defs uri i ugraph =
262 let module C = Cic in
263 let module R = CicReduction in
264 let module U = UriManager in
265 let _ = CicTypeChecker.typecheck uri in
268 CicEnvironment.get_cooked_obj ugraph uri
269 with Not_found -> assert false
272 C.InductiveDefinition (dl,_,_,_) ->
273 let (_,_,arity,_) = List.nth dl i in
278 (lazy ("Unknown mutual inductive definition " ^ U.string_of_uri uri)))
280 and type_of_mutual_inductive_constr uri i j ugraph =
281 let module C = Cic in
282 let module R = CicReduction in
283 let module U = UriManager in
284 let _ = CicTypeChecker.typecheck uri in
287 CicEnvironment.get_cooked_obj ugraph uri
288 with Not_found -> assert false
291 C.InductiveDefinition (dl,_,_,_) ->
292 let (_,_,_,cl) = List.nth dl i in
293 let (_,ty) = List.nth cl (j-1) in
299 ("Unkown mutual inductive definition " ^ U.string_of_uri uri)))
302 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
304 (* the check_branch function checks if a branch of a case is refinable.
305 It returns a pair (outype_instance,args), a subst and a metasenv.
306 outype_instance is the expected result of applying the case outtype
308 The problem is that outype is in general unknown, and we should
309 try to synthesize it from the above information, that is in general
310 a second order unification problem. *)
312 and check_branch n context metasenv subst left_args_no actualtype term expectedtype ugraph =
313 let module C = Cic in
314 let module R = CicReduction in
315 match R.whd ~subst context expectedtype with
317 (n,context,actualtype, [term]), subst, metasenv, ugraph
318 | C.Appl (C.MutInd (_,_,_)::tl) ->
319 let (_,arguments) = split tl left_args_no in
320 (n,context,actualtype, arguments@[term]), subst, metasenv, ugraph
321 | C.Prod (_,so,de) ->
322 (* we expect that the actual type of the branch has the due
324 (match R.whd ~subst context actualtype with
325 C.Prod (name',so',de') ->
326 let subst, metasenv, ugraph1 =
327 fo_unif_subst subst context metasenv so so' ugraph in
329 (match CicSubstitution.lift 1 term with
330 C.Appl l -> C.Appl (l@[C.Rel 1])
331 | t -> C.Appl [t ; C.Rel 1]) in
332 (* we should also check that the name variable is anonymous in
333 the actual type de' ?? *)
335 ((Some (name',(C.Decl so)))::context)
336 metasenv subst left_args_no de' term' de ugraph1
337 | _ -> raise (AssertFailure (lazy "Wrong number of arguments")))
338 | _ -> raise (AssertFailure (lazy "Prod or MutInd expected"))
340 and type_of_aux' ?(clean_dummy_dependent_types=true) ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
343 let rec type_of_aux subst metasenv context t ugraph =
344 let module C = Cic in
345 let module S = CicSubstitution in
346 let module U = UriManager in
347 let (t',_,_,_,_) as res =
352 match List.nth context (n - 1) with
353 Some (_,C.Decl ty) ->
354 t,S.lift n ty,subst,metasenv, ugraph
355 | Some (_,C.Def (_,ty)) ->
356 t,S.lift n ty,subst,metasenv, ugraph
358 enrich localization_tbl t
359 (RefineFailure (lazy "Rel to hidden hypothesis"))
362 enrich localization_tbl t
363 (RefineFailure (lazy "Not a closed term")))
364 | C.Var (uri,exp_named_subst) ->
365 let exp_named_subst',subst',metasenv',ugraph1 =
366 check_exp_named_subst
367 subst metasenv context exp_named_subst ugraph
369 let ty_uri,ugraph1 = type_of_variable uri ugraph in
371 CicSubstitution.subst_vars exp_named_subst' ty_uri
373 C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
376 let (canonical_context, term,ty) =
377 CicUtil.lookup_subst n subst
379 let l',subst',metasenv',ugraph1 =
380 check_metasenv_consistency n subst metasenv context
381 canonical_context l ugraph
383 (* trust or check ??? *)
384 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
385 subst', metasenv', ugraph1
386 (* type_of_aux subst metasenv
387 context (CicSubstitution.subst_meta l term) *)
388 with CicUtil.Subst_not_found _ ->
389 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
390 let l',subst',metasenv', ugraph1 =
391 check_metasenv_consistency n subst metasenv context
392 canonical_context l ugraph
394 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
395 subst', metasenv',ugraph1)
396 | C.Sort (C.Type tno) ->
397 let tno' = CicUniv.fresh() in
399 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
400 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
402 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
403 | C.Sort (C.CProp tno) ->
404 let tno' = CicUniv.fresh() in
406 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
407 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
409 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
410 | C.Sort (C.Prop|C.Set) ->
411 t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
412 | C.Implicit infos ->
413 let metasenv',t' = exp_impl metasenv subst context infos in
414 type_of_aux subst metasenv' context t' ugraph
416 let ty',_,subst',metasenv',ugraph1 =
417 type_of_aux subst metasenv context ty ugraph
419 let te',inferredty,subst'',metasenv'',ugraph2 =
420 type_of_aux subst' metasenv' context te ugraph1
422 let rec count_prods context ty =
423 match CicReduction.whd context ~subst:subst'' ty with
424 | Cic.Prod (n,s,t) ->
425 1 + count_prods (Some (n,Cic.Decl s)::context) t
428 let exp_prods = count_prods context ty' in
429 let inf_prods = count_prods context inferredty in
430 let te', inferredty, metasenv'', subst'', ugraph2 =
431 let rec aux t m s ug it = function
434 match CicReduction.whd context ~subst:s it with
435 | Cic.Prod (_,src,tgt) ->
436 let newmeta, metaty, s, m, ug =
437 type_of_aux s m context (Cic.Implicit None) ug
440 fo_unif_subst s context m metaty src ug
444 | Cic.Appl l -> Cic.Appl (l @ [newmeta])
445 | _ -> Cic.Appl [t;newmeta]
447 aux t m s ug (CicSubstitution.subst newmeta tgt) (n-1)
450 aux te' metasenv'' subst'' ugraph2 inferredty
451 (max 0 (inf_prods - exp_prods))
453 let (te', ty'), subst''',metasenv''',ugraph3 =
454 coerce_to_something true localization_tbl te' inferredty ty'
455 subst'' metasenv'' context ugraph2
457 C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
458 | C.Prod (name,s,t) ->
459 let s',sort1,subst',metasenv',ugraph1 =
460 type_of_aux subst metasenv context s ugraph
462 let s',sort1,subst', metasenv',ugraph1 =
463 coerce_to_sort localization_tbl
464 s' sort1 subst' context metasenv' ugraph1
466 let context_for_t = ((Some (name,(C.Decl s')))::context) in
467 let t',sort2,subst'',metasenv'',ugraph2 =
468 type_of_aux subst' metasenv'
469 context_for_t t ugraph1
471 let t',sort2,subst'',metasenv'',ugraph2 =
472 coerce_to_sort localization_tbl
473 t' sort2 subst'' context_for_t metasenv'' ugraph2
475 let sop,subst''',metasenv''',ugraph3 =
476 sort_of_prod localization_tbl subst'' metasenv''
477 context (name,s') t' (sort1,sort2) ugraph2
479 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
480 | C.Lambda (n,s,t) ->
481 let s',sort1,subst',metasenv',ugraph1 =
482 type_of_aux subst metasenv context s ugraph
484 let s',sort1,subst',metasenv',ugraph1 =
485 coerce_to_sort localization_tbl
486 s' sort1 subst' context metasenv' ugraph1
488 let context_for_t = ((Some (n,(C.Decl s')))::context) in
489 let t',type2,subst'',metasenv'',ugraph2 =
490 type_of_aux subst' metasenv' context_for_t t ugraph1
492 C.Lambda (n,s',t'),C.Prod (n,s',type2),
493 subst'',metasenv'',ugraph2
494 | C.LetIn (n,s,ty,t) ->
495 (* only to check if s is well-typed *)
496 let s',ty',subst',metasenv',ugraph1 =
497 type_of_aux subst metasenv context s ugraph in
498 let ty,_,subst',metasenv',ugraph1 =
499 type_of_aux subst' metasenv' context ty ugraph1 in
500 let subst',metasenv',ugraph1 =
502 fo_unif_subst subst' context metasenv'
506 enrich localization_tbl s' exn
508 lazy ("(2) The term " ^
509 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' s'
510 context ^ " has type " ^
511 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' ty'
512 context ^ " but is here used with type " ^
513 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' ty
516 let context_for_t = ((Some (n,(C.Def (s',ty))))::context) in
518 let t',inferredty,subst'',metasenv'',ugraph2 =
519 type_of_aux subst' metasenv'
520 context_for_t t ugraph1
522 (* One-step LetIn reduction.
523 * Even faster than the previous solution.
524 * Moreover the inferred type is closer to the expected one.
526 C.LetIn (n,s',ty,t'),
527 CicSubstitution.subst ~avoid_beta_redexes:true s' inferredty,
528 subst'',metasenv'',ugraph2
529 | C.Appl (he::((_::_) as tl)) ->
530 let he',hetype,subst',metasenv',ugraph1 =
531 type_of_aux subst metasenv context he ugraph
533 let tlbody_and_type,subst'',metasenv'',ugraph2 =
534 typeof_list subst' metasenv' context ugraph1 tl
536 let coerced_he,coerced_args,applty,subst''',metasenv''',ugraph3 =
537 eat_prods true subst'' metasenv'' context
538 he' hetype tlbody_and_type ugraph2
540 let newappl = (C.Appl (coerced_he::coerced_args)) in
541 avoid_double_coercion
542 context subst''' metasenv''' ugraph3 newappl applty
543 | C.Appl _ -> assert false
544 | C.Const (uri,exp_named_subst) ->
545 let exp_named_subst',subst',metasenv',ugraph1 =
546 check_exp_named_subst subst metasenv context
547 exp_named_subst ugraph in
548 let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
550 CicSubstitution.subst_vars exp_named_subst' ty_uri
552 C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
553 | C.MutInd (uri,i,exp_named_subst) ->
554 let exp_named_subst',subst',metasenv',ugraph1 =
555 check_exp_named_subst subst metasenv context
556 exp_named_subst ugraph
558 let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
560 CicSubstitution.subst_vars exp_named_subst' ty_uri in
561 C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
562 | C.MutConstruct (uri,i,j,exp_named_subst) ->
563 let exp_named_subst',subst',metasenv',ugraph1 =
564 check_exp_named_subst subst metasenv context
565 exp_named_subst ugraph
568 type_of_mutual_inductive_constr uri i j ugraph1
571 CicSubstitution.subst_vars exp_named_subst' ty_uri
573 C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
575 | C.MutCase (uri, i, outtype, term, pl) ->
576 (* first, get the inductive type (and noparams)
577 * in the environment *)
578 let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
579 let _ = CicTypeChecker.typecheck uri in
580 let obj,u = CicEnvironment.get_cooked_obj ugraph uri in
582 C.InductiveDefinition (l,expl_params,parsno,_) ->
583 List.nth l i , expl_params, parsno, u
585 enrich localization_tbl t
587 (lazy ("Unkown mutual inductive definition " ^
588 U.string_of_uri uri)))
590 if List.length constructors <> List.length pl then
591 enrich localization_tbl t
593 (lazy "Wrong number of cases")) ;
594 let rec count_prod t =
595 match CicReduction.whd ~subst context t with
596 C.Prod (_, _, t) -> 1 + (count_prod t)
599 let no_args = count_prod arity in
600 (* now, create a "generic" MutInd *)
601 let metasenv,left_args =
602 CicMkImplicit.n_fresh_metas metasenv subst context no_left_params
604 let metasenv,right_args =
605 let no_right_params = no_args - no_left_params in
606 if no_right_params < 0 then assert false
607 else CicMkImplicit.n_fresh_metas
608 metasenv subst context no_right_params
610 let metasenv,exp_named_subst =
611 CicMkImplicit.fresh_subst metasenv subst context expl_params in
614 C.MutInd (uri,i,exp_named_subst)
617 (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
619 (* check consistency with the actual type of term *)
620 let term',actual_type,subst,metasenv,ugraph1 =
621 type_of_aux subst metasenv context term ugraph in
622 let expected_type',_, subst, metasenv,ugraph2 =
623 type_of_aux subst metasenv context expected_type ugraph1
625 let actual_type = CicReduction.whd ~subst context actual_type in
626 let subst,metasenv,ugraph3 =
628 fo_unif_subst subst context metasenv
629 expected_type' actual_type ugraph2
632 enrich localization_tbl term' exn
634 lazy ("(3) The term " ^
635 CicMetaSubst.ppterm_in_context ~metasenv subst term'
636 context ^ " has type " ^
637 CicMetaSubst.ppterm_in_context ~metasenv subst actual_type
638 context ^ " but is here used with type " ^
639 CicMetaSubst.ppterm_in_context ~metasenv subst expected_type'
642 let rec instantiate_prod t =
646 match CicReduction.whd ~subst context t with
648 instantiate_prod (CicSubstitution.subst he t') tl
651 let arity_instantiated_with_left_args =
652 instantiate_prod arity left_args in
653 (* TODO: check if the sort elimination
654 * is allowed: [(I q1 ... qr)|B] *)
655 let (pl',_,outtypeinstances,subst,metasenv,ugraph4) =
657 (fun p (pl,j,outtypeinstances,subst,metasenv,ugraph) ->
659 if left_args = [] then
660 (C.MutConstruct (uri,i,j,exp_named_subst))
663 (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
665 let p',actual_type,subst,metasenv,ugraph1 =
666 type_of_aux subst metasenv context p ugraph
668 let constructor',expected_type, subst, metasenv,ugraph2 =
669 type_of_aux subst metasenv context constructor ugraph1
671 let outtypeinstance,subst,metasenv,ugraph3 =
673 check_branch 0 context metasenv subst
674 no_left_params actual_type constructor' expected_type
678 enrich localization_tbl constructor'
680 lazy ("(4) The term " ^
681 CicMetaSubst.ppterm_in_context metasenv subst p'
682 context ^ " has type " ^
683 CicMetaSubst.ppterm_in_context metasenv subst actual_type
684 context ^ " but is here used with type " ^
685 CicMetaSubst.ppterm_in_context metasenv subst expected_type
689 outtypeinstance::outtypeinstances,subst,metasenv,ugraph3))
690 pl ([],List.length pl,[],subst,metasenv,ugraph3)
693 (* we are left to check that the outype matches his instances.
694 The easy case is when the outype is specified, that amount
695 to a trivial check. Otherwise, we should guess a type from
699 let outtype,outtypety, subst, metasenv,ugraph4 =
700 type_of_aux subst metasenv context outtype ugraph4 in
703 (let candidate,ugraph5,metasenv,subst =
704 let exp_name_subst, metasenv =
706 CicEnvironment.get_cooked_obj CicUniv.oblivion_ugraph uri
708 let uris = CicUtil.params_of_obj o in
710 fun uri (acc,metasenv) ->
711 let metasenv',new_meta =
712 CicMkImplicit.mk_implicit metasenv subst context
715 CicMkImplicit.identity_relocation_list_for_metavariable
718 (uri, Cic.Meta(new_meta,irl))::acc, metasenv'
722 match left_args,right_args with
723 [],[] -> Cic.MutInd(uri, i, exp_name_subst)
725 let rec mk_right_args =
728 | n -> (Cic.Rel n)::(mk_right_args (n - 1))
730 let right_args_no = List.length right_args in
731 let lifted_left_args =
732 List.map (CicSubstitution.lift right_args_no) left_args
734 Cic.Appl (Cic.MutInd(uri,i,exp_name_subst)::
735 (lifted_left_args @ mk_right_args right_args_no))
738 FreshNamesGenerator.mk_fresh_name ~subst metasenv
739 context Cic.Anonymous ~typ:ty
741 match outtypeinstances with
743 let extended_context =
744 let rec add_right_args =
746 Cic.Prod (name,ty,t) ->
747 Some (name,Cic.Decl ty)::(add_right_args t)
750 (Some (fresh_name,Cic.Decl ty))::
752 (add_right_args arity_instantiated_with_left_args))@
755 let metasenv,new_meta =
756 CicMkImplicit.mk_implicit metasenv subst extended_context
759 CicMkImplicit.identity_relocation_list_for_metavariable
762 let rec add_lambdas b =
764 Cic.Prod (name,ty,t) ->
765 Cic.Lambda (name,ty,(add_lambdas b t))
766 | _ -> Cic.Lambda (fresh_name, ty, b)
769 add_lambdas (Cic.Meta (new_meta,irl))
770 arity_instantiated_with_left_args
772 (Some candidate),ugraph4,metasenv,subst
773 | (constructor_args_no,_,instance,_)::tl ->
775 let instance',subst,metasenv =
776 CicMetaSubst.delift_rels subst metasenv
777 constructor_args_no instance
779 let candidate,ugraph,metasenv,subst =
781 fun (candidate_oty,ugraph,metasenv,subst)
782 (constructor_args_no,_,instance,_) ->
783 match candidate_oty with
784 | None -> None,ugraph,metasenv,subst
787 let instance',subst,metasenv =
788 CicMetaSubst.delift_rels subst metasenv
789 constructor_args_no instance
791 let subst,metasenv,ugraph =
792 fo_unif_subst subst context metasenv
795 candidate_oty,ugraph,metasenv,subst
797 CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable
798 | RefineFailure _ | Uncertain _ ->
799 None,ugraph,metasenv,subst
800 ) (Some instance',ugraph4,metasenv,subst) tl
803 | None -> None, ugraph,metasenv,subst
805 let rec add_lambdas n b =
807 Cic.Prod (name,ty,t) ->
808 Cic.Lambda (name,ty,(add_lambdas (n + 1) b t))
810 Cic.Lambda (fresh_name, ty,
811 CicSubstitution.lift (n + 1) t)
814 (add_lambdas 0 t arity_instantiated_with_left_args),
815 ugraph,metasenv,subst
816 with CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
817 None,ugraph4,metasenv,subst
820 | None -> raise (Uncertain (lazy "can't solve an higher order unification problem"))
822 let subst,metasenv,ugraph =
824 fo_unif_subst subst context metasenv
825 candidate outtype ugraph5
827 exn -> assert false(* unification against a metavariable *)
829 C.MutCase (uri, i, outtype, term', pl'),
830 CicReduction.head_beta_reduce
831 (CicMetaSubst.apply_subst subst
832 (Cic.Appl (outtype::right_args@[term']))),
833 subst,metasenv,ugraph)
834 | _ -> (* easy case *)
835 let tlbody_and_type,subst,metasenv,ugraph4 =
836 typeof_list subst metasenv context ugraph4 (right_args @ [term'])
838 let _,_,_,subst,metasenv,ugraph4 =
839 eat_prods false subst metasenv context
840 outtype outtypety tlbody_and_type ugraph4
842 let _,_, subst, metasenv,ugraph5 =
843 type_of_aux subst metasenv context
844 (C.Appl ((outtype :: right_args) @ [term'])) ugraph4
846 let (subst,metasenv,ugraph6) =
848 (fun (subst,metasenv,ugraph)
849 p (constructor_args_no,context,instance,args)
854 CicSubstitution.lift constructor_args_no outtype
856 C.Appl (outtype'::args)
858 CicReduction.head_beta_reduce ~delta:false
859 ~upto:(List.length args) appl
862 fo_unif_subst subst context metasenv instance instance'
866 enrich localization_tbl p exn
868 lazy ("(5) The term " ^
869 CicMetaSubst.ppterm_in_context ~metasenv subst p
870 context ^ " has type " ^
871 CicMetaSubst.ppterm_in_context ~metasenv subst instance'
872 context ^ " but is here used with type " ^
873 CicMetaSubst.ppterm_in_context ~metasenv subst instance
875 (subst,metasenv,ugraph5) pl' outtypeinstances
877 C.MutCase (uri, i, outtype, term', pl'),
878 CicReduction.head_beta_reduce
879 (CicMetaSubst.apply_subst subst
880 (C.Appl(outtype::right_args@[term']))),
881 subst,metasenv,ugraph6)
883 let fl_ty',subst,metasenv,types,ugraph1,len =
885 (fun (fl,subst,metasenv,types,ugraph,len) (n,_,ty,_) ->
886 let ty',_,subst',metasenv',ugraph1 =
887 type_of_aux subst metasenv context ty ugraph
889 fl @ [ty'],subst',metasenv',
890 Some (C.Name n,(C.Decl (CicSubstitution.lift len ty')))
891 :: types, ugraph, len+1
892 ) ([],subst,metasenv,[],ugraph,0) fl
894 let context' = types@context in
895 let fl_bo',subst,metasenv,ugraph2 =
897 (fun (fl,subst,metasenv,ugraph) ((name,x,_,bo),ty) ->
898 let bo',ty_of_bo,subst,metasenv,ugraph1 =
899 type_of_aux subst metasenv context' bo ugraph in
900 let expected_ty = CicSubstitution.lift len ty in
901 let subst',metasenv',ugraph' =
903 fo_unif_subst subst context' metasenv
904 ty_of_bo expected_ty ugraph1
907 enrich localization_tbl bo exn
909 lazy ("(7) The term " ^
910 CicMetaSubst.ppterm_in_context ~metasenv subst bo
911 context' ^ " has type " ^
912 CicMetaSubst.ppterm_in_context ~metasenv subst ty_of_bo
913 context' ^ " but is here used with type " ^
914 CicMetaSubst.ppterm_in_context ~metasenv subst expected_ty
917 fl @ [bo'] , subst',metasenv',ugraph'
918 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
920 let ty = List.nth fl_ty' i in
921 (* now we have the new ty in fl_ty', the new bo in fl_bo',
922 * and we want the new fl with bo' and ty' injected in the right
925 let rec map3 f l1 l2 l3 =
928 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
931 let fl'' = map3 (fun ty' bo' (name,x,ty,bo) -> (name,x,ty',bo') )
934 C.Fix (i,fl''),ty,subst,metasenv,ugraph2
936 let fl_ty',subst,metasenv,types,ugraph1,len =
938 (fun (fl,subst,metasenv,types,ugraph,len) (n,ty,_) ->
939 let ty',_,subst',metasenv',ugraph1 =
940 type_of_aux subst metasenv context ty ugraph
942 fl @ [ty'],subst',metasenv',
943 Some (C.Name n,(C.Decl (CicSubstitution.lift len ty'))) ::
944 types, ugraph1, len+1
945 ) ([],subst,metasenv,[],ugraph,0) fl
947 let context' = types@context in
948 let fl_bo',subst,metasenv,ugraph2 =
950 (fun (fl,subst,metasenv,ugraph) ((name,_,bo),ty) ->
951 let bo',ty_of_bo,subst,metasenv,ugraph1 =
952 type_of_aux subst metasenv context' bo ugraph in
953 let expected_ty = CicSubstitution.lift len ty in
954 let subst',metasenv',ugraph' =
956 fo_unif_subst subst context' metasenv
957 ty_of_bo expected_ty ugraph1
960 enrich localization_tbl bo exn
962 lazy ("(8) The term " ^
963 CicMetaSubst.ppterm_in_context ~metasenv subst bo
964 context' ^ " has type " ^
965 CicMetaSubst.ppterm_in_context ~metasenv subst ty_of_bo
966 context' ^ " but is here used with type " ^
967 CicMetaSubst.ppterm_in_context ~metasenv subst expected_ty
970 fl @ [bo'],subst',metasenv',ugraph'
971 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
973 let ty = List.nth fl_ty' i in
974 (* now we have the new ty in fl_ty', the new bo in fl_bo',
975 * and we want the new fl with bo' and ty' injected in the right
978 let rec map3 f l1 l2 l3 =
981 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
984 let fl'' = map3 (fun ty' bo' (name,ty,bo) -> (name,ty',bo') )
987 C.CoFix (i,fl''),ty,subst,metasenv,ugraph2
989 relocalize localization_tbl t t';
992 (* check_metasenv_consistency checks that the "canonical" context of a
993 metavariable is consitent - up to relocation via the relocation list l -
994 with the actual context *)
995 and check_metasenv_consistency
996 metano subst metasenv context canonical_context l ugraph
998 let module C = Cic in
999 let module R = CicReduction in
1000 let module S = CicSubstitution in
1001 let lifted_canonical_context =
1005 | (Some (n,C.Decl t))::tl ->
1006 (Some (n,C.Decl (S.subst_meta l (S.lift i t))))::(aux (i+1) tl)
1007 | None::tl -> None::(aux (i+1) tl)
1008 | (Some (n,C.Def (t,ty)))::tl ->
1012 (S.subst_meta l (S.lift i t),
1013 S.subst_meta l (S.lift i ty)))) :: (aux (i+1) tl)
1015 aux 1 canonical_context
1019 (fun (l,subst,metasenv,ugraph) t ct ->
1022 l @ [None],subst,metasenv,ugraph
1023 | Some t,Some (_,C.Def (ct,_)) ->
1024 (*CSC: the following optimization is to avoid a possibly
1025 expensive reduction that can be easily avoided and
1026 that is quite frequent. However, this is better
1027 handled using levels to control reduction *)
1032 match List.nth context (n - 1) with
1033 Some (_,C.Def (te,_)) -> S.lift n te
1039 let subst',metasenv',ugraph' =
1041 (*prerr_endline ("poco geniale: nel caso di IRL basterebbe sapere che questo e'
1042 * il Rel corrispondente. Si puo' ottimizzare il caso t = rel.");*)
1043 fo_unif_subst subst context metasenv optimized_t ct ugraph
1044 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))))))
1046 l @ [Some t],subst',metasenv',ugraph'
1047 | Some t,Some (_,C.Decl ct) ->
1048 let t',inferredty,subst',metasenv',ugraph1 =
1049 type_of_aux subst metasenv context t ugraph
1051 let subst'',metasenv'',ugraph2 =
1054 subst' context metasenv' inferredty ct ugraph1
1055 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))))))
1057 l @ [Some t'], subst'',metasenv'',ugraph2
1059 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
1061 Invalid_argument _ ->
1065 "Not well typed metavariable instance %s: the length of the local context does not match the length of the canonical context %s"
1066 (CicMetaSubst.ppterm ~metasenv subst (Cic.Meta (metano, l)))
1067 (CicMetaSubst.ppcontext ~metasenv subst canonical_context))))
1069 and check_exp_named_subst metasubst metasenv context tl ugraph =
1070 let rec check_exp_named_subst_aux metasubst metasenv substs tl ugraph =
1072 [] -> [],metasubst,metasenv,ugraph
1074 let ty_uri,ugraph1 = type_of_variable uri ugraph in
1076 CicSubstitution.subst_vars substs ty_uri in
1077 (* CSC: why was this code here? it is wrong
1078 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1079 Cic.Variable (_,Some bo,_,_) ->
1081 (RefineFailure (lazy
1082 "A variable with a body can not be explicit substituted"))
1083 | Cic.Variable (_,None,_,_) -> ()
1086 (RefineFailure (lazy
1087 ("Unkown variable definition " ^ UriManager.string_of_uri uri)))
1090 let t',typeoft,metasubst',metasenv',ugraph2 =
1091 type_of_aux metasubst metasenv context t ugraph1 in
1092 let subst = uri,t' in
1093 let metasubst'',metasenv'',ugraph3 =
1096 metasubst' context metasenv' typeoft typeofvar ugraph2
1098 raise (RefineFailure (lazy
1099 ("Wrong Explicit Named Substitution: " ^
1100 CicMetaSubst.ppterm metasenv' metasubst' typeoft ^
1101 " not unifiable with " ^
1102 CicMetaSubst.ppterm metasenv' metasubst' typeofvar)))
1104 (* FIXME: no mere tail recursive! *)
1105 let exp_name_subst, metasubst''', metasenv''', ugraph4 =
1106 check_exp_named_subst_aux
1107 metasubst'' metasenv'' (substs@[subst]) tl ugraph3
1109 ((uri,t')::exp_name_subst), metasubst''', metasenv''', ugraph4
1111 check_exp_named_subst_aux metasubst metasenv [] tl ugraph
1114 and sort_of_prod localization_tbl subst metasenv context (name,s) t (t1, t2)
1117 let module C = Cic in
1118 let context_for_t2 = (Some (name,C.Decl s))::context in
1119 let t1'' = CicReduction.whd ~subst context t1 in
1120 let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
1121 match (t1'', t2'') with
1122 | (C.Sort s1, C.Sort s2) when (s2 = C.Prop || s2 = C.Set) ->
1123 (* different than Coq manual!!! *)
1124 C.Sort s2,subst,metasenv,ugraph
1125 | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
1126 let t' = CicUniv.fresh() in
1128 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1129 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1130 C.Sort (C.Type t'),subst,metasenv,ugraph2
1132 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1133 | (C.Sort (C.CProp t1), C.Sort (C.CProp t2)) ->
1134 let t' = CicUniv.fresh() in
1136 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1137 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1138 C.Sort (C.CProp t'),subst,metasenv,ugraph2
1140 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1141 | (C.Sort (C.Type t1), C.Sort (C.CProp t2)) ->
1142 let t' = CicUniv.fresh() in
1144 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1145 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1146 C.Sort (C.CProp t'),subst,metasenv,ugraph2
1148 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1149 | (C.Sort (C.CProp t1), C.Sort (C.Type t2)) ->
1150 let t' = CicUniv.fresh() in
1152 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1153 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1154 C.Sort (C.Type t'),subst,metasenv,ugraph2
1156 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1157 | (C.Sort _,C.Sort (C.Type t1)) ->
1158 C.Sort (C.Type t1),subst,metasenv,ugraph
1159 | (C.Sort _,C.Sort (C.CProp t1)) ->
1160 C.Sort (C.CProp t1),subst,metasenv,ugraph
1161 | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
1162 | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
1163 (* TODO how can we force the meta to become a sort? If we don't we
1164 * break the invariant that refine produce only well typed terms *)
1165 (* TODO if we check the non meta term and if it is a sort then we
1166 * are likely to know the exact value of the result e.g. if the rhs
1167 * is a Sort (Prop | Set | CProp) then the result is the rhs *)
1168 let (metasenv,idx) =
1169 CicMkImplicit.mk_implicit_sort metasenv subst in
1170 let (subst, metasenv,ugraph1) =
1172 fo_unif_subst subst context_for_t2 metasenv
1173 (C.Meta (idx,[])) t2'' ugraph
1174 with _ -> assert false (* unification against a metavariable *)
1176 t2'',subst,metasenv,ugraph1
1179 enrich localization_tbl s
1183 "%s is supposed to be a type, but its type is %s"
1184 (CicMetaSubst.ppterm_in_context ~metasenv subst t context)
1185 (CicMetaSubst.ppterm_in_context ~metasenv subst t2 context))))
1187 enrich localization_tbl t
1191 "%s is supposed to be a type, but its type is %s"
1192 (CicMetaSubst.ppterm_in_context ~metasenv subst s context)
1193 (CicMetaSubst.ppterm_in_context ~metasenv subst t1 context))))
1195 and avoid_double_coercion context subst metasenv ugraph t ty =
1196 if not !pack_coercions then
1197 t,ty,subst,metasenv,ugraph
1199 let b, c1, c2, head, c1_c2_implicit = is_a_double_coercion t in
1201 let source_carr = CoercGraph.source_of c2 in
1202 let tgt_carr = CicMetaSubst.apply_subst subst ty in
1203 (match CoercGraph.look_for_coercion metasenv subst context source_carr tgt_carr
1205 | CoercGraph.SomeCoercion candidates ->
1207 HExtlib.list_findopt
1208 (fun (metasenv,last,c) _ ->
1209 let subst,metasenv,ugraph =
1210 fo_unif_subst subst context metasenv last head ugraph in
1211 debug_print (lazy ("\nprovo" ^ CicPp.ppterm c));
1216 CicPp.ppterm t ^ " ==> " ^ CicPp.ppterm c));
1217 let newt,_,subst,metasenv,ugraph =
1218 type_of_aux subst metasenv context c ugraph in
1219 debug_print (lazy "tipa...");
1220 let subst, metasenv, ugraph =
1221 (* COME MAI C'ERA UN IF su !pack_coercions ??? *)
1222 fo_unif_subst subst context metasenv newt t ugraph
1224 debug_print (lazy "unifica...");
1225 Some (newt, ty, subst, metasenv, ugraph)
1227 | RefineFailure s | Uncertain s when not !pack_coercions->
1228 debug_print s; debug_print (lazy "stop\n");None
1229 | RefineFailure s | Uncertain s ->
1230 debug_print s;debug_print (lazy "goon\n");
1232 let old_pack_coercions = !pack_coercions in
1233 pack_coercions := false; (* to avoid diverging *)
1234 let refined_c1_c2_implicit,ty,subst,metasenv,ugraph =
1235 type_of_aux subst metasenv context c1_c2_implicit ugraph
1237 pack_coercions := old_pack_coercions;
1239 is_a_double_coercion refined_c1_c2_implicit
1245 match refined_c1_c2_implicit with
1246 | Cic.Appl l -> HExtlib.list_last l
1249 let subst, metasenv, ugraph =
1250 try fo_unif_subst subst context metasenv
1252 with RefineFailure s| Uncertain s->
1253 debug_print s;assert false
1255 let subst, metasenv, ugraph =
1256 fo_unif_subst subst context metasenv
1257 refined_c1_c2_implicit t ugraph
1259 Some (refined_c1_c2_implicit,ty,subst,metasenv,ugraph)
1261 | RefineFailure s | Uncertain s ->
1262 pack_coercions := true;debug_print s;None
1263 | exn -> pack_coercions := true; raise exn))
1266 (match selected with
1270 (lazy ("#### Coercion not packed: " ^ CicPp.ppterm t));
1271 t, ty, subst, metasenv, ugraph)
1272 | _ -> t, ty, subst, metasenv, ugraph)
1274 t, ty, subst, metasenv, ugraph
1276 and typeof_list subst metasenv context ugraph l =
1277 let tlbody_and_type,subst,metasenv,ugraph =
1279 (fun x (res,subst,metasenv,ugraph) ->
1280 let x',ty,subst',metasenv',ugraph1 =
1281 type_of_aux subst metasenv context x ugraph
1283 (x', ty)::res,subst',metasenv',ugraph1
1284 ) l ([],subst,metasenv,ugraph)
1286 tlbody_and_type,subst,metasenv,ugraph
1289 allow_coercions subst metasenv context he hetype args_bo_and_ty ugraph
1291 (* given he:hety, gives beack all (c he) such that (c e):?->? *)
1292 let fix_arity n metasenv context subst he hetype ugraph =
1293 let hetype = CicMetaSubst.apply_subst subst hetype in
1294 (* instead of a dummy functional type we may create the real product
1295 * using args_bo_and_ty, but since coercions lookup ignores the
1296 * actual ariety we opt for the simple solution *)
1297 let fty = Cic.Prod(Cic.Anonymous, Cic.Sort Cic.Prop, Cic.Sort Cic.Prop) in
1298 match CoercGraph.look_for_coercion metasenv subst context hetype fty with
1299 | CoercGraph.NoCoercion -> []
1300 | CoercGraph.NotHandled ->
1301 raise (MoreArgsThanExpected (n,Uncertain (lazy "")))
1302 | CoercGraph.SomeCoercionToTgt candidates
1303 | CoercGraph.SomeCoercion candidates ->
1305 (fun (metasenv,last,coerc) ->
1307 CicMetaSubst.ppterm_in_context ~metasenv subst t context in
1309 let subst,metasenv,ugraph =
1310 fo_unif_subst subst context metasenv last he ugraph in
1311 debug_print (lazy ("New head: "^ pp coerc));
1313 CicTypeChecker.type_of_aux' ~subst metasenv context coerc
1316 debug_print (lazy (" has type: "^ pp tty));
1318 Some (unvariant coerc,tty,subst,metasenv,ugraph)
1320 | Uncertain _ | RefineFailure _
1321 | HExtlib.Localized (_,Uncertain _)
1322 | HExtlib.Localized (_,RefineFailure _) -> None
1323 | exn -> assert false)
1326 (* aux function to process the type of the head and the args in parallel *)
1327 let rec eat_prods_and_args metasenv subst context he hetype ugraph newargs =
1329 | [] -> newargs,subst,metasenv,he,hetype,ugraph
1330 | (hete, hety)::tl as args ->
1331 match (CicReduction.whd ~subst context hetype) with
1332 | Cic.Prod (n,s,t) ->
1333 let arg,subst,metasenv,ugraph =
1334 coerce_to_something allow_coercions localization_tbl
1335 hete hety s subst metasenv context ugraph in
1337 metasenv subst context he (CicSubstitution.subst (fst arg) t)
1338 ugraph (newargs@[arg]) tl
1341 match he, newargs with
1343 | Cic.Appl l, _ -> Cic.Appl (l@List.map fst newargs)
1344 | _ -> Cic.Appl (he::List.map fst newargs)
1346 (*{{{*) debug_print (lazy
1348 CicMetaSubst.ppterm_in_context ~metasenv subst x context in
1349 "Fixing arity of: "^ pp he ^ "\n that has type: "^ pp hetype^
1350 "\n but is applyed to: " ^ String.concat ";"
1351 (List.map (fun (t,_)->pp t) args_bo_and_ty)); (*}}}*)
1352 let error = ref None in
1353 let possible_fixes =
1354 fix_arity (List.length args) metasenv context subst he hetype
1357 HExtlib.list_findopt
1358 (fun (he,hetype,subst,metasenv,ugraph) _ ->
1359 (* {{{ *)debug_print (lazy ("Try fix: "^
1360 CicMetaSubst.ppterm_in_context ~metasenv subst he context));
1361 debug_print (lazy (" of type: "^
1362 CicMetaSubst.ppterm_in_context
1363 ~metasenv subst hetype context)); (* }}} *)
1365 Some (eat_prods_and_args
1366 metasenv subst context he hetype ugraph [] args)
1368 | RefineFailure _ | Uncertain _
1369 | HExtlib.Localized (_,RefineFailure _)
1370 | HExtlib.Localized (_,Uncertain _) as exn ->
1371 error := Some exn; None)
1379 (MoreArgsThanExpected
1380 (List.length args, RefineFailure (lazy "")))
1381 | Some exn -> raise exn
1383 (* first we check if we are in the simple case of a meta closed term *)
1384 let subst,metasenv,ugraph1,hetype',he,args_bo_and_ty =
1385 if CicUtil.is_meta_closed (CicMetaSubst.apply_subst subst hetype) then
1386 (* this optimization is to postpone fix_arity (the most common case)*)
1387 subst,metasenv,ugraph,hetype,he,args_bo_and_ty
1389 (* this (says CSC) is also useful to infer dependent types *)
1390 let pristinemenv = metasenv in
1391 let metasenv,hetype' =
1392 mk_prod_of_metas metasenv context subst args_bo_and_ty
1395 let subst,metasenv,ugraph =
1396 fo_unif_subst_eat_prods subst context metasenv hetype hetype' ugraph
1398 subst,metasenv,ugraph,hetype',he,args_bo_and_ty
1399 with RefineFailure _ | Uncertain _ ->
1400 subst,pristinemenv,ugraph,hetype,he,args_bo_and_ty
1402 let coerced_args,subst,metasenv,he,t,ugraph =
1405 metasenv subst context he hetype' ugraph1 [] args_bo_and_ty
1407 MoreArgsThanExpected (residuals,exn) ->
1408 more_args_than_expected localization_tbl metasenv
1409 subst he context hetype' residuals args_bo_and_ty exn
1411 he,(List.map fst coerced_args),t,subst,metasenv,ugraph
1413 and coerce_to_something
1414 allow_coercions localization_tbl t infty expty subst metasenv context ugraph
1416 let module CS = CicSubstitution in
1417 let module CR = CicReduction in
1418 let cs_subst = CS.subst ~avoid_beta_redexes:true in
1419 let coerce_atom_to_something t infty expty subst metasenv context ugraph =
1420 debug_print (lazy ("COERCE_ATOM_TO_SOMETHING"));
1422 CoercGraph.look_for_coercion metasenv subst context infty expty
1425 | CoercGraph.NoCoercion
1426 | CoercGraph.SomeCoercionToTgt _ -> raise (RefineFailure (lazy
1427 "coerce_atom_to_something fails since no coercions found"))
1428 | CoercGraph.NotHandled when
1429 not (CicUtil.is_meta_closed infty) ||
1430 not (CicUtil.is_meta_closed expty) -> raise (Uncertain (lazy
1431 "coerce_atom_to_something fails since carriers have metas"))
1432 | CoercGraph.NotHandled -> raise (RefineFailure (lazy
1433 "coerce_atom_to_something fails since no coercions found"))
1434 | CoercGraph.SomeCoercion candidates ->
1435 debug_print (lazy (string_of_int (List.length candidates) ^
1436 " candidates found"));
1437 let uncertain = ref false in
1441 (fun (metasenv,last,c) ->
1443 (* {{{ *) debug_print (lazy ("FO_UNIF_SUBST: " ^
1444 CicMetaSubst.ppterm_in_context ~metasenv subst last context ^
1446 CicMetaSubst.ppterm_in_context ~metasenv subst t context ^
1447 "####" ^ CicMetaSubst.ppterm_in_context ~metasenv subst c
1449 debug_print (lazy ("FO_UNIF_SUBST: " ^
1450 CicPp.ppterm last ^ " <==> " ^ CicPp.ppterm t)); (* }}} *)
1451 let subst,metasenv,ugraph =
1452 fo_unif_subst subst context metasenv last t ugraph
1454 let newt,newhety,subst,metasenv,ugraph =
1455 type_of_aux subst metasenv context c ugraph in
1456 let newt, newty, subst, metasenv, ugraph =
1457 avoid_double_coercion context subst metasenv ugraph newt
1460 let subst,metasenv,ugraph =
1461 fo_unif_subst subst context metasenv newhety expty ugraph
1464 CicReduction.are_convertible
1465 ~subst ~metasenv context infty expty ugraph
1468 Some ((t,infty), subst, metasenv, ugraph)
1470 let newt = unvariant newt in
1471 Some ((newt,newty), subst, metasenv, ugraph)
1473 | Uncertain _ -> uncertain := true; None
1474 | RefineFailure _ -> None)
1479 (fun (_,_,m1,_) (_,_,m2,_) -> List.length m1 - List.length m2)
1487 | None when !uncertain -> raise (Uncertain (lazy "coerce_atom fails"))
1488 | None -> raise (RefineFailure (lazy "coerce_atom fails"))
1490 let rec coerce_to_something_aux
1491 t infty expty subst metasenv context ugraph
1494 let subst, metasenv, ugraph =
1495 fo_unif_subst subst context metasenv infty expty ugraph
1497 (t, expty), subst, metasenv, ugraph
1498 with (Uncertain _ | RefineFailure _ as exn)
1499 when allow_coercions && !insert_coercions ->
1500 let whd = CicReduction.whd ~delta:false in
1501 let clean t s c = whd c (CicMetaSubst.apply_subst s t) in
1502 let infty = clean infty subst context in
1503 let expty = clean expty subst context in
1504 let t = clean t subst context in
1505 (*{{{*) debug_print (lazy ("COERCE_TO_SOMETHING: " ^
1506 CicMetaSubst.ppterm_in_context ~metasenv subst t context ^ " : " ^
1507 CicMetaSubst.ppterm_in_context ~metasenv subst infty context ^" ==> "^
1508 CicMetaSubst.ppterm_in_context ~metasenv subst expty context));(*}}}*)
1509 let (coerced,_),subst,metasenv,_ as result =
1510 match infty, expty, t with
1511 | Cic.Prod (nameprod,src,ty), Cic.Prod (_,src2,ty2),Cic.Fix (n,fl) ->
1512 (*{{{*) debug_print (lazy "FIX");
1514 [name,i,_(* infty *),bo] ->
1516 Some (Cic.Name name,Cic.Decl expty)::context in
1517 let (rel1, _), subst, metasenv, ugraph =
1518 coerce_to_something_aux (Cic.Rel 1)
1519 (CS.lift 1 expty) (CS.lift 1 infty) subst
1520 metasenv context_bo ugraph in
1521 let bo = cs_subst rel1 (CS.lift_from 2 1 bo) in
1522 let (bo,_), subst, metasenv, ugraph =
1523 coerce_to_something_aux bo (CS.lift 1 infty) (CS.lift 1
1525 metasenv context_bo ugraph
1527 (Cic.Fix (n,[name,i,expty,bo]),expty),subst,metasenv,ugraph
1528 | _ -> assert false (* not implemented yet *)) (*}}}*)
1529 | _,_, Cic.MutCase (uri,tyno,outty,m,pl) ->
1530 (*{{{*) debug_print (lazy "CASE");
1531 (* {{{ helper functions *)
1532 let get_cl_and_left_p uri tyno outty ugraph =
1533 match CicEnvironment.get_obj ugraph uri with
1534 | Cic.InductiveDefinition (tl, _, leftno, _),ugraph ->
1537 match CicReduction.whd ~delta:false ctx t with
1538 | Cic.Prod (name,src,tgt) ->
1539 let ctx = Some (name, Cic.Decl src) :: ctx in
1545 let rec skip_lambda_delifting t n =
1548 | Cic.Lambda (_,_,t),n ->
1549 skip_lambda_delifting
1550 (CS.subst (Cic.Implicit None) t) (n - 1)
1553 let get_l_r_p n = function
1554 | Cic.Lambda (_,Cic.MutInd _,_) -> [],[]
1555 | Cic.Lambda (_,Cic.Appl (Cic.MutInd _ :: args),_) ->
1556 HExtlib.split_nth n args
1559 let _, _, ty, cl = List.nth tl tyno in
1560 let pis = count_pis ty in
1561 let rno = pis - leftno in
1562 let t = skip_lambda_delifting outty rno in
1563 let left_p, _ = get_l_r_p leftno t in
1564 let instantiale_with_left cl =
1568 (fun t p -> match t with
1569 | Cic.Prod (_,_,t) ->
1575 let cl = instantiale_with_left (List.map snd cl) in
1576 cl, left_p, leftno, rno, ugraph
1579 let rec keep_lambdas_and_put_expty ctx t bo right_p matched n =
1582 let rec mkr n = function
1583 | [] -> [] | _::tl -> Cic.Rel n :: mkr (n+1) tl
1586 CicReplace.replace_lifting
1587 ~equality:(fun _ -> CicUtil.alpha_equivalence)
1589 ~what:(matched::right_p)
1590 ~with_what:(Cic.Rel 1::List.rev (mkr 2 right_p))
1594 | Cic.Lambda (name, src, tgt),_ ->
1595 Cic.Lambda (name, src,
1596 keep_lambdas_and_put_expty
1597 (Some (name, Cic.Decl src)::ctx) tgt (CS.lift 1 bo)
1598 (List.map (CS.lift 1) right_p) (CS.lift 1 matched) (n-1))
1601 let eq_uri, eq, eq_refl =
1602 match LibraryObjects.eq_URI () with
1603 | None -> HLog.warn "no default equality"; raise exn
1604 | Some u -> u, Cic.MutInd(u,0,[]), Cic.MutConstruct (u,0,1,[])
1607 metasenv subst context uri tyno cty outty mty m leftno i
1609 let rec aux context outty par k mty m = function
1610 | Cic.Prod (name, src, tgt) ->
1613 (Some (name, Cic.Decl src) :: context)
1614 (CS.lift 1 outty) (Cic.Rel k::par) (k+1)
1615 (CS.lift 1 mty) (CS.lift 1 m) tgt
1617 Cic.Prod (name, src, t), k
1620 let k = Cic.MutConstruct (uri,tyno,i,[]) in
1621 if par <> [] then Cic.Appl (k::par) else k
1623 Cic.Prod (Cic.Name "p",
1624 Cic.Appl [eq; mty; m; k],
1626 (CR.head_beta_reduce ~delta:false
1627 (Cic.Appl [outty;k])))),k
1628 | Cic.Appl (Cic.MutInd _::pl) ->
1629 let left_p,right_p = HExtlib.split_nth leftno pl in
1630 let has_rights = right_p <> [] in
1632 let k = Cic.MutConstruct (uri,tyno,i,[]) in
1633 Cic.Appl (k::left_p@par)
1637 CicTypeChecker.type_of_aux' ~subst metasenv context k
1638 CicUniv.oblivion_ugraph
1640 | Cic.Appl (Cic.MutInd _::args),_ ->
1641 snd (HExtlib.split_nth leftno args)
1643 with CicTypeChecker.TypeCheckerFailure _-> assert false
1646 CR.head_beta_reduce ~delta:false
1647 (Cic.Appl (outty ::right_p @ [k])),k
1649 Cic.Prod (Cic.Name "p",
1650 Cic.Appl [eq; mty; m; k],
1652 (CR.head_beta_reduce ~delta:false
1653 (Cic.Appl (outty ::right_p @ [k]))))),k
1656 aux context outty [] 1 mty m cty
1658 let add_lambda_for_refl_m pbo rno mty m k cty =
1659 (* k lives in the right context *)
1660 if rno <> 0 then pbo else
1661 let rec aux mty m = function
1662 | Cic.Lambda (name,src,bo), Cic.Prod (_,_,ty) ->
1663 Cic.Lambda (name,src,
1664 (aux (CS.lift 1 mty) (CS.lift 1 m) (bo,ty)))
1666 Cic.Lambda (Cic.Name "p",
1667 Cic.Appl [eq; mty; m; k],CS.lift 1 t)
1671 let add_pi_for_refl_m new_outty mty m rno =
1672 if rno <> 0 then new_outty else
1673 let rec aux m mty = function
1674 | Cic.Lambda (name, src, tgt) ->
1675 Cic.Lambda (name, src,
1676 aux (CS.lift 1 m) (CS.lift 1 mty) tgt)
1679 (Cic.Anonymous, Cic.Appl [eq;mty;m;Cic.Rel 1],
1683 in (* }}} end helper functions *)
1684 (* constructors types with left params already instantiated *)
1685 let outty = CicMetaSubst.apply_subst subst outty in
1686 let cl, left_p, leftno,rno,ugraph =
1687 get_cl_and_left_p uri tyno outty ugraph
1692 CicTypeChecker.type_of_aux' ~subst metasenv context m
1693 CicUniv.oblivion_ugraph
1695 | (Cic.MutInd _ | Cic.Meta _) as mty,_ -> [], mty
1696 | Cic.Appl ((Cic.MutInd _|Cic.Meta _)::args) as mty,_ ->
1697 snd (HExtlib.split_nth leftno args), mty
1699 with CicTypeChecker.TypeCheckerFailure _ ->
1700 raise (AssertFailure(lazy "already ill-typed matched term"))
1703 keep_lambdas_and_put_expty context outty expty right_p m (rno+1)
1706 (lazy ("CASE: new_outty: " ^ CicMetaSubst.ppterm_in_context
1707 ~metasenv subst new_outty context));
1708 let _,pl,subst,metasenv,ugraph =
1710 (fun cty pbo (i, acc, s, menv, ugraph) ->
1711 (* Pi k_par, (Pi H:m=(K_i left_par k_par)),
1712 * (new_)outty right_par (K_i left_par k_par) *)
1714 add_params menv s context uri tyno
1715 cty outty mty m leftno i in
1717 (lazy ("CASE: infty_pbo: "^CicMetaSubst.ppterm_in_context
1718 ~metasenv subst infty_pbo context));
1719 let expty_pbo, k = (* k is (K_i left_par k_par) *)
1720 add_params menv s context uri tyno
1721 cty new_outty mty m leftno i in
1723 (lazy ("CASE: expty_pbo: "^CicMetaSubst.ppterm_in_context
1724 ~metasenv subst expty_pbo context));
1725 let pbo = add_lambda_for_refl_m pbo rno mty m k cty in
1727 (lazy ("CASE: pbo: " ^ CicMetaSubst.ppterm_in_context
1728 ~metasenv subst pbo context));
1729 let (pbo, _), subst, metasenv, ugraph =
1730 coerce_to_something_aux pbo infty_pbo expty_pbo
1731 s menv context ugraph
1734 (lazy ("CASE: pbo: " ^ CicMetaSubst.ppterm_in_context
1735 ~metasenv subst pbo context));
1736 (i-1, pbo::acc, subst, metasenv, ugraph))
1737 cl pl (List.length pl, [], subst, metasenv, ugraph)
1739 let new_outty = add_pi_for_refl_m new_outty mty m rno in
1741 (lazy ("CASE: new_outty: " ^ CicMetaSubst.ppterm_in_context
1742 ~metasenv subst new_outty context));
1745 let refl_m=Cic.Appl[eq_refl;mty;m]in
1746 Cic.Appl [Cic.MutCase(uri,tyno,new_outty,m,pl);refl_m]
1748 Cic.MutCase(uri,tyno,new_outty,m,pl)
1750 (t, expty), subst, metasenv, ugraph (*}}}*)
1751 | Cic.Prod (nameprod, src, ty),Cic.Prod (_, src2, ty2), _ ->
1752 (*{{{*) debug_print (lazy "LAM");
1754 FreshNamesGenerator.mk_fresh_name
1755 ~subst metasenv context ~typ:src2 Cic.Anonymous
1757 let context_src2 = (Some (name_con, Cic.Decl src2) :: context) in
1758 (* contravariant part: the argument of f:src->ty *)
1759 let (rel1, _), subst, metasenv, ugraph =
1760 coerce_to_something_aux
1761 (Cic.Rel 1) (CS.lift 1 src2)
1762 (CS.lift 1 src) subst metasenv context_src2 ugraph
1764 (* covariant part: the result of f(c x); x:src2; (c x):src *)
1767 | Cic.Lambda (n,_,bo) -> n, cs_subst rel1 (CS.lift_from 2 1 bo)
1768 | _ -> name_con, Cic.Appl[CS.lift 1 t;rel1]
1770 (* we fix the possible dependency problem in the source ty *)
1771 let ty = cs_subst rel1 (CS.lift_from 2 1 ty) in
1772 let (bo, _), subst, metasenv, ugraph =
1773 coerce_to_something_aux
1774 bo ty ty2 subst metasenv context_src2 ugraph
1776 let coerced = Cic.Lambda (name_t,src2, bo) in
1777 (coerced, expty), subst, metasenv, ugraph (*}}}*)
1779 (*{{{*)debug_print (lazy ("ATOM: "^CicMetaSubst.ppterm_in_context
1780 ~metasenv subst infty context ^ " ==> " ^
1781 CicMetaSubst.ppterm_in_context ~metasenv subst expty context));
1782 coerce_atom_to_something
1783 t infty expty subst metasenv context ugraph (*}}}*)
1785 debug_print (lazy ("COERCE TO SOMETHING END: "^
1786 CicMetaSubst.ppterm_in_context ~metasenv subst coerced context));
1790 coerce_to_something_aux t infty expty subst metasenv context ugraph
1791 with Uncertain _ | RefineFailure _ as exn ->
1793 lazy ("(9) The term " ^
1794 CicMetaSubst.ppterm_in_context metasenv subst t context ^
1795 " has type " ^ CicMetaSubst.ppterm_in_context metasenv subst
1796 infty context ^ " but is here used with type " ^
1797 CicMetaSubst.ppterm_in_context metasenv subst expty context)
1799 enrich localization_tbl ~f t exn
1801 and coerce_to_sort localization_tbl t infty subst context metasenv uragph =
1802 match CicReduction.whd ~delta:false ~subst context infty with
1803 | Cic.Meta _ | Cic.Sort _ ->
1804 t,infty, subst, metasenv, ugraph
1806 debug_print (lazy ("COERCE TO SORT: "^CicMetaSubst.ppterm_in_context
1807 ~metasenv subst src context));
1808 let tgt = Cic.Sort (Cic.Type (CicUniv.fresh())) in
1810 let (t, ty_t), subst, metasenv, ugraph =
1811 coerce_to_something true
1812 localization_tbl t src tgt subst metasenv context ugraph
1814 debug_print (lazy ("COERCE TO SORT END: "^
1815 CicMetaSubst.ppterm_in_context ~metasenv subst t context));
1816 t, ty_t, subst, metasenv, ugraph
1817 with HExtlib.Localized (_, exn) ->
1819 lazy ("(7)The term " ^
1820 CicMetaSubst.ppterm_in_context ~metasenv subst t context
1821 ^ " is not a type since it has type " ^
1822 CicMetaSubst.ppterm_in_context ~metasenv subst src context
1823 ^ " that is not a sort")
1825 enrich localization_tbl ~f t exn
1828 (* eat prods ends here! *)
1830 let t',ty,subst',metasenv',ugraph1 =
1831 type_of_aux [] metasenv context t ugraph
1833 let substituted_t = CicMetaSubst.apply_subst subst' t' in
1834 let substituted_ty = CicMetaSubst.apply_subst subst' ty in
1835 (* Andrea: ho rimesso qui l'applicazione della subst al
1836 metasenv dopo che ho droppato l'invariante che il metsaenv
1837 e' sempre istanziato *)
1838 let substituted_metasenv =
1839 CicMetaSubst.apply_subst_metasenv subst' metasenv' in
1841 (* substituted_t,substituted_ty,substituted_metasenv *)
1842 (* ANDREA: spostare tutta questa robaccia da un altra parte *)
1844 if clean_dummy_dependent_types then
1845 FreshNamesGenerator.clean_dummy_dependent_types substituted_t
1846 else substituted_t in
1848 if clean_dummy_dependent_types then
1849 FreshNamesGenerator.clean_dummy_dependent_types substituted_ty
1850 else substituted_ty in
1851 let cleaned_metasenv =
1852 if clean_dummy_dependent_types then
1854 (function (n,context,ty) ->
1855 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty in
1860 | Some (n, Cic.Decl t) ->
1862 Cic.Decl (FreshNamesGenerator.clean_dummy_dependent_types t))
1863 | Some (n, Cic.Def (bo,ty)) ->
1864 let bo' = FreshNamesGenerator.clean_dummy_dependent_types bo in
1865 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty
1867 Some (n, Cic.Def (bo',ty'))
1871 ) substituted_metasenv
1873 substituted_metasenv
1875 (cleaned_t,cleaned_ty,cleaned_metasenv,ugraph1)
1878 let undebrujin uri typesno tys t =
1881 (fun (name,_,_,_) (i,t) ->
1882 (* here the explicit_named_substituion is assumed to be *)
1884 let t' = Cic.MutInd (uri,i,[]) in
1885 let t = CicSubstitution.subst t' t in
1887 ) tys (typesno - 1,t))
1889 let map_first_n n start f g l =
1890 let rec aux acc k l =
1893 | [] -> raise (Invalid_argument "map_first_n")
1894 | hd :: tl -> f hd k (aux acc (k+1) tl)
1900 (*CSC: this is a very rough approximation; to be finished *)
1901 let are_all_occurrences_positive metasenv ugraph uri tys leftno =
1902 let subst,metasenv,ugraph,tys =
1904 (fun (name,ind,arity,cl) (subst,metasenv,ugraph,acc) ->
1905 let subst,metasenv,ugraph,cl =
1907 (fun (name,ty) (subst,metasenv,ugraph,acc) ->
1908 let rec aux ctx k subst = function
1909 | Cic.Appl((Cic.MutInd (uri',_,_)as hd)::tl) when uri = uri'->
1910 let subst,metasenv,ugraph,tl =
1912 (subst,metasenv,ugraph,[])
1913 (fun t n (subst,metasenv,ugraph,acc) ->
1914 let subst,metasenv,ugraph =
1916 subst ctx metasenv t (Cic.Rel (k-n)) ugraph
1918 subst,metasenv,ugraph,(t::acc))
1919 (fun (s,m,g,acc) tl -> assert(acc=[]);(s,m,g,tl))
1922 subst,metasenv,ugraph,(Cic.Appl (hd::tl))
1923 | Cic.MutInd(uri',_,_) as t when uri = uri'->
1924 subst,metasenv,ugraph,t
1925 | Cic.Prod (name,s,t) ->
1926 let ctx = (Some (name,Cic.Decl s))::ctx in
1927 let subst,metasenv,ugraph,t = aux ctx (k+1) subst t in
1928 subst,metasenv,ugraph,Cic.Prod (name,s,t)
1932 (lazy "not well formed constructor type"))
1934 let subst,metasenv,ugraph,ty = aux [] 0 subst ty in
1935 subst,metasenv,ugraph,(name,ty) :: acc)
1936 cl (subst,metasenv,ugraph,[])
1938 subst,metasenv,ugraph,(name,ind,arity,cl)::acc)
1939 tys ([],metasenv,ugraph,[])
1941 let substituted_tys =
1943 (fun (name,ind,arity,cl) ->
1945 List.map (fun (name, ty) -> name,CicMetaSubst.apply_subst subst ty) cl
1947 name,ind,CicMetaSubst.apply_subst subst arity,cl)
1950 metasenv,ugraph,substituted_tys
1952 let typecheck metasenv uri obj ~localization_tbl =
1953 let ugraph = CicUniv.oblivion_ugraph in
1955 Cic.Constant (name,Some bo,ty,args,attrs) ->
1956 (* CSC: ugly code. Here I need to retrieve in advance the loc of bo
1957 since type_of_aux' destroys localization information (which are
1958 preserved by type_of_aux *)
1961 Cic.CicHash.find localization_tbl bo
1963 HLog.debug ("!!! NOT LOCALIZED: " ^ CicPp.ppterm bo);
1965 let bo',boty,metasenv,ugraph =
1966 type_of_aux' ~localization_tbl metasenv [] bo ugraph in
1967 let ty',_,metasenv,ugraph =
1968 type_of_aux' ~localization_tbl metasenv [] ty ugraph in
1969 let subst,metasenv,ugraph =
1971 fo_unif_subst [] [] metasenv boty ty' ugraph
1974 | Uncertain _ as exn ->
1976 lazy ("(1) The term " ^
1977 CicMetaSubst.ppterm_in_context ~metasenv [] bo' [] ^
1979 CicMetaSubst.ppterm_in_context ~metasenv [] boty [] ^
1980 " but is here used with type " ^
1981 CicMetaSubst.ppterm_in_context ~metasenv [] ty' [])
1985 RefineFailure _ -> RefineFailure msg
1986 | Uncertain _ -> Uncertain msg
1989 raise (HExtlib.Localized (loc exn',exn'))
1991 let bo' = CicMetaSubst.apply_subst subst bo' in
1992 let ty' = CicMetaSubst.apply_subst subst ty' in
1993 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1994 Cic.Constant (name,Some bo',ty',args,attrs),metasenv,ugraph
1995 | Cic.Constant (name,None,ty,args,attrs) ->
1996 let ty',sort,metasenv,ugraph =
1997 type_of_aux' ~localization_tbl metasenv [] ty ugraph
1999 (match CicReduction.whd [] sort with
2001 | Cic.Meta _ -> Cic.Constant (name,None,ty',args,attrs),metasenv,ugraph
2002 | _ -> raise (RefineFailure (lazy "")))
2003 | Cic.CurrentProof (name,metasenv',bo,ty,args,attrs) ->
2004 assert (metasenv' = metasenv);
2005 (* Here we do not check the metasenv for correctness *)
2006 let bo',boty,metasenv,ugraph =
2007 type_of_aux' ~localization_tbl metasenv [] bo ugraph in
2008 let ty',sort,metasenv,ugraph =
2009 type_of_aux' ~localization_tbl metasenv [] ty ugraph in
2011 match CicReduction.whd ~delta:true [] sort with
2013 (* instead of raising Uncertain, let's hope that the meta will become
2016 | _ -> raise (RefineFailure (lazy "The term provided is not a type"))
2018 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
2019 let bo' = CicMetaSubst.apply_subst subst bo' in
2020 let ty' = CicMetaSubst.apply_subst subst ty' in
2021 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
2022 Cic.CurrentProof (name,metasenv,bo',ty',args,attrs),metasenv,ugraph
2023 | Cic.Variable _ -> assert false (* not implemented *)
2024 | Cic.InductiveDefinition (tys,args,paramsno,attrs) ->
2025 (*CSC: this code is greately simplified and many many checks are missing *)
2026 (*CSC: e.g. the constructors are not required to build their own types, *)
2027 (*CSC: the arities are not required to have as type a sort, etc. *)
2028 let uri = match uri with Some uri -> uri | None -> assert false in
2029 let typesno = List.length tys in
2030 (* first phase: we fix only the types *)
2031 let metasenv,ugraph,tys =
2033 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
2034 let ty',_,metasenv,ugraph =
2035 (* clean_dummy_dependent_types: false to avoid cleaning the names
2036 of the left products, that must be identical to those of the
2037 constructors; however, non-left products should probably be
2039 type_of_aux' ~clean_dummy_dependent_types:false ~localization_tbl
2040 metasenv [] ty ugraph
2042 metasenv,ugraph,(name,b,ty',cl)::res
2043 ) tys (metasenv,ugraph,[]) in
2045 List.rev_map (fun (name,_,ty,_)-> Some (Cic.Name name,Cic.Decl ty)) tys in
2046 (* second phase: we fix only the constructors *)
2047 let saved_menv = metasenv in
2048 let metasenv,ugraph,tys =
2050 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
2051 let metasenv,ugraph,cl' =
2053 (fun (name,ty) (metasenv,ugraph,res) ->
2055 CicTypeChecker.debrujin_constructor
2056 ~cb:(relocalize localization_tbl) uri typesno [] ty in
2057 let ty',_,metasenv,ugraph =
2058 type_of_aux' ~localization_tbl metasenv con_context ty ugraph in
2059 let ty' = undebrujin uri typesno tys ty' in
2060 metasenv@saved_menv,ugraph,(name,ty')::res
2061 ) cl (metasenv,ugraph,[])
2063 metasenv,ugraph,(name,b,ty,cl')::res
2064 ) tys (metasenv,ugraph,[]) in
2065 (* third phase: we check the positivity condition *)
2066 let metasenv,ugraph,tys =
2067 are_all_occurrences_positive metasenv ugraph uri tys paramsno
2069 Cic.InductiveDefinition (tys,args,paramsno,attrs),metasenv,ugraph
2072 (* sara' piu' veloce che raffinare da zero? mah.... *)
2073 let pack_coercion metasenv ctx t =
2074 let module C = Cic in
2075 let rec merge_coercions ctx =
2076 let aux = (fun (u,t) -> u,merge_coercions ctx t) in
2078 | C.Rel _ | C.Sort _ | C.Implicit _ as t -> t
2079 | C.Meta (n,subst) ->
2082 (function None -> None | Some t -> Some (merge_coercions ctx t)) subst
2085 | C.Cast (te,ty) -> C.Cast (merge_coercions ctx te, merge_coercions ctx ty)
2086 | C.Prod (name,so,dest) ->
2087 let ctx' = (Some (name,C.Decl so))::ctx in
2088 C.Prod (name, merge_coercions ctx so, merge_coercions ctx' dest)
2089 | C.Lambda (name,so,dest) ->
2090 let ctx' = (Some (name,C.Decl so))::ctx in
2091 C.Lambda (name, merge_coercions ctx so, merge_coercions ctx' dest)
2092 | C.LetIn (name,so,ty,dest) ->
2093 let ctx' = Some (name,(C.Def (so,ty)))::ctx in
2095 (name, merge_coercions ctx so, merge_coercions ctx ty,
2096 merge_coercions ctx' dest)
2098 let l = List.map (merge_coercions ctx) l in
2100 let b,_,_,_,_ = is_a_double_coercion t in
2102 let ugraph = CicUniv.oblivion_ugraph in
2103 let old_insert_coercions = !insert_coercions in
2104 insert_coercions := false;
2105 let newt, _, menv, _ =
2107 type_of_aux' metasenv ctx t ugraph
2108 with RefineFailure _ | Uncertain _ ->
2111 insert_coercions := old_insert_coercions;
2112 if metasenv <> [] || menv = [] then
2115 (prerr_endline "PUO' SUCCEDERE!!!!!";t)
2118 | C.Var (uri,exp_named_subst) ->
2119 let exp_named_subst = List.map aux exp_named_subst in
2120 C.Var (uri, exp_named_subst)
2121 | C.Const (uri,exp_named_subst) ->
2122 let exp_named_subst = List.map aux exp_named_subst in
2123 C.Const (uri, exp_named_subst)
2124 | C.MutInd (uri,tyno,exp_named_subst) ->
2125 let exp_named_subst = List.map aux exp_named_subst in
2126 C.MutInd (uri,tyno,exp_named_subst)
2127 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
2128 let exp_named_subst = List.map aux exp_named_subst in
2129 C.MutConstruct (uri,tyno,consno,exp_named_subst)
2130 | C.MutCase (uri,tyno,out,te,pl) ->
2131 let pl = List.map (merge_coercions ctx) pl in
2132 C.MutCase (uri,tyno,merge_coercions ctx out, merge_coercions ctx te, pl)
2133 | C.Fix (fno, fl) ->
2136 (fun l (n,_,ty,_) -> (Some (C.Name n,C.Decl ty))::l)
2141 (fun (name,idx,ty,bo) ->
2142 (name,idx,merge_coercions ctx ty,merge_coercions ctx' bo))
2146 | C.CoFix (fno, fl) ->
2149 (fun l (n,ty,_) -> (Some (C.Name n,C.Decl ty))::l)
2154 (fun (name,ty,bo) ->
2155 (name, merge_coercions ctx ty, merge_coercions ctx' bo))
2160 merge_coercions ctx t
2163 let pack_coercion_metasenv conjectures = conjectures (*
2165 TASSI: this code war written when coercions were a toy,
2166 now packing coercions involves unification thus
2167 the metasenv may change, and this pack coercion
2168 does not handle that.
2170 let module C = Cic in
2172 (fun (i, ctx, ty) ->
2178 Some (name, C.Decl t) ->
2179 Some (name, C.Decl (pack_coercion conjectures ctx t))
2180 | Some (name, C.Def (t,None)) ->
2181 Some (name,C.Def (pack_coercion conjectures ctx t,None))
2182 | Some (name, C.Def (t,Some ty)) ->
2183 Some (name, C.Def (pack_coercion conjectures ctx t,
2184 Some (pack_coercion conjectures ctx ty)))
2190 ((i,ctx,pack_coercion conjectures ctx ty))
2195 let pack_coercion_obj obj = obj (*
2197 TASSI: this code war written when coercions were a toy,
2198 now packing coercions involves unification thus
2199 the metasenv may change, and this pack coercion
2200 does not handle that.
2202 let module C = Cic in
2204 | C.Constant (id, body, ty, params, attrs) ->
2208 | Some body -> Some (pack_coercion [] [] body)
2210 let ty = pack_coercion [] [] ty in
2211 C.Constant (id, body, ty, params, attrs)
2212 | C.Variable (name, body, ty, params, attrs) ->
2216 | Some body -> Some (pack_coercion [] [] body)
2218 let ty = pack_coercion [] [] ty in
2219 C.Variable (name, body, ty, params, attrs)
2220 | C.CurrentProof (name, conjectures, body, ty, params, attrs) ->
2221 let conjectures = pack_coercion_metasenv conjectures in
2222 let body = pack_coercion conjectures [] body in
2223 let ty = pack_coercion conjectures [] ty in
2224 C.CurrentProof (name, conjectures, body, ty, params, attrs)
2225 | C.InductiveDefinition (indtys, params, leftno, attrs) ->
2228 (fun (name, ind, arity, cl) ->
2229 let arity = pack_coercion [] [] arity in
2231 List.map (fun (name, ty) -> (name,pack_coercion [] [] ty)) cl
2233 (name, ind, arity, cl))
2236 C.InductiveDefinition (indtys, params, leftno, attrs) *)
2241 let type_of_aux' metasenv context term =
2244 type_of_aux' metasenv context term in
2246 ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty));
2248 ("@@@ REFINE SUCCESSFUL (metasenv):\n" ^ CicMetaSubst.ppmetasenv ~sep:";" m []));
2251 | RefineFailure msg as e ->
2252 debug_print (lazy ("@@@ REFINE FAILED: " ^ msg));
2254 | Uncertain msg as e ->
2255 debug_print (lazy ("@@@ REFINE UNCERTAIN: " ^ msg));
2259 let profiler2 = HExtlib.profile "CicRefine"
2261 let type_of_aux' ?localization_tbl metasenv context term ugraph =
2262 profiler2.HExtlib.profile
2263 (type_of_aux' ?localization_tbl metasenv context term) ugraph
2265 let typecheck ~localization_tbl metasenv uri obj =
2266 profiler2.HExtlib.profile (typecheck ~localization_tbl metasenv uri) obj
2268 let _ = DoubleTypeInference.pack_coercion := pack_coercion;;
2269 (* vim:set foldmethod=marker: *)