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)
134 let is_a_double_coercion t =
135 let rec subst_nth n x l =
138 | 0, _::tl -> x :: tl
139 | n, hd::tl -> hd :: subst_nth (n-1) x tl
141 let imp = Cic.Implicit None in
142 let dummyres = false,imp, imp,imp,imp in
145 (match CoercGraph.coerced_arg l1 with
146 | Some (Cic.Appl l2, pos1) ->
147 (match CoercGraph.coerced_arg l2 with
149 true, List.hd l1, List.hd l2, x,
150 Cic.Appl (subst_nth (pos1 + 1)
151 (Cic.Appl (subst_nth (pos2+1) imp l2)) l1)
157 let more_args_than_expected localization_tbl metasenv subst he context hetype' residuals tlbody_and_type exn
159 let len = List.length tlbody_and_type in
162 CicMetaSubst.ppterm_in_context ~metasenv subst he context ^
163 " (that has type "^ CicMetaSubst.ppterm_in_context ~metasenv subst hetype' context ^
164 ") is here applied to " ^ string_of_int len ^
165 " arguments but here it can handle only up to " ^
166 string_of_int (len - residuals) ^ " arguments")
168 enrich localization_tbl he ~f:(fun _-> msg) exn
171 let mk_prod_of_metas metasenv context subst args =
172 let rec mk_prod metasenv context' = function
174 let (metasenv, idx) =
175 CicMkImplicit.mk_implicit_type metasenv subst context'
178 CicMkImplicit.identity_relocation_list_for_metavariable context'
180 metasenv,Cic.Meta (idx, irl)
182 let (metasenv, idx) =
183 CicMkImplicit.mk_implicit_type metasenv subst context'
186 CicMkImplicit.identity_relocation_list_for_metavariable context'
188 let meta = Cic.Meta (idx,irl) in
190 (* The name must be fresh for context. *)
191 (* Nevertheless, argty is well-typed only in context. *)
192 (* Thus I generate a name (name_hint) in context and *)
193 (* then I generate a name --- using the hint name_hint *)
194 (* --- that is fresh in context'. *)
196 FreshNamesGenerator.mk_fresh_name ~subst metasenv
197 (CicMetaSubst.apply_subst_context subst context)
199 ~typ:(CicMetaSubst.apply_subst subst argty)
201 FreshNamesGenerator.mk_fresh_name ~subst
202 [] context' name_hint ~typ:(Cic.Sort Cic.Prop)
204 let metasenv,target =
205 mk_prod metasenv ((Some (name, Cic.Decl meta))::context') tl
207 metasenv,Cic.Prod (name,meta,target)
209 mk_prod metasenv context args
212 let rec type_of_constant uri ugraph =
213 let module C = Cic in
214 let module R = CicReduction in
215 let module U = UriManager in
216 let _ = CicTypeChecker.typecheck uri in
219 CicEnvironment.get_cooked_obj ugraph uri
220 with Not_found -> assert false
223 C.Constant (_,_,ty,_,_) -> ty,u
224 | C.CurrentProof (_,_,_,ty,_,_) -> ty,u
228 (lazy ("Unknown constant definition " ^ U.string_of_uri uri)))
230 and type_of_variable uri 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.Variable (_,_,ty,_,_) -> ty,u
245 (lazy ("Unknown variable definition " ^ UriManager.string_of_uri uri)))
247 and type_of_mutual_inductive_defs uri i ugraph =
248 let module C = Cic in
249 let module R = CicReduction in
250 let module U = UriManager in
251 let _ = CicTypeChecker.typecheck uri in
254 CicEnvironment.get_cooked_obj ugraph uri
255 with Not_found -> assert false
258 C.InductiveDefinition (dl,_,_,_) ->
259 let (_,_,arity,_) = List.nth dl i in
264 (lazy ("Unknown mutual inductive definition " ^ U.string_of_uri uri)))
266 and type_of_mutual_inductive_constr uri i j ugraph =
267 let module C = Cic in
268 let module R = CicReduction in
269 let module U = UriManager in
270 let _ = CicTypeChecker.typecheck uri in
273 CicEnvironment.get_cooked_obj ugraph uri
274 with Not_found -> assert false
277 C.InductiveDefinition (dl,_,_,_) ->
278 let (_,_,_,cl) = List.nth dl i in
279 let (_,ty) = List.nth cl (j-1) in
285 ("Unkown mutual inductive definition " ^ U.string_of_uri uri)))
288 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
290 (* the check_branch function checks if a branch of a case is refinable.
291 It returns a pair (outype_instance,args), a subst and a metasenv.
292 outype_instance is the expected result of applying the case outtype
294 The problem is that outype is in general unknown, and we should
295 try to synthesize it from the above information, that is in general
296 a second order unification problem. *)
298 and check_branch n context metasenv subst left_args_no actualtype term expectedtype ugraph =
299 let module C = Cic in
300 let module R = CicReduction in
301 match R.whd ~subst context expectedtype with
303 (n,context,actualtype, [term]), subst, metasenv, ugraph
304 | C.Appl (C.MutInd (_,_,_)::tl) ->
305 let (_,arguments) = split tl left_args_no in
306 (n,context,actualtype, arguments@[term]), subst, metasenv, ugraph
307 | C.Prod (_,so,de) ->
308 (* we expect that the actual type of the branch has the due
310 (match R.whd ~subst context actualtype with
311 C.Prod (name',so',de') ->
312 let subst, metasenv, ugraph1 =
313 fo_unif_subst subst context metasenv so so' ugraph in
315 (match CicSubstitution.lift 1 term with
316 C.Appl l -> C.Appl (l@[C.Rel 1])
317 | t -> C.Appl [t ; C.Rel 1]) in
318 (* we should also check that the name variable is anonymous in
319 the actual type de' ?? *)
321 ((Some (name',(C.Decl so)))::context)
322 metasenv subst left_args_no de' term' de ugraph1
323 | _ -> raise (AssertFailure (lazy "Wrong number of arguments")))
324 | _ -> raise (AssertFailure (lazy "Prod or MutInd expected"))
326 and type_of_aux' ?(clean_dummy_dependent_types=true) ?(localization_tbl = Cic.CicHash.create 1) metasenv context t
329 let rec type_of_aux subst metasenv context t ugraph =
330 let module C = Cic in
331 let module S = CicSubstitution in
332 let module U = UriManager in
333 let (t',_,_,_,_) as res =
338 match List.nth context (n - 1) with
339 Some (_,C.Decl ty) ->
340 t,S.lift n ty,subst,metasenv, ugraph
341 | Some (_,C.Def (_,ty)) ->
342 t,S.lift n ty,subst,metasenv, ugraph
344 enrich localization_tbl t
345 (RefineFailure (lazy "Rel to hidden hypothesis"))
348 enrich localization_tbl t
349 (RefineFailure (lazy "Not a closed term")))
350 | C.Var (uri,exp_named_subst) ->
351 let exp_named_subst',subst',metasenv',ugraph1 =
352 check_exp_named_subst
353 subst metasenv context exp_named_subst ugraph
355 let ty_uri,ugraph1 = type_of_variable uri ugraph in
357 CicSubstitution.subst_vars exp_named_subst' ty_uri
359 C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
362 let (canonical_context, term,ty) =
363 CicUtil.lookup_subst n subst
365 let l',subst',metasenv',ugraph1 =
366 check_metasenv_consistency n subst metasenv context
367 canonical_context l ugraph
369 (* trust or check ??? *)
370 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
371 subst', metasenv', ugraph1
372 (* type_of_aux subst metasenv
373 context (CicSubstitution.subst_meta l term) *)
374 with CicUtil.Subst_not_found _ ->
375 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
376 let l',subst',metasenv', ugraph1 =
377 check_metasenv_consistency n subst metasenv context
378 canonical_context l ugraph
380 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
381 subst', metasenv',ugraph1)
382 | C.Sort (C.Type tno) ->
383 let tno' = CicUniv.fresh() in
385 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
386 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
388 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
389 | C.Sort (C.CProp tno) ->
390 let tno' = CicUniv.fresh() in
392 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
393 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
395 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
396 | C.Sort (C.Prop|C.Set) ->
397 t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
398 | C.Implicit infos ->
399 let metasenv',t' = exp_impl metasenv subst context infos in
400 type_of_aux subst metasenv' context t' ugraph
402 let ty',_,subst',metasenv',ugraph1 =
403 type_of_aux subst metasenv context ty ugraph
405 let te',inferredty,subst'',metasenv'',ugraph2 =
406 type_of_aux subst' metasenv' context te ugraph1
408 let rec count_prods context ty =
409 match CicReduction.whd context ty with
410 | Cic.Prod (n,s,t) ->
411 1 + count_prods (Some (n,Cic.Decl s)::context) t
414 let exp_prods = count_prods context ty' in
415 let inf_prods = count_prods context inferredty in
416 let te', inferredty, metasenv'', subst'', ugraph2 =
417 let rec aux t m s ug it = function
420 match CicReduction.whd context it with
421 | Cic.Prod (_,src,tgt) ->
422 let newmeta, metaty, s, m, ug =
423 type_of_aux s m context (Cic.Implicit None) ug
426 fo_unif_subst s context m metaty src ug
428 (* prerr_endline "saturo"; *)
431 | Cic.Appl l -> Cic.Appl (l @ [newmeta])
432 | _ -> Cic.Appl [t;newmeta]
434 aux t m s ug (CicSubstitution.subst newmeta tgt) (n-1)
437 aux te' metasenv'' subst'' ugraph2 inferredty
438 (max 0 (inf_prods - exp_prods))
440 (* prerr_endline ("ottengo: " ^ CicPp.ppterm te'); *)
441 let (te', ty'), subst''',metasenv''',ugraph3 =
442 coerce_to_something true localization_tbl te' inferredty ty'
443 subst'' metasenv'' context ugraph2
445 C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
446 | C.Prod (name,s,t) ->
447 let s',sort1,subst',metasenv',ugraph1 =
448 type_of_aux subst metasenv context s ugraph
450 let s',sort1,subst', metasenv',ugraph1 =
451 coerce_to_sort localization_tbl
452 s' sort1 subst' context metasenv' ugraph1
454 let context_for_t = ((Some (name,(C.Decl s')))::context) in
455 let t',sort2,subst'',metasenv'',ugraph2 =
456 type_of_aux subst' metasenv'
457 context_for_t t ugraph1
459 let t',sort2,subst'',metasenv'',ugraph2 =
460 coerce_to_sort localization_tbl
461 t' sort2 subst'' context_for_t metasenv'' ugraph2
463 let sop,subst''',metasenv''',ugraph3 =
464 sort_of_prod localization_tbl subst'' metasenv''
465 context (name,s') t' (sort1,sort2) ugraph2
467 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
468 | C.Lambda (n,s,t) ->
469 let s',sort1,subst',metasenv',ugraph1 =
470 type_of_aux subst metasenv context s ugraph
472 let s',sort1,subst',metasenv',ugraph1 =
473 coerce_to_sort localization_tbl
474 s' sort1 subst' context metasenv' ugraph1
476 let context_for_t = ((Some (n,(C.Decl s')))::context) in
477 let t',type2,subst'',metasenv'',ugraph2 =
478 type_of_aux subst' metasenv' context_for_t t ugraph1
480 C.Lambda (n,s',t'),C.Prod (n,s',type2),
481 subst'',metasenv'',ugraph2
482 | C.LetIn (n,s,ty,t) ->
483 (* only to check if s is well-typed *)
484 let s',ty',subst',metasenv',ugraph1 =
485 type_of_aux subst metasenv context s ugraph in
486 let ty,_,subst',metasenv',ugraph1 =
487 type_of_aux subst' metasenv' context ty ugraph1 in
488 let subst',metasenv',ugraph1 =
490 fo_unif_subst subst' context metasenv'
494 enrich localization_tbl s' exn
497 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' s'
498 context ^ " has type " ^
499 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' ty'
500 context ^ " but is here used with type " ^
501 CicMetaSubst.ppterm_in_context ~metasenv:metasenv' subst' ty
504 let context_for_t = ((Some (n,(C.Def (s',ty))))::context) in
506 let t',inferredty,subst'',metasenv'',ugraph2 =
507 type_of_aux subst' metasenv'
508 context_for_t t ugraph1
510 (* One-step LetIn reduction.
511 * Even faster than the previous solution.
512 * Moreover the inferred type is closer to the expected one.
514 C.LetIn (n,s',ty,t'),
515 CicSubstitution.subst ~avoid_beta_redexes:true s' inferredty,
516 subst'',metasenv'',ugraph2
517 | C.Appl (he::((_::_) as tl)) ->
518 let he',hetype,subst',metasenv',ugraph1 =
519 type_of_aux subst metasenv context he ugraph
521 let tlbody_and_type,subst'',metasenv'',ugraph2 =
522 typeof_list subst' metasenv' context ugraph1 tl
524 let coerced_he,coerced_args,applty,subst''',metasenv''',ugraph3 =
525 eat_prods true subst'' metasenv'' context
526 he' hetype tlbody_and_type ugraph2
528 let newappl = (C.Appl (coerced_he::coerced_args)) in
529 avoid_double_coercion
530 context subst''' metasenv''' ugraph3 newappl applty
531 | C.Appl _ -> assert false
532 | C.Const (uri,exp_named_subst) ->
533 let exp_named_subst',subst',metasenv',ugraph1 =
534 check_exp_named_subst subst metasenv context
535 exp_named_subst ugraph in
536 let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
538 CicSubstitution.subst_vars exp_named_subst' ty_uri
540 C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
541 | C.MutInd (uri,i,exp_named_subst) ->
542 let exp_named_subst',subst',metasenv',ugraph1 =
543 check_exp_named_subst subst metasenv context
544 exp_named_subst ugraph
546 let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
548 CicSubstitution.subst_vars exp_named_subst' ty_uri in
549 C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
550 | C.MutConstruct (uri,i,j,exp_named_subst) ->
551 let exp_named_subst',subst',metasenv',ugraph1 =
552 check_exp_named_subst subst metasenv context
553 exp_named_subst ugraph
556 type_of_mutual_inductive_constr uri i j ugraph1
559 CicSubstitution.subst_vars exp_named_subst' ty_uri
561 C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
563 | C.MutCase (uri, i, outtype, term, pl) ->
564 (* first, get the inductive type (and noparams)
565 * in the environment *)
566 let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
567 let _ = CicTypeChecker.typecheck uri in
568 let obj,u = CicEnvironment.get_cooked_obj ugraph uri in
570 C.InductiveDefinition (l,expl_params,parsno,_) ->
571 List.nth l i , expl_params, parsno, u
573 enrich localization_tbl t
575 (lazy ("Unkown mutual inductive definition " ^
576 U.string_of_uri uri)))
578 if List.length constructors <> List.length pl then
579 enrich localization_tbl t
581 (lazy "Wrong number of cases")) ;
582 let rec count_prod t =
583 match CicReduction.whd ~subst context t with
584 C.Prod (_, _, t) -> 1 + (count_prod t)
587 let no_args = count_prod arity in
588 (* now, create a "generic" MutInd *)
589 let metasenv,left_args =
590 CicMkImplicit.n_fresh_metas metasenv subst context no_left_params
592 let metasenv,right_args =
593 let no_right_params = no_args - no_left_params in
594 if no_right_params < 0 then assert false
595 else CicMkImplicit.n_fresh_metas
596 metasenv subst context no_right_params
598 let metasenv,exp_named_subst =
599 CicMkImplicit.fresh_subst metasenv subst context expl_params in
602 C.MutInd (uri,i,exp_named_subst)
605 (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
607 (* check consistency with the actual type of term *)
608 let term',actual_type,subst,metasenv,ugraph1 =
609 type_of_aux subst metasenv context term ugraph in
610 let expected_type',_, subst, metasenv,ugraph2 =
611 type_of_aux subst metasenv context expected_type ugraph1
613 let actual_type = CicReduction.whd ~subst context actual_type in
614 let subst,metasenv,ugraph3 =
616 fo_unif_subst subst context metasenv
617 expected_type' actual_type ugraph2
620 enrich localization_tbl term' exn
623 CicMetaSubst.ppterm_in_context ~metasenv subst term'
624 context ^ " has type " ^
625 CicMetaSubst.ppterm_in_context ~metasenv subst actual_type
626 context ^ " but is here used with type " ^
627 CicMetaSubst.ppterm_in_context ~metasenv subst expected_type'
630 let rec instantiate_prod t =
634 match CicReduction.whd ~subst context t with
636 instantiate_prod (CicSubstitution.subst he t') tl
639 let arity_instantiated_with_left_args =
640 instantiate_prod arity left_args in
641 (* TODO: check if the sort elimination
642 * is allowed: [(I q1 ... qr)|B] *)
643 let (pl',_,outtypeinstances,subst,metasenv,ugraph4) =
645 (fun p (pl,j,outtypeinstances,subst,metasenv,ugraph) ->
647 if left_args = [] then
648 (C.MutConstruct (uri,i,j,exp_named_subst))
651 (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
653 let p',actual_type,subst,metasenv,ugraph1 =
654 type_of_aux subst metasenv context p ugraph
656 let constructor',expected_type, subst, metasenv,ugraph2 =
657 type_of_aux subst metasenv context constructor ugraph1
659 let outtypeinstance,subst,metasenv,ugraph3 =
661 check_branch 0 context metasenv subst
662 no_left_params actual_type constructor' expected_type
666 enrich localization_tbl constructor'
669 CicMetaSubst.ppterm_in_context metasenv subst p'
670 context ^ " has type " ^
671 CicMetaSubst.ppterm_in_context metasenv subst actual_type
672 context ^ " but is here used with type " ^
673 CicMetaSubst.ppterm_in_context metasenv subst expected_type
677 outtypeinstance::outtypeinstances,subst,metasenv,ugraph3))
678 pl ([],List.length pl,[],subst,metasenv,ugraph3)
681 (* we are left to check that the outype matches his instances.
682 The easy case is when the outype is specified, that amount
683 to a trivial check. Otherwise, we should guess a type from
687 let outtype,outtypety, subst, metasenv,ugraph4 =
688 type_of_aux subst metasenv context outtype ugraph4 in
691 (let candidate,ugraph5,metasenv,subst =
692 let exp_name_subst, metasenv =
694 CicEnvironment.get_cooked_obj CicUniv.oblivion_ugraph uri
696 let uris = CicUtil.params_of_obj o in
698 fun uri (acc,metasenv) ->
699 let metasenv',new_meta =
700 CicMkImplicit.mk_implicit metasenv subst context
703 CicMkImplicit.identity_relocation_list_for_metavariable
706 (uri, Cic.Meta(new_meta,irl))::acc, metasenv'
710 match left_args,right_args with
711 [],[] -> Cic.MutInd(uri, i, exp_name_subst)
713 let rec mk_right_args =
716 | n -> (Cic.Rel n)::(mk_right_args (n - 1))
718 let right_args_no = List.length right_args in
719 let lifted_left_args =
720 List.map (CicSubstitution.lift right_args_no) left_args
722 Cic.Appl (Cic.MutInd(uri,i,exp_name_subst)::
723 (lifted_left_args @ mk_right_args right_args_no))
726 FreshNamesGenerator.mk_fresh_name ~subst metasenv
727 context Cic.Anonymous ~typ:ty
729 match outtypeinstances with
731 let extended_context =
732 let rec add_right_args =
734 Cic.Prod (name,ty,t) ->
735 Some (name,Cic.Decl ty)::(add_right_args t)
738 (Some (fresh_name,Cic.Decl ty))::
740 (add_right_args arity_instantiated_with_left_args))@
743 let metasenv,new_meta =
744 CicMkImplicit.mk_implicit metasenv subst extended_context
747 CicMkImplicit.identity_relocation_list_for_metavariable
750 let rec add_lambdas b =
752 Cic.Prod (name,ty,t) ->
753 Cic.Lambda (name,ty,(add_lambdas b t))
754 | _ -> Cic.Lambda (fresh_name, ty, b)
757 add_lambdas (Cic.Meta (new_meta,irl))
758 arity_instantiated_with_left_args
760 (Some candidate),ugraph4,metasenv,subst
761 | (constructor_args_no,_,instance,_)::tl ->
763 let instance',subst,metasenv =
764 CicMetaSubst.delift_rels subst metasenv
765 constructor_args_no instance
767 let candidate,ugraph,metasenv,subst =
769 fun (candidate_oty,ugraph,metasenv,subst)
770 (constructor_args_no,_,instance,_) ->
771 match candidate_oty with
772 | None -> None,ugraph,metasenv,subst
775 let instance',subst,metasenv =
776 CicMetaSubst.delift_rels subst metasenv
777 constructor_args_no instance
779 let subst,metasenv,ugraph =
780 fo_unif_subst subst context metasenv
783 candidate_oty,ugraph,metasenv,subst
785 CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable
786 | RefineFailure _ | Uncertain _ ->
787 None,ugraph,metasenv,subst
788 ) (Some instance',ugraph4,metasenv,subst) tl
791 | None -> None, ugraph,metasenv,subst
793 let rec add_lambdas n b =
795 Cic.Prod (name,ty,t) ->
796 Cic.Lambda (name,ty,(add_lambdas (n + 1) b t))
798 Cic.Lambda (fresh_name, ty,
799 CicSubstitution.lift (n + 1) t)
802 (add_lambdas 0 t arity_instantiated_with_left_args),
803 ugraph,metasenv,subst
804 with CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
805 None,ugraph4,metasenv,subst
808 | None -> raise (Uncertain (lazy "can't solve an higher order unification problem"))
810 let subst,metasenv,ugraph =
812 fo_unif_subst subst context metasenv
813 candidate outtype ugraph5
815 exn -> assert false(* unification against a metavariable *)
817 C.MutCase (uri, i, outtype, term', pl'),
818 CicReduction.head_beta_reduce
819 (CicMetaSubst.apply_subst subst
820 (Cic.Appl (outtype::right_args@[term']))),
821 subst,metasenv,ugraph)
822 | _ -> (* easy case *)
823 let tlbody_and_type,subst,metasenv,ugraph4 =
824 typeof_list subst metasenv context ugraph4 (right_args @ [term'])
826 let _,_,_,subst,metasenv,ugraph4 =
827 eat_prods false subst metasenv context
828 outtype outtypety tlbody_and_type ugraph4
830 let _,_, subst, metasenv,ugraph5 =
831 type_of_aux subst metasenv context
832 (C.Appl ((outtype :: right_args) @ [term'])) ugraph4
834 let (subst,metasenv,ugraph6) =
836 (fun (subst,metasenv,ugraph)
837 p (constructor_args_no,context,instance,args)
842 CicSubstitution.lift constructor_args_no outtype
844 C.Appl (outtype'::args)
846 CicReduction.head_beta_reduce ~delta:false
847 ~upto:(List.length args) appl
850 fo_unif_subst subst context metasenv instance instance'
854 enrich localization_tbl p exn
857 CicMetaSubst.ppterm_in_context ~metasenv subst p
858 context ^ " has type " ^
859 CicMetaSubst.ppterm_in_context ~metasenv subst instance'
860 context ^ " but is here used with type " ^
861 CicMetaSubst.ppterm_in_context ~metasenv subst instance
863 (subst,metasenv,ugraph5) pl' outtypeinstances
865 C.MutCase (uri, i, outtype, term', pl'),
866 CicReduction.head_beta_reduce
867 (CicMetaSubst.apply_subst subst
868 (C.Appl(outtype::right_args@[term']))),
869 subst,metasenv,ugraph6)
871 let fl_ty',subst,metasenv,types,ugraph1,len =
873 (fun (fl,subst,metasenv,types,ugraph,len) (n,_,ty,_) ->
874 let ty',_,subst',metasenv',ugraph1 =
875 type_of_aux subst metasenv context ty ugraph
877 fl @ [ty'],subst',metasenv',
878 Some (C.Name n,(C.Decl (CicSubstitution.lift len ty')))
879 :: types, ugraph, len+1
880 ) ([],subst,metasenv,[],ugraph,0) fl
882 let context' = types@context in
883 let fl_bo',subst,metasenv,ugraph2 =
885 (fun (fl,subst,metasenv,ugraph) ((name,x,_,bo),ty) ->
886 let bo',ty_of_bo,subst,metasenv,ugraph1 =
887 type_of_aux subst metasenv context' bo ugraph in
888 let expected_ty = CicSubstitution.lift len ty in
889 let subst',metasenv',ugraph' =
891 fo_unif_subst subst context' metasenv
892 ty_of_bo expected_ty ugraph1
895 enrich localization_tbl bo exn
898 CicMetaSubst.ppterm_in_context ~metasenv subst bo
899 context' ^ " has type " ^
900 CicMetaSubst.ppterm_in_context ~metasenv subst ty_of_bo
901 context' ^ " but is here used with type " ^
902 CicMetaSubst.ppterm_in_context ~metasenv subst expected_ty
905 fl @ [bo'] , subst',metasenv',ugraph'
906 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
908 let ty = List.nth fl_ty' i in
909 (* now we have the new ty in fl_ty', the new bo in fl_bo',
910 * and we want the new fl with bo' and ty' injected in the right
913 let rec map3 f l1 l2 l3 =
916 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
919 let fl'' = map3 (fun ty' bo' (name,x,ty,bo) -> (name,x,ty',bo') )
922 C.Fix (i,fl''),ty,subst,metasenv,ugraph2
924 let fl_ty',subst,metasenv,types,ugraph1,len =
926 (fun (fl,subst,metasenv,types,ugraph,len) (n,ty,_) ->
927 let ty',_,subst',metasenv',ugraph1 =
928 type_of_aux subst metasenv context ty ugraph
930 fl @ [ty'],subst',metasenv',
931 Some (C.Name n,(C.Decl (CicSubstitution.lift len ty'))) ::
932 types, ugraph1, len+1
933 ) ([],subst,metasenv,[],ugraph,0) fl
935 let context' = types@context in
936 let fl_bo',subst,metasenv,ugraph2 =
938 (fun (fl,subst,metasenv,ugraph) ((name,_,bo),ty) ->
939 let bo',ty_of_bo,subst,metasenv,ugraph1 =
940 type_of_aux subst metasenv context' bo ugraph in
941 let expected_ty = CicSubstitution.lift len ty in
942 let subst',metasenv',ugraph' =
944 fo_unif_subst subst context' metasenv
945 ty_of_bo expected_ty ugraph1
948 enrich localization_tbl bo exn
951 CicMetaSubst.ppterm_in_context ~metasenv subst bo
952 context' ^ " has type " ^
953 CicMetaSubst.ppterm_in_context ~metasenv subst ty_of_bo
954 context' ^ " but is here used with type " ^
955 CicMetaSubst.ppterm_in_context ~metasenv subst expected_ty
958 fl @ [bo'],subst',metasenv',ugraph'
959 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
961 let ty = List.nth fl_ty' i in
962 (* now we have the new ty in fl_ty', the new bo in fl_bo',
963 * and we want the new fl with bo' and ty' injected in the right
966 let rec map3 f l1 l2 l3 =
969 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
972 let fl'' = map3 (fun ty' bo' (name,ty,bo) -> (name,ty',bo') )
975 C.CoFix (i,fl''),ty,subst,metasenv,ugraph2
977 relocalize localization_tbl t t';
980 (* check_metasenv_consistency checks that the "canonical" context of a
981 metavariable is consitent - up to relocation via the relocation list l -
982 with the actual context *)
983 and check_metasenv_consistency
984 metano subst metasenv context canonical_context l ugraph
986 let module C = Cic in
987 let module R = CicReduction in
988 let module S = CicSubstitution in
989 let lifted_canonical_context =
993 | (Some (n,C.Decl t))::tl ->
994 (Some (n,C.Decl (S.subst_meta l (S.lift i t))))::(aux (i+1) tl)
995 | None::tl -> None::(aux (i+1) tl)
996 | (Some (n,C.Def (t,ty)))::tl ->
1000 (S.subst_meta l (S.lift i t),
1001 S.subst_meta l (S.lift i ty)))) :: (aux (i+1) tl)
1003 aux 1 canonical_context
1007 (fun (l,subst,metasenv,ugraph) t ct ->
1010 l @ [None],subst,metasenv,ugraph
1011 | Some t,Some (_,C.Def (ct,_)) ->
1012 (*CSC: the following optimization is to avoid a possibly
1013 expensive reduction that can be easily avoided and
1014 that is quite frequent. However, this is better
1015 handled using levels to control reduction *)
1020 match List.nth context (n - 1) with
1021 Some (_,C.Def (te,_)) -> S.lift n te
1027 let subst',metasenv',ugraph' =
1029 (*prerr_endline ("poco geniale: nel caso di IRL basterebbe sapere che questo e'
1030 * il Rel corrispondente. Si puo' ottimizzare il caso t = rel.");*)
1031 fo_unif_subst subst context metasenv optimized_t ct ugraph
1032 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))))))
1034 l @ [Some t],subst',metasenv',ugraph'
1035 | Some t,Some (_,C.Decl ct) ->
1036 let t',inferredty,subst',metasenv',ugraph1 =
1037 type_of_aux subst metasenv context t ugraph
1039 let subst'',metasenv'',ugraph2 =
1042 subst' context metasenv' inferredty ct ugraph1
1043 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))))))
1045 l @ [Some t'], subst'',metasenv'',ugraph2
1047 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
1049 Invalid_argument _ ->
1053 "Not well typed metavariable instance %s: the length of the local context does not match the length of the canonical context %s"
1054 (CicMetaSubst.ppterm ~metasenv subst (Cic.Meta (metano, l)))
1055 (CicMetaSubst.ppcontext ~metasenv subst canonical_context))))
1057 and check_exp_named_subst metasubst metasenv context tl ugraph =
1058 let rec check_exp_named_subst_aux metasubst metasenv substs tl ugraph =
1060 [] -> [],metasubst,metasenv,ugraph
1062 let ty_uri,ugraph1 = type_of_variable uri ugraph in
1064 CicSubstitution.subst_vars substs ty_uri in
1065 (* CSC: why was this code here? it is wrong
1066 (match CicEnvironment.get_cooked_obj ~trust:false uri with
1067 Cic.Variable (_,Some bo,_,_) ->
1069 (RefineFailure (lazy
1070 "A variable with a body can not be explicit substituted"))
1071 | Cic.Variable (_,None,_,_) -> ()
1074 (RefineFailure (lazy
1075 ("Unkown variable definition " ^ UriManager.string_of_uri uri)))
1078 let t',typeoft,metasubst',metasenv',ugraph2 =
1079 type_of_aux metasubst metasenv context t ugraph1 in
1080 let subst = uri,t' in
1081 let metasubst'',metasenv'',ugraph3 =
1084 metasubst' context metasenv' typeoft typeofvar ugraph2
1086 raise (RefineFailure (lazy
1087 ("Wrong Explicit Named Substitution: " ^
1088 CicMetaSubst.ppterm metasenv' metasubst' typeoft ^
1089 " not unifiable with " ^
1090 CicMetaSubst.ppterm metasenv' metasubst' typeofvar)))
1092 (* FIXME: no mere tail recursive! *)
1093 let exp_name_subst, metasubst''', metasenv''', ugraph4 =
1094 check_exp_named_subst_aux
1095 metasubst'' metasenv'' (substs@[subst]) tl ugraph3
1097 ((uri,t')::exp_name_subst), metasubst''', metasenv''', ugraph4
1099 check_exp_named_subst_aux metasubst metasenv [] tl ugraph
1102 and sort_of_prod localization_tbl subst metasenv context (name,s) t (t1, t2)
1105 let module C = Cic in
1106 let context_for_t2 = (Some (name,C.Decl s))::context in
1107 let t1'' = CicReduction.whd ~subst context t1 in
1108 let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
1109 match (t1'', t2'') with
1110 | (C.Sort s1, C.Sort s2) when (s2 = C.Prop || s2 = C.Set) ->
1111 (* different than Coq manual!!! *)
1112 C.Sort s2,subst,metasenv,ugraph
1113 | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
1114 let t' = CicUniv.fresh() in
1116 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1117 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1118 C.Sort (C.Type t'),subst,metasenv,ugraph2
1120 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1121 | (C.Sort (C.CProp t1), C.Sort (C.CProp t2)) ->
1122 let t' = CicUniv.fresh() in
1124 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1125 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1126 C.Sort (C.CProp t'),subst,metasenv,ugraph2
1128 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1129 | (C.Sort (C.Type t1), C.Sort (C.CProp t2)) ->
1130 let t' = CicUniv.fresh() in
1132 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1133 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1134 C.Sort (C.CProp t'),subst,metasenv,ugraph2
1136 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1137 | (C.Sort (C.CProp t1), C.Sort (C.Type t2)) ->
1138 let t' = CicUniv.fresh() in
1140 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1141 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1142 C.Sort (C.Type t'),subst,metasenv,ugraph2
1144 CicUniv.UniverseInconsistency msg -> raise (RefineFailure msg))
1145 | (C.Sort _,C.Sort (C.Type t1)) ->
1146 C.Sort (C.Type t1),subst,metasenv,ugraph
1147 | (C.Sort _,C.Sort (C.CProp t1)) ->
1148 C.Sort (C.CProp t1),subst,metasenv,ugraph
1149 | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
1150 | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
1151 (* TODO how can we force the meta to become a sort? If we don't we
1152 * break the invariant that refine produce only well typed terms *)
1153 (* TODO if we check the non meta term and if it is a sort then we
1154 * are likely to know the exact value of the result e.g. if the rhs
1155 * is a Sort (Prop | Set | CProp) then the result is the rhs *)
1156 let (metasenv,idx) =
1157 CicMkImplicit.mk_implicit_sort metasenv subst in
1158 let (subst, metasenv,ugraph1) =
1160 fo_unif_subst subst context_for_t2 metasenv
1161 (C.Meta (idx,[])) t2'' ugraph
1162 with _ -> assert false (* unification against a metavariable *)
1164 t2'',subst,metasenv,ugraph1
1167 enrich localization_tbl s
1171 "%s is supposed to be a type, but its type is %s"
1172 (CicMetaSubst.ppterm_in_context ~metasenv subst t context)
1173 (CicMetaSubst.ppterm_in_context ~metasenv subst t2 context))))
1175 enrich localization_tbl t
1179 "%s is supposed to be a type, but its type is %s"
1180 (CicMetaSubst.ppterm_in_context ~metasenv subst s context)
1181 (CicMetaSubst.ppterm_in_context ~metasenv subst t1 context))))
1183 and avoid_double_coercion context subst metasenv ugraph t ty =
1184 if not !pack_coercions then
1185 t,ty,subst,metasenv,ugraph
1187 let b, c1, c2, head, c1_c2_implicit = is_a_double_coercion t in
1189 let source_carr = CoercGraph.source_of c2 in
1190 let tgt_carr = CicMetaSubst.apply_subst subst ty in
1191 (match CoercGraph.look_for_coercion metasenv subst context source_carr tgt_carr
1193 | CoercGraph.SomeCoercion candidates ->
1195 HExtlib.list_findopt
1196 (function (metasenv,last,c) ->
1198 | c when not (CoercGraph.is_composite c) ->
1199 debug_print (lazy ("\nNot a composite.."^CicPp.ppterm c));
1202 let subst,metasenv,ugraph =
1203 fo_unif_subst subst context metasenv last head ugraph in
1204 debug_print (lazy ("\nprovo" ^ CicPp.ppterm c));
1209 CicPp.ppterm t ^ " ==> " ^ CicPp.ppterm c));
1210 let newt,_,subst,metasenv,ugraph =
1211 type_of_aux subst metasenv context c ugraph in
1212 debug_print (lazy "tipa...");
1213 let subst, metasenv, ugraph =
1214 (* COME MAI C'ERA UN IF su !pack_coercions ??? *)
1215 fo_unif_subst subst context metasenv newt t ugraph
1217 debug_print (lazy "unifica...");
1218 Some (newt, ty, subst, metasenv, ugraph)
1220 | RefineFailure s | Uncertain s when not !pack_coercions->
1221 debug_print s; debug_print (lazy "stop\n");None
1222 | RefineFailure s | Uncertain s ->
1223 debug_print s;debug_print (lazy "goon\n");
1225 let old_pack_coercions = !pack_coercions in
1226 pack_coercions := false; (* to avoid diverging *)
1227 let refined_c1_c2_implicit,ty,subst,metasenv,ugraph =
1228 type_of_aux subst metasenv context c1_c2_implicit ugraph
1230 pack_coercions := old_pack_coercions;
1232 is_a_double_coercion refined_c1_c2_implicit
1238 match refined_c1_c2_implicit with
1239 | Cic.Appl l -> HExtlib.list_last l
1242 let subst, metasenv, ugraph =
1243 try fo_unif_subst subst context metasenv
1245 with RefineFailure s| Uncertain s->
1246 debug_print s;assert false
1248 let subst, metasenv, ugraph =
1249 fo_unif_subst subst context metasenv
1250 refined_c1_c2_implicit t ugraph
1252 Some (refined_c1_c2_implicit,ty,subst,metasenv,ugraph)
1254 | RefineFailure s | Uncertain s ->
1255 pack_coercions := true;debug_print s;None
1256 | exn -> pack_coercions := true; raise exn))
1259 (match selected with
1263 (lazy ("#### Coercion not packed: " ^ CicPp.ppterm t));
1264 t, ty, subst, metasenv, ugraph)
1265 | _ -> t, ty, subst, metasenv, ugraph)
1267 t, ty, subst, metasenv, ugraph
1269 and typeof_list subst metasenv context ugraph l =
1270 let tlbody_and_type,subst,metasenv,ugraph =
1272 (fun x (res,subst,metasenv,ugraph) ->
1273 let x',ty,subst',metasenv',ugraph1 =
1274 type_of_aux subst metasenv context x ugraph
1276 (x', ty)::res,subst',metasenv',ugraph1
1277 ) l ([],subst,metasenv,ugraph)
1279 tlbody_and_type,subst,metasenv,ugraph
1282 allow_coercions subst metasenv context he hetype args_bo_and_ty ugraph
1284 (* given he:hety, gives beack all (c he) such that (c e):?->? *)
1285 let fix_arity n metasenv context subst he hetype ugraph =
1286 let hetype = CicMetaSubst.apply_subst subst hetype in
1287 (* instead of a dummy functional type we may create the real product
1288 * using args_bo_and_ty, but since coercions lookup ignores the
1289 * actual ariety we opt for the simple solution *)
1290 let fty = Cic.Prod(Cic.Anonymous, Cic.Sort Cic.Prop, Cic.Sort Cic.Prop) in
1291 match CoercGraph.look_for_coercion metasenv subst context hetype fty with
1292 | CoercGraph.NoCoercion -> []
1293 | CoercGraph.NotHandled ->
1294 raise (MoreArgsThanExpected (n,Uncertain (lazy "")))
1295 | CoercGraph.SomeCoercionToTgt candidates
1296 | CoercGraph.SomeCoercion candidates ->
1298 (fun (metasenv,last,coerc) ->
1300 CicMetaSubst.ppterm_in_context ~metasenv subst t context in
1302 let subst,metasenv,ugraph =
1303 fo_unif_subst subst context metasenv last he ugraph in
1304 debug_print (lazy ("New head: "^ pp coerc));
1306 CicTypeChecker.type_of_aux' ~subst metasenv context coerc
1309 debug_print (lazy (" has type: "^ pp tty));
1310 Some (coerc,tty,subst,metasenv,ugraph)
1312 | Uncertain _ | RefineFailure _
1313 | HExtlib.Localized (_,Uncertain _)
1314 | HExtlib.Localized (_,RefineFailure _) -> None
1315 | exn -> assert false)
1318 (* aux function to process the type of the head and the args in parallel *)
1319 let rec eat_prods_and_args metasenv subst context he hetype ugraph newargs =
1321 | [] -> newargs,subst,metasenv,he,hetype,ugraph
1322 | (hete, hety)::tl as args ->
1323 match (CicReduction.whd ~subst context hetype) with
1324 | Cic.Prod (n,s,t) ->
1325 let arg,subst,metasenv,ugraph =
1326 coerce_to_something allow_coercions localization_tbl
1327 hete hety s subst metasenv context ugraph in
1329 metasenv subst context he (CicSubstitution.subst (fst arg) t)
1330 ugraph (newargs@[arg]) tl
1333 match he, newargs with
1335 | Cic.Appl l, _ -> Cic.Appl (l@List.map fst newargs)
1336 | _ -> Cic.Appl (he::List.map fst newargs)
1338 (*{{{*) debug_print (lazy
1340 CicMetaSubst.ppterm_in_context ~metasenv subst x context in
1341 "Fixing arity of: "^ pp he ^ "\n that has type: "^ pp hetype^
1342 "\n but is applyed to: " ^ String.concat ";"
1343 (List.map (fun (t,_)->pp t) args_bo_and_ty)); (*}}}*)
1344 let error = ref None in
1345 let possible_fixes =
1346 fix_arity (List.length args) metasenv context subst he hetype
1349 HExtlib.list_findopt
1350 (fun (he,hetype,subst,metasenv,ugraph) ->
1351 (* {{{ *)debug_print (lazy ("Try fix: "^
1352 CicMetaSubst.ppterm_in_context ~metasenv subst he context));
1353 debug_print (lazy (" of type: "^
1354 CicMetaSubst.ppterm_in_context
1355 ~metasenv subst hetype context)); (* }}} *)
1357 Some (eat_prods_and_args
1358 metasenv subst context he hetype ugraph [] args)
1360 | RefineFailure _ | Uncertain _
1361 | HExtlib.Localized (_,RefineFailure _)
1362 | HExtlib.Localized (_,Uncertain _) as exn ->
1363 error := Some exn; None)
1371 (MoreArgsThanExpected
1372 (List.length args, RefineFailure (lazy "")))
1373 | Some exn -> raise exn
1375 (* first we check if we are in the simple case of a meta closed term *)
1376 let subst,metasenv,ugraph1,hetype',he,args_bo_and_ty =
1377 if CicUtil.is_meta_closed (CicMetaSubst.apply_subst subst hetype) then
1378 (* this optimization is to postpone fix_arity (the most common case)*)
1379 subst,metasenv,ugraph,hetype,he,args_bo_and_ty
1381 (* this (says CSC) is also useful to infer dependent types *)
1382 let pristinemenv = metasenv in
1383 let metasenv,hetype' =
1384 mk_prod_of_metas metasenv context subst args_bo_and_ty
1387 let subst,metasenv,ugraph =
1388 fo_unif_subst_eat_prods subst context metasenv hetype hetype' ugraph
1390 subst,metasenv,ugraph,hetype',he,args_bo_and_ty
1391 with RefineFailure _ | Uncertain _ ->
1392 subst,pristinemenv,ugraph,hetype,he,args_bo_and_ty
1394 let coerced_args,subst,metasenv,he,t,ugraph =
1397 metasenv subst context he hetype' ugraph1 [] args_bo_and_ty
1399 MoreArgsThanExpected (residuals,exn) ->
1400 more_args_than_expected localization_tbl metasenv
1401 subst he context hetype' residuals args_bo_and_ty exn
1403 he,(List.map fst coerced_args),t,subst,metasenv,ugraph
1405 and coerce_to_something
1406 allow_coercions localization_tbl t infty expty subst metasenv context ugraph
1408 let module CS = CicSubstitution in
1409 let module CR = CicReduction in
1410 let cs_subst = CS.subst ~avoid_beta_redexes:true in
1411 let coerce_atom_to_something t infty expty subst metasenv context ugraph =
1412 debug_print (lazy ("COERCE_ATOM_TO_SOMETHING"));
1414 CoercGraph.look_for_coercion metasenv subst context infty expty
1417 | CoercGraph.NoCoercion
1418 | CoercGraph.SomeCoercionToTgt _ -> raise (RefineFailure (lazy
1419 "coerce_atom_to_something fails since no coercions found"))
1420 | CoercGraph.NotHandled when
1421 not (CicUtil.is_meta_closed infty) ||
1422 not (CicUtil.is_meta_closed expty) -> raise (Uncertain (lazy
1423 "coerce_atom_to_something fails since carriers have metas"))
1424 | CoercGraph.NotHandled -> raise (RefineFailure (lazy
1425 "coerce_atom_to_something fails since no coercions found"))
1426 | CoercGraph.SomeCoercion candidates ->
1427 debug_print (lazy (string_of_int (List.length candidates) ^
1428 " candidates found"));
1429 let uncertain = ref false in
1433 (fun (metasenv,last,c) ->
1435 (* {{{ *) debug_print (lazy ("FO_UNIF_SUBST: " ^
1436 CicMetaSubst.ppterm_in_context ~metasenv subst last context ^
1438 CicMetaSubst.ppterm_in_context ~metasenv subst t context ^
1439 "####" ^ CicMetaSubst.ppterm_in_context ~metasenv subst c
1441 debug_print (lazy ("FO_UNIF_SUBST: " ^
1442 CicPp.ppterm last ^ " <==> " ^ CicPp.ppterm t)); (* }}} *)
1443 let subst,metasenv,ugraph =
1444 fo_unif_subst subst context metasenv last t ugraph
1446 let newt,newhety,subst,metasenv,ugraph =
1447 type_of_aux subst metasenv context c ugraph in
1448 let newt, newty, subst, metasenv, ugraph =
1449 avoid_double_coercion context subst metasenv ugraph newt expty
1451 let subst,metasenv,ugraph =
1452 fo_unif_subst subst context metasenv newhety expty ugraph in
1453 Some ((newt,newty), subst, metasenv, ugraph)
1455 | Uncertain _ -> uncertain := true; None
1456 | RefineFailure _ -> None)
1461 (fun (_,_,m1,_) (_,_,m2,_) -> List.length m1 - List.length m2)
1469 | None when !uncertain -> raise (Uncertain (lazy "coerce_atom fails"))
1470 | None -> raise (RefineFailure (lazy "coerce_atom fails"))
1472 let rec coerce_to_something_aux
1473 t infty expty subst metasenv context ugraph
1476 let subst, metasenv, ugraph =
1477 fo_unif_subst subst context metasenv infty expty ugraph
1479 (t, expty), subst, metasenv, ugraph
1480 with (Uncertain _ | RefineFailure _ as exn)
1481 when allow_coercions && !insert_coercions ->
1482 let whd = CicReduction.whd ~delta:false in
1483 let clean t s c = whd c (CicMetaSubst.apply_subst s t) in
1484 let infty = clean infty subst context in
1485 let expty = clean expty subst context in
1486 let t = clean t subst context in
1487 (*{{{*) debug_print (lazy ("COERCE_TO_SOMETHING: " ^
1488 CicMetaSubst.ppterm_in_context ~metasenv subst t context ^ " : " ^
1489 CicMetaSubst.ppterm_in_context ~metasenv subst infty context ^" ==> "^
1490 CicMetaSubst.ppterm_in_context ~metasenv subst expty context));(*}}}*)
1491 let (coerced,_),subst,metasenv,_ as result =
1492 match infty, expty, t with
1493 | Cic.Prod (nameprod,src,ty), Cic.Prod (_,src2,ty2),Cic.Fix (n,fl) ->
1494 (*{{{*) debug_print (lazy "FIX");
1496 [name,i,_(* infty *),bo] ->
1498 Some (Cic.Name name,Cic.Decl expty)::context in
1499 let (rel1, _), subst, metasenv, ugraph =
1500 coerce_to_something_aux (Cic.Rel 1)
1501 (CS.lift 1 expty) (CS.lift 1 infty) subst
1502 metasenv context_bo ugraph in
1503 let bo = cs_subst rel1 (CS.lift_from 2 1 bo) in
1504 let (bo,_), subst, metasenv, ugraph =
1505 coerce_to_something_aux bo (CS.lift 1 infty) (CS.lift 1
1507 metasenv context_bo ugraph
1509 (Cic.Fix (n,[name,i,expty,bo]),expty),subst,metasenv,ugraph
1510 | _ -> assert false (* not implemented yet *)) (*}}}*)
1511 | _,_, Cic.MutCase (uri,tyno,outty,m,pl) ->
1512 (*{{{*) debug_print (lazy "CASE");
1513 (* {{{ helper functions *)
1514 let get_cl_and_left_p uri tyno outty ugraph =
1515 match CicEnvironment.get_obj ugraph uri with
1516 | Cic.InductiveDefinition (tl, _, leftno, _),ugraph ->
1519 match CicReduction.whd ~delta:false ctx t with
1520 | Cic.Prod (name,src,tgt) ->
1521 let ctx = Some (name, Cic.Decl src) :: ctx in
1527 let rec skip_lambda_delifting t n =
1530 | Cic.Lambda (_,_,t),n ->
1531 skip_lambda_delifting
1532 (CS.subst (Cic.Implicit None) t) (n - 1)
1535 let get_l_r_p n = function
1536 | Cic.Lambda (_,Cic.MutInd _,_) -> [],[]
1537 | Cic.Lambda (_,Cic.Appl (Cic.MutInd _ :: args),_) ->
1538 HExtlib.split_nth n args
1541 let _, _, ty, cl = List.nth tl tyno in
1542 let pis = count_pis ty in
1543 let rno = pis - leftno in
1544 let t = skip_lambda_delifting outty rno in
1545 let left_p, _ = get_l_r_p leftno t in
1546 let instantiale_with_left cl =
1550 (fun t p -> match t with
1551 | Cic.Prod (_,_,t) ->
1557 let cl = instantiale_with_left (List.map snd cl) in
1558 cl, left_p, leftno, rno, ugraph
1561 let rec keep_lambdas_and_put_expty ctx t bo right_p matched n =
1564 let rec mkr n = function
1565 | [] -> [] | _::tl -> Cic.Rel n :: mkr (n+1) tl
1568 CicReplace.replace_lifting
1569 ~equality:(fun _ -> CicUtil.alpha_equivalence)
1571 ~what:(matched::right_p)
1572 ~with_what:(Cic.Rel 1::List.rev (mkr 2 right_p))
1576 | Cic.Lambda (name, src, tgt),_ ->
1577 Cic.Lambda (name, src,
1578 keep_lambdas_and_put_expty
1579 (Some (name, Cic.Decl src)::ctx) tgt (CS.lift 1 bo)
1580 (List.map (CS.lift 1) right_p) (CS.lift 1 matched) (n-1))
1583 let eq_uri, eq, eq_refl =
1584 match LibraryObjects.eq_URI () with
1585 | None -> HLog.warn "no default equality"; raise exn
1586 | Some u -> u, Cic.MutInd(u,0,[]), Cic.MutConstruct (u,0,1,[])
1589 metasenv subst context uri tyno cty outty mty m leftno i
1591 let rec aux context outty par k mty m = function
1592 | Cic.Prod (name, src, tgt) ->
1595 (Some (name, Cic.Decl src) :: context)
1596 (CS.lift 1 outty) (Cic.Rel k::par) (k+1)
1597 (CS.lift 1 mty) (CS.lift 1 m) tgt
1599 Cic.Prod (name, src, t), k
1602 let k = Cic.MutConstruct (uri,tyno,i,[]) in
1603 if par <> [] then Cic.Appl (k::par) else k
1605 Cic.Prod (Cic.Name "p",
1606 Cic.Appl [eq; mty; m; k],
1608 (CR.head_beta_reduce ~delta:false
1609 (Cic.Appl [outty;k])))),k
1610 | Cic.Appl (Cic.MutInd _::pl) ->
1611 let left_p,right_p = HExtlib.split_nth leftno pl in
1612 let has_rights = right_p <> [] in
1614 let k = Cic.MutConstruct (uri,tyno,i,[]) in
1615 Cic.Appl (k::left_p@par)
1619 CicTypeChecker.type_of_aux' ~subst metasenv context k
1620 CicUniv.oblivion_ugraph
1622 | Cic.Appl (Cic.MutInd _::args),_ ->
1623 snd (HExtlib.split_nth leftno args)
1625 with CicTypeChecker.TypeCheckerFailure _-> assert false
1628 CR.head_beta_reduce ~delta:false
1629 (Cic.Appl (outty ::right_p @ [k])),k
1631 Cic.Prod (Cic.Name "p",
1632 Cic.Appl [eq; mty; m; k],
1634 (CR.head_beta_reduce ~delta:false
1635 (Cic.Appl (outty ::right_p @ [k]))))),k
1638 aux context outty [] 1 mty m cty
1640 let add_lambda_for_refl_m pbo rno mty m k cty =
1641 (* k lives in the right context *)
1642 if rno <> 0 then pbo else
1643 let rec aux mty m = function
1644 | Cic.Lambda (name,src,bo), Cic.Prod (_,_,ty) ->
1645 Cic.Lambda (name,src,
1646 (aux (CS.lift 1 mty) (CS.lift 1 m) (bo,ty)))
1648 Cic.Lambda (Cic.Name "p",
1649 Cic.Appl [eq; mty; m; k],CS.lift 1 t)
1653 let add_pi_for_refl_m new_outty mty m rno =
1654 if rno <> 0 then new_outty else
1655 let rec aux m mty = function
1656 | Cic.Lambda (name, src, tgt) ->
1657 Cic.Lambda (name, src,
1658 aux (CS.lift 1 m) (CS.lift 1 mty) tgt)
1661 (Cic.Anonymous, Cic.Appl [eq;mty;m;Cic.Rel 1],
1665 in (* }}} end helper functions *)
1666 (* constructors types with left params already instantiated *)
1667 let outty = CicMetaSubst.apply_subst subst outty in
1668 let cl, left_p, leftno,rno,ugraph =
1669 get_cl_and_left_p uri tyno outty ugraph
1674 CicTypeChecker.type_of_aux' ~subst metasenv context m
1675 CicUniv.oblivion_ugraph
1677 | (Cic.MutInd _ | Cic.Meta _) as mty,_ -> [], mty
1678 | Cic.Appl ((Cic.MutInd _|Cic.Meta _)::args) as mty,_ ->
1679 snd (HExtlib.split_nth leftno args), mty
1681 with CicTypeChecker.TypeCheckerFailure _ ->
1682 raise (AssertFailure(lazy "already ill-typed matched term"))
1685 keep_lambdas_and_put_expty context outty expty right_p m (rno+1)
1688 (lazy ("CASE: new_outty: " ^ CicMetaSubst.ppterm_in_context
1689 ~metasenv subst new_outty context));
1690 let _,pl,subst,metasenv,ugraph =
1692 (fun cty pbo (i, acc, s, menv, ugraph) ->
1693 (* Pi k_par, (Pi H:m=(K_i left_par k_par)),
1694 * (new_)outty right_par (K_i left_par k_par) *)
1696 add_params menv s context uri tyno
1697 cty outty mty m leftno i in
1699 (lazy ("CASE: infty_pbo: "^CicMetaSubst.ppterm_in_context
1700 ~metasenv subst infty_pbo context));
1701 let expty_pbo, k = (* k is (K_i left_par k_par) *)
1702 add_params menv s context uri tyno
1703 cty new_outty mty m leftno i in
1705 (lazy ("CASE: expty_pbo: "^CicMetaSubst.ppterm_in_context
1706 ~metasenv subst expty_pbo context));
1707 let pbo = add_lambda_for_refl_m pbo rno mty m k cty in
1709 (lazy ("CASE: pbo: " ^ CicMetaSubst.ppterm_in_context
1710 ~metasenv subst pbo context));
1711 let (pbo, _), subst, metasenv, ugraph =
1712 coerce_to_something_aux pbo infty_pbo expty_pbo
1713 s menv context ugraph
1716 (lazy ("CASE: pbo: " ^ CicMetaSubst.ppterm_in_context
1717 ~metasenv subst pbo context));
1718 (i-1, pbo::acc, subst, metasenv, ugraph))
1719 cl pl (List.length pl, [], subst, metasenv, ugraph)
1721 let new_outty = add_pi_for_refl_m new_outty mty m rno in
1723 (lazy ("CASE: new_outty: " ^ CicMetaSubst.ppterm_in_context
1724 ~metasenv subst new_outty context));
1727 let refl_m=Cic.Appl[eq_refl;mty;m]in
1728 Cic.Appl [Cic.MutCase(uri,tyno,new_outty,m,pl);refl_m]
1730 Cic.MutCase(uri,tyno,new_outty,m,pl)
1732 (t, expty), subst, metasenv, ugraph (*}}}*)
1733 | Cic.Prod (nameprod, src, ty),Cic.Prod (_, src2, ty2), _ ->
1734 (*{{{*) debug_print (lazy "LAM");
1736 FreshNamesGenerator.mk_fresh_name
1737 ~subst metasenv context ~typ:src2 Cic.Anonymous
1739 let context_src2 = (Some (name_con, Cic.Decl src2) :: context) in
1740 (* contravariant part: the argument of f:src->ty *)
1741 let (rel1, _), subst, metasenv, ugraph =
1742 coerce_to_something_aux
1743 (Cic.Rel 1) (CS.lift 1 src2)
1744 (CS.lift 1 src) subst metasenv context_src2 ugraph
1746 (* covariant part: the result of f(c x); x:src2; (c x):src *)
1749 | Cic.Lambda (n,_,bo) -> n, cs_subst rel1 (CS.lift_from 2 1 bo)
1750 | _ -> name_con, Cic.Appl[CS.lift 1 t;rel1]
1752 (* we fix the possible dependency problem in the source ty *)
1753 let ty = cs_subst rel1 (CS.lift_from 2 1 ty) in
1754 let (bo, _), subst, metasenv, ugraph =
1755 coerce_to_something_aux
1756 bo ty ty2 subst metasenv context_src2 ugraph
1758 let coerced = Cic.Lambda (name_t,src2, bo) in
1759 (coerced, expty), subst, metasenv, ugraph (*}}}*)
1761 (*{{{*)debug_print (lazy ("ATOM: "^CicMetaSubst.ppterm_in_context
1762 ~metasenv subst infty context ^ " ==> " ^
1763 CicMetaSubst.ppterm_in_context ~metasenv subst expty context));
1764 coerce_atom_to_something
1765 t infty expty subst metasenv context ugraph (*}}}*)
1767 debug_print (lazy ("COERCE TO SOMETHING END: "^
1768 CicMetaSubst.ppterm_in_context ~metasenv subst coerced context));
1772 coerce_to_something_aux t infty expty subst metasenv context ugraph
1773 with Uncertain _ | RefineFailure _ as exn ->
1776 CicMetaSubst.ppterm_in_context metasenv subst t context ^
1777 " has type " ^ CicMetaSubst.ppterm_in_context metasenv subst
1778 infty context ^ " but is here used with type " ^
1779 CicMetaSubst.ppterm_in_context metasenv subst expty context)
1781 enrich localization_tbl ~f t exn
1783 and coerce_to_sort localization_tbl t infty subst context metasenv uragph =
1784 match CicReduction.whd ~delta:false ~subst context infty with
1785 | Cic.Meta _ | Cic.Sort _ ->
1786 t,infty, subst, metasenv, ugraph
1788 debug_print (lazy ("COERCE TO SORT: "^CicMetaSubst.ppterm_in_context
1789 ~metasenv subst src context));
1790 let tgt = Cic.Sort (Cic.Type (CicUniv.fresh())) in
1792 let (t, ty_t), subst, metasenv, ugraph =
1793 coerce_to_something true
1794 localization_tbl t src tgt subst metasenv context ugraph
1796 debug_print (lazy ("COERCE TO SORT END: "^
1797 CicMetaSubst.ppterm_in_context ~metasenv subst t context));
1798 t, ty_t, subst, metasenv, ugraph
1799 with HExtlib.Localized (_, exn) ->
1801 lazy ("(7)The term " ^
1802 CicMetaSubst.ppterm_in_context ~metasenv subst t context
1803 ^ " is not a type since it has type " ^
1804 CicMetaSubst.ppterm_in_context ~metasenv subst src context
1805 ^ " that is not a sort")
1807 enrich localization_tbl ~f t exn
1810 (* eat prods ends here! *)
1812 let t',ty,subst',metasenv',ugraph1 =
1813 type_of_aux [] metasenv context t ugraph
1815 let substituted_t = CicMetaSubst.apply_subst subst' t' in
1816 let substituted_ty = CicMetaSubst.apply_subst subst' ty in
1817 (* Andrea: ho rimesso qui l'applicazione della subst al
1818 metasenv dopo che ho droppato l'invariante che il metsaenv
1819 e' sempre istanziato *)
1820 let substituted_metasenv =
1821 CicMetaSubst.apply_subst_metasenv subst' metasenv' in
1823 (* substituted_t,substituted_ty,substituted_metasenv *)
1824 (* ANDREA: spostare tutta questa robaccia da un altra parte *)
1826 if clean_dummy_dependent_types then
1827 FreshNamesGenerator.clean_dummy_dependent_types substituted_t
1828 else substituted_t in
1830 if clean_dummy_dependent_types then
1831 FreshNamesGenerator.clean_dummy_dependent_types substituted_ty
1832 else substituted_ty in
1833 let cleaned_metasenv =
1834 if clean_dummy_dependent_types then
1836 (function (n,context,ty) ->
1837 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty in
1842 | Some (n, Cic.Decl t) ->
1844 Cic.Decl (FreshNamesGenerator.clean_dummy_dependent_types t))
1845 | Some (n, Cic.Def (bo,ty)) ->
1846 let bo' = FreshNamesGenerator.clean_dummy_dependent_types bo in
1847 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty
1849 Some (n, Cic.Def (bo',ty'))
1853 ) substituted_metasenv
1855 substituted_metasenv
1857 (cleaned_t,cleaned_ty,cleaned_metasenv,ugraph1)
1860 let undebrujin uri typesno tys t =
1863 (fun (name,_,_,_) (i,t) ->
1864 (* here the explicit_named_substituion is assumed to be *)
1866 let t' = Cic.MutInd (uri,i,[]) in
1867 let t = CicSubstitution.subst t' t in
1869 ) tys (typesno - 1,t))
1871 let map_first_n n start f g l =
1872 let rec aux acc k l =
1875 | [] -> raise (Invalid_argument "map_first_n")
1876 | hd :: tl -> f hd k (aux acc (k+1) tl)
1882 (*CSC: this is a very rough approximation; to be finished *)
1883 let are_all_occurrences_positive metasenv ugraph uri tys leftno =
1884 let subst,metasenv,ugraph,tys =
1886 (fun (name,ind,arity,cl) (subst,metasenv,ugraph,acc) ->
1887 let subst,metasenv,ugraph,cl =
1889 (fun (name,ty) (subst,metasenv,ugraph,acc) ->
1890 let rec aux ctx k subst = function
1891 | Cic.Appl((Cic.MutInd (uri',_,_)as hd)::tl) when uri = uri'->
1892 let subst,metasenv,ugraph,tl =
1894 (subst,metasenv,ugraph,[])
1895 (fun t n (subst,metasenv,ugraph,acc) ->
1896 let subst,metasenv,ugraph =
1898 subst ctx metasenv t (Cic.Rel (k-n)) ugraph
1900 subst,metasenv,ugraph,(t::acc))
1901 (fun (s,m,g,acc) tl -> assert(acc=[]);(s,m,g,tl))
1904 subst,metasenv,ugraph,(Cic.Appl (hd::tl))
1905 | Cic.MutInd(uri',_,_) as t when uri = uri'->
1906 subst,metasenv,ugraph,t
1907 | Cic.Prod (name,s,t) ->
1908 let ctx = (Some (name,Cic.Decl s))::ctx in
1909 let subst,metasenv,ugraph,t = aux ctx (k+1) subst t in
1910 subst,metasenv,ugraph,Cic.Prod (name,s,t)
1914 (lazy "not well formed constructor type"))
1916 let subst,metasenv,ugraph,ty = aux [] 0 subst ty in
1917 subst,metasenv,ugraph,(name,ty) :: acc)
1918 cl (subst,metasenv,ugraph,[])
1920 subst,metasenv,ugraph,(name,ind,arity,cl)::acc)
1921 tys ([],metasenv,ugraph,[])
1923 let substituted_tys =
1925 (fun (name,ind,arity,cl) ->
1927 List.map (fun (name, ty) -> name,CicMetaSubst.apply_subst subst ty) cl
1929 name,ind,CicMetaSubst.apply_subst subst arity,cl)
1932 metasenv,ugraph,substituted_tys
1934 let typecheck metasenv uri obj ~localization_tbl =
1935 let ugraph = CicUniv.oblivion_ugraph in
1937 Cic.Constant (name,Some bo,ty,args,attrs) ->
1938 (* CSC: ugly code. Here I need to retrieve in advance the loc of bo
1939 since type_of_aux' destroys localization information (which are
1940 preserved by type_of_aux *)
1943 Cic.CicHash.find localization_tbl bo
1945 HLog.debug ("!!! NOT LOCALIZED: " ^ CicPp.ppterm bo);
1947 let bo',boty,metasenv,ugraph =
1948 type_of_aux' ~localization_tbl metasenv [] bo ugraph in
1949 let ty',_,metasenv,ugraph =
1950 type_of_aux' ~localization_tbl metasenv [] ty ugraph in
1951 let subst,metasenv,ugraph =
1953 fo_unif_subst [] [] metasenv boty ty' ugraph
1956 | Uncertain _ as exn ->
1959 CicMetaSubst.ppterm_in_context ~metasenv [] bo' [] ^
1961 CicMetaSubst.ppterm_in_context ~metasenv [] boty [] ^
1962 " but is here used with type " ^
1963 CicMetaSubst.ppterm_in_context ~metasenv [] ty' [])
1967 RefineFailure _ -> RefineFailure msg
1968 | Uncertain _ -> Uncertain msg
1971 raise (HExtlib.Localized (loc exn',exn'))
1973 let bo' = CicMetaSubst.apply_subst subst bo' in
1974 let ty' = CicMetaSubst.apply_subst subst ty' in
1975 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1976 Cic.Constant (name,Some bo',ty',args,attrs),metasenv,ugraph
1977 | Cic.Constant (name,None,ty,args,attrs) ->
1978 let ty',_,metasenv,ugraph =
1979 type_of_aux' ~localization_tbl metasenv [] ty ugraph
1981 Cic.Constant (name,None,ty',args,attrs),metasenv,ugraph
1982 | Cic.CurrentProof (name,metasenv',bo,ty,args,attrs) ->
1983 assert (metasenv' = metasenv);
1984 (* Here we do not check the metasenv for correctness *)
1985 let bo',boty,metasenv,ugraph =
1986 type_of_aux' ~localization_tbl metasenv [] bo ugraph in
1987 let ty',sort,metasenv,ugraph =
1988 type_of_aux' ~localization_tbl metasenv [] ty ugraph in
1992 (* instead of raising Uncertain, let's hope that the meta will become
1995 | _ -> raise (RefineFailure (lazy "The term provided is not a type"))
1997 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1998 let bo' = CicMetaSubst.apply_subst subst bo' in
1999 let ty' = CicMetaSubst.apply_subst subst ty' in
2000 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
2001 Cic.CurrentProof (name,metasenv,bo',ty',args,attrs),metasenv,ugraph
2002 | Cic.Variable _ -> assert false (* not implemented *)
2003 | Cic.InductiveDefinition (tys,args,paramsno,attrs) ->
2004 (*CSC: this code is greately simplified and many many checks are missing *)
2005 (*CSC: e.g. the constructors are not required to build their own types, *)
2006 (*CSC: the arities are not required to have as type a sort, etc. *)
2007 let uri = match uri with Some uri -> uri | None -> assert false in
2008 let typesno = List.length tys in
2009 (* first phase: we fix only the types *)
2010 let metasenv,ugraph,tys =
2012 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
2013 let ty',_,metasenv,ugraph =
2014 (* clean_dummy_dependent_types: false to avoid cleaning the names
2015 of the left products, that must be identical to those of the
2016 constructors; however, non-left products should probably be
2018 type_of_aux' ~clean_dummy_dependent_types:false ~localization_tbl
2019 metasenv [] ty ugraph
2021 metasenv,ugraph,(name,b,ty',cl)::res
2022 ) tys (metasenv,ugraph,[]) in
2024 List.rev_map (fun (name,_,ty,_)-> Some (Cic.Name name,Cic.Decl ty)) tys in
2025 (* second phase: we fix only the constructors *)
2026 let saved_menv = metasenv in
2027 let metasenv,ugraph,tys =
2029 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
2030 let metasenv,ugraph,cl' =
2032 (fun (name,ty) (metasenv,ugraph,res) ->
2034 CicTypeChecker.debrujin_constructor
2035 ~cb:(relocalize localization_tbl) uri typesno [] ty in
2036 let ty',_,metasenv,ugraph =
2037 type_of_aux' ~localization_tbl metasenv con_context ty ugraph in
2038 let ty' = undebrujin uri typesno tys ty' in
2039 metasenv@saved_menv,ugraph,(name,ty')::res
2040 ) cl (metasenv,ugraph,[])
2042 metasenv,ugraph,(name,b,ty,cl')::res
2043 ) tys (metasenv,ugraph,[]) in
2044 (* third phase: we check the positivity condition *)
2045 let metasenv,ugraph,tys =
2046 are_all_occurrences_positive metasenv ugraph uri tys paramsno
2048 Cic.InductiveDefinition (tys,args,paramsno,attrs),metasenv,ugraph
2051 (* sara' piu' veloce che raffinare da zero? mah.... *)
2052 let pack_coercion metasenv ctx t =
2053 let module C = Cic in
2054 let rec merge_coercions ctx =
2055 let aux = (fun (u,t) -> u,merge_coercions ctx t) in
2057 | C.Rel _ | C.Sort _ | C.Implicit _ as t -> t
2058 | C.Meta (n,subst) ->
2061 (function None -> None | Some t -> Some (merge_coercions ctx t)) subst
2064 | C.Cast (te,ty) -> C.Cast (merge_coercions ctx te, merge_coercions ctx ty)
2065 | C.Prod (name,so,dest) ->
2066 let ctx' = (Some (name,C.Decl so))::ctx in
2067 C.Prod (name, merge_coercions ctx so, merge_coercions ctx' dest)
2068 | C.Lambda (name,so,dest) ->
2069 let ctx' = (Some (name,C.Decl so))::ctx in
2070 C.Lambda (name, merge_coercions ctx so, merge_coercions ctx' dest)
2071 | C.LetIn (name,so,ty,dest) ->
2072 let ctx' = Some (name,(C.Def (so,ty)))::ctx in
2074 (name, merge_coercions ctx so, merge_coercions ctx ty,
2075 merge_coercions ctx' dest)
2077 let l = List.map (merge_coercions ctx) l in
2079 let b,_,_,_,_ = is_a_double_coercion t in
2081 let ugraph = CicUniv.oblivion_ugraph in
2082 let old_insert_coercions = !insert_coercions in
2083 insert_coercions := false;
2084 let newt, _, menv, _ =
2086 type_of_aux' metasenv ctx t ugraph
2087 with RefineFailure _ | Uncertain _ ->
2090 insert_coercions := old_insert_coercions;
2091 if metasenv <> [] || menv = [] then
2094 (prerr_endline "PUO' SUCCEDERE!!!!!";t)
2097 | C.Var (uri,exp_named_subst) ->
2098 let exp_named_subst = List.map aux exp_named_subst in
2099 C.Var (uri, exp_named_subst)
2100 | C.Const (uri,exp_named_subst) ->
2101 let exp_named_subst = List.map aux exp_named_subst in
2102 C.Const (uri, exp_named_subst)
2103 | C.MutInd (uri,tyno,exp_named_subst) ->
2104 let exp_named_subst = List.map aux exp_named_subst in
2105 C.MutInd (uri,tyno,exp_named_subst)
2106 | C.MutConstruct (uri,tyno,consno,exp_named_subst) ->
2107 let exp_named_subst = List.map aux exp_named_subst in
2108 C.MutConstruct (uri,tyno,consno,exp_named_subst)
2109 | C.MutCase (uri,tyno,out,te,pl) ->
2110 let pl = List.map (merge_coercions ctx) pl in
2111 C.MutCase (uri,tyno,merge_coercions ctx out, merge_coercions ctx te, pl)
2112 | C.Fix (fno, fl) ->
2115 (fun l (n,_,ty,_) -> (Some (C.Name n,C.Decl ty))::l)
2120 (fun (name,idx,ty,bo) ->
2121 (name,idx,merge_coercions ctx ty,merge_coercions ctx' bo))
2125 | C.CoFix (fno, fl) ->
2128 (fun l (n,ty,_) -> (Some (C.Name n,C.Decl ty))::l)
2133 (fun (name,ty,bo) ->
2134 (name, merge_coercions ctx ty, merge_coercions ctx' bo))
2139 merge_coercions ctx t
2142 let pack_coercion_metasenv conjectures = conjectures (*
2144 TASSI: this code war written when coercions were a toy,
2145 now packing coercions involves unification thus
2146 the metasenv may change, and this pack coercion
2147 does not handle that.
2149 let module C = Cic in
2151 (fun (i, ctx, ty) ->
2157 Some (name, C.Decl t) ->
2158 Some (name, C.Decl (pack_coercion conjectures ctx t))
2159 | Some (name, C.Def (t,None)) ->
2160 Some (name,C.Def (pack_coercion conjectures ctx t,None))
2161 | Some (name, C.Def (t,Some ty)) ->
2162 Some (name, C.Def (pack_coercion conjectures ctx t,
2163 Some (pack_coercion conjectures ctx ty)))
2169 ((i,ctx,pack_coercion conjectures ctx ty))
2174 let pack_coercion_obj obj = obj (*
2176 TASSI: this code war written when coercions were a toy,
2177 now packing coercions involves unification thus
2178 the metasenv may change, and this pack coercion
2179 does not handle that.
2181 let module C = Cic in
2183 | C.Constant (id, body, ty, params, attrs) ->
2187 | Some body -> Some (pack_coercion [] [] body)
2189 let ty = pack_coercion [] [] ty in
2190 C.Constant (id, body, ty, params, attrs)
2191 | C.Variable (name, body, ty, params, attrs) ->
2195 | Some body -> Some (pack_coercion [] [] body)
2197 let ty = pack_coercion [] [] ty in
2198 C.Variable (name, body, ty, params, attrs)
2199 | C.CurrentProof (name, conjectures, body, ty, params, attrs) ->
2200 let conjectures = pack_coercion_metasenv conjectures in
2201 let body = pack_coercion conjectures [] body in
2202 let ty = pack_coercion conjectures [] ty in
2203 C.CurrentProof (name, conjectures, body, ty, params, attrs)
2204 | C.InductiveDefinition (indtys, params, leftno, attrs) ->
2207 (fun (name, ind, arity, cl) ->
2208 let arity = pack_coercion [] [] arity in
2210 List.map (fun (name, ty) -> (name,pack_coercion [] [] ty)) cl
2212 (name, ind, arity, cl))
2215 C.InductiveDefinition (indtys, params, leftno, attrs) *)
2220 let type_of_aux' metasenv context term =
2223 type_of_aux' metasenv context term in
2225 ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty));
2227 ("@@@ REFINE SUCCESSFUL (metasenv):\n" ^ CicMetaSubst.ppmetasenv ~sep:";" m []));
2230 | RefineFailure msg as e ->
2231 debug_print (lazy ("@@@ REFINE FAILED: " ^ msg));
2233 | Uncertain msg as e ->
2234 debug_print (lazy ("@@@ REFINE UNCERTAIN: " ^ msg));
2238 let profiler2 = HExtlib.profile "CicRefine"
2240 let type_of_aux' ?localization_tbl metasenv context term ugraph =
2241 profiler2.HExtlib.profile
2242 (type_of_aux' ?localization_tbl metasenv context term) ugraph
2244 let typecheck ~localization_tbl metasenv uri obj =
2245 profiler2.HExtlib.profile (typecheck ~localization_tbl metasenv uri) obj
2247 let _ = DoubleTypeInference.pack_coercion := pack_coercion;;
2248 (* vim:set foldmethod=marker: *)