1 (* Copyright (C) 2000, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
28 exception RefineFailure of string Lazy.t;;
29 exception Uncertain of string Lazy.t;;
30 exception AssertFailure of string Lazy.t;;
32 let debug_print = fun _ -> ()
34 let profiler = HExtlib.profile "CicRefine.fo_unif"
36 let fo_unif_subst subst context metasenv t1 t2 ugraph =
39 CicUnification.fo_unif_subst subst context metasenv t1 t2 ugraph
40 in profiler.HExtlib.profile foo ()
42 (CicUnification.UnificationFailure msg) -> raise (RefineFailure msg)
43 | (CicUnification.Uncertain msg) -> raise (Uncertain msg)
48 RefineFailure msg -> raise (RefineFailure (f msg))
49 | Uncertain msg -> raise (Uncertain (f msg))
55 | (he::tl, n) -> let (l1,l2) = split tl (n-1) in (he::l1,l2)
56 | (_,_) -> raise (AssertFailure (lazy "split: list too short"))
59 let exp_impl metasenv subst context term =
60 let rec aux metasenv context = function
61 | (Cic.Rel _) as t -> metasenv, t
62 | (Cic.Sort _) as t -> metasenv, t
63 | Cic.Const (uri, subst) ->
64 let metasenv', subst' = do_subst metasenv context subst in
65 metasenv', Cic.Const (uri, subst')
66 | Cic.Var (uri, subst) ->
67 let metasenv', subst' = do_subst metasenv context subst in
68 metasenv', Cic.Var (uri, subst')
69 | Cic.MutInd (uri, i, subst) ->
70 let metasenv', subst' = do_subst metasenv context subst in
71 metasenv', Cic.MutInd (uri, i, subst')
72 | Cic.MutConstruct (uri, i, j, subst) ->
73 let metasenv', subst' = do_subst metasenv context subst in
74 metasenv', Cic.MutConstruct (uri, i, j, subst')
76 let metasenv', l' = do_local_context metasenv context l in
77 metasenv', Cic.Meta (n, l')
78 | Cic.Implicit (Some `Type) ->
79 let (metasenv', idx) = CicMkImplicit.mk_implicit_type metasenv subst context in
80 let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
81 metasenv', Cic.Meta (idx, irl)
82 | Cic.Implicit (Some `Closed) ->
83 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst [] in
84 metasenv', Cic.Meta (idx, [])
85 | Cic.Implicit None ->
86 let (metasenv', idx) = CicMkImplicit.mk_implicit metasenv subst context in
87 let irl = CicMkImplicit.identity_relocation_list_for_metavariable context in
88 metasenv', Cic.Meta (idx, irl)
89 | Cic.Implicit _ -> assert false
90 | Cic.Cast (te, ty) ->
91 let metasenv', ty' = aux metasenv context ty in
92 let metasenv'', te' = aux metasenv' context te in
93 metasenv'', Cic.Cast (te', ty')
94 | Cic.Prod (name, s, t) ->
95 let metasenv', s' = aux metasenv context s in
96 metasenv', Cic.Prod (name, s', t)
97 | Cic.Lambda (name, s, t) ->
98 let metasenv', s' = aux metasenv context s in
99 metasenv', Cic.Lambda (name, s', t)
100 | Cic.LetIn (name, s, t) ->
101 let metasenv', s' = aux metasenv context s in
102 metasenv', Cic.LetIn (name, s', t)
103 | Cic.Appl l when List.length l > 1 ->
106 (fun term (metasenv, terms) ->
107 let new_metasenv, term = aux metasenv context term in
108 new_metasenv, term :: terms)
111 metasenv', Cic.Appl l'
112 | Cic.Appl _ -> assert false
113 | Cic.MutCase (uri, i, outtype, term, patterns) ->
116 (fun term (metasenv, terms) ->
117 let new_metasenv, term = aux metasenv context term in
118 new_metasenv, term :: terms)
119 (outtype :: term :: patterns) (metasenv, [])
121 let outtype', term', patterns' =
123 | outtype' :: term' :: patterns' -> outtype', term', patterns'
126 metasenv', Cic.MutCase (uri, i, outtype', term', patterns')
127 | Cic.Fix (i, funs) ->
128 let metasenv', types =
130 (fun (name, _, typ, _) (metasenv, types) ->
131 let new_metasenv, new_type = aux metasenv context typ in
132 (new_metasenv, (name, new_type) :: types))
135 let rec combine = function
136 | ((name, index, _, body) :: funs_tl),
137 ((_, typ) :: typ_tl) ->
138 (name, index, typ, body) :: combine (funs_tl, typ_tl)
142 let funs' = combine (funs, types) in
143 metasenv', Cic.Fix (i, funs')
144 | Cic.CoFix (i, funs) ->
145 let metasenv', types =
147 (fun (name, typ, _) (metasenv, types) ->
148 let new_metasenv, new_type = aux metasenv context typ in
149 (new_metasenv, (name, new_type) :: types))
152 let rec combine = function
153 | ((name, _, body) :: funs_tl),
154 ((_, typ) :: typ_tl) ->
155 (name, typ, body) :: combine (funs_tl, typ_tl)
159 let funs' = combine (funs, types) in
160 metasenv', Cic.CoFix (i, funs')
161 and do_subst metasenv context subst =
163 (fun (uri, term) (metasenv, substs) ->
164 let metasenv', term' = aux metasenv context term in
165 (metasenv', (uri, term') :: substs))
167 and do_local_context metasenv context local_context =
169 (fun term (metasenv, local_context) ->
170 let metasenv', term' =
172 | None -> metasenv, None
174 let metasenv', term' = aux metasenv context term in
175 metasenv', Some term'
177 metasenv', term' :: local_context)
178 local_context (metasenv, [])
180 aux metasenv context term
183 let rec type_of_constant uri ugraph =
184 let module C = Cic in
185 let module R = CicReduction in
186 let module U = UriManager in
187 let _ = CicTypeChecker.typecheck uri in
190 CicEnvironment.get_cooked_obj ugraph uri
191 with Not_found -> assert false
194 C.Constant (_,_,ty,_,_) -> ty,u
195 | C.CurrentProof (_,_,_,ty,_,_) -> ty,u
198 (RefineFailure (lazy ("Unknown constant definition " ^ U.string_of_uri uri)))
200 and type_of_variable uri ugraph =
201 let module C = Cic in
202 let module R = CicReduction in
203 let module U = UriManager in
204 let _ = CicTypeChecker.typecheck uri in
207 CicEnvironment.get_cooked_obj ugraph uri
208 with Not_found -> assert false
211 C.Variable (_,_,ty,_,_) -> ty,u
215 (lazy ("Unknown variable definition " ^ UriManager.string_of_uri uri)))
217 and type_of_mutual_inductive_defs uri i ugraph =
218 let module C = Cic in
219 let module R = CicReduction in
220 let module U = UriManager in
221 let _ = CicTypeChecker.typecheck uri in
224 CicEnvironment.get_cooked_obj ugraph uri
225 with Not_found -> assert false
228 C.InductiveDefinition (dl,_,_,_) ->
229 let (_,_,arity,_) = List.nth dl i in
234 (lazy ("Unknown mutual inductive definition " ^ U.string_of_uri uri)))
236 and type_of_mutual_inductive_constr uri i j ugraph =
237 let module C = Cic in
238 let module R = CicReduction in
239 let module U = UriManager in
240 let _ = CicTypeChecker.typecheck uri in
243 CicEnvironment.get_cooked_obj ugraph uri
244 with Not_found -> assert false
247 C.InductiveDefinition (dl,_,_,_) ->
248 let (_,_,_,cl) = List.nth dl i in
249 let (_,ty) = List.nth cl (j-1) in
255 ("Unkown mutual inductive definition " ^ U.string_of_uri uri)))
258 (* type_of_aux' is just another name (with a different scope) for type_of_aux *)
260 (* the check_branch function checks if a branch of a case is refinable.
261 It returns a pair (outype_instance,args), a subst and a metasenv.
262 outype_instance is the expected result of applying the case outtype
264 The problem is that outype is in general unknown, and we should
265 try to synthesize it from the above information, that is in general
266 a second order unification problem. *)
268 and check_branch n context metasenv subst left_args_no actualtype term expectedtype ugraph =
269 let module C = Cic in
270 (* let module R = CicMetaSubst in *)
271 let module R = CicReduction in
272 match R.whd ~subst context expectedtype with
274 (n,context,actualtype, [term]), subst, metasenv, ugraph
275 | C.Appl (C.MutInd (_,_,_)::tl) ->
276 let (_,arguments) = split tl left_args_no in
277 (n,context,actualtype, arguments@[term]), subst, metasenv, ugraph
278 | C.Prod (name,so,de) ->
279 (* we expect that the actual type of the branch has the due
281 (match R.whd ~subst context actualtype with
282 C.Prod (name',so',de') ->
283 let subst, metasenv, ugraph1 =
284 fo_unif_subst subst context metasenv so so' ugraph in
286 (match CicSubstitution.lift 1 term with
287 C.Appl l -> C.Appl (l@[C.Rel 1])
288 | t -> C.Appl [t ; C.Rel 1]) in
289 (* we should also check that the name variable is anonymous in
290 the actual type de' ?? *)
292 ((Some (name,(C.Decl so)))::context)
293 metasenv subst left_args_no de' term' de ugraph1
294 | _ -> raise (AssertFailure (lazy "Wrong number of arguments")))
295 | _ -> raise (AssertFailure (lazy "Prod or MutInd expected"))
297 and type_of_aux' metasenv context t ugraph =
298 let metasenv, t = exp_impl metasenv [] context t in
299 let rec type_of_aux subst metasenv context t ugraph =
300 let module C = Cic in
301 let module S = CicSubstitution in
302 let module U = UriManager in
303 (* this stops on binders, so we have to call it every time *)
308 match List.nth context (n - 1) with
309 Some (_,C.Decl ty) ->
310 t,S.lift n ty,subst,metasenv, ugraph
311 | Some (_,C.Def (_,Some ty)) ->
312 t,S.lift n ty,subst,metasenv, ugraph
313 | Some (_,C.Def (bo,None)) ->
315 (* if it is in the context it must be already well-typed*)
316 CicTypeChecker.type_of_aux' ~subst metasenv context
319 t,ty,subst,metasenv,ugraph
320 | None -> raise (RefineFailure (lazy "Rel to hidden hypothesis"))
322 _ -> raise (RefineFailure (lazy "Not a close term")))
323 | C.Var (uri,exp_named_subst) ->
324 let exp_named_subst',subst',metasenv',ugraph1 =
325 check_exp_named_subst
326 subst metasenv context exp_named_subst ugraph
328 let ty_uri,ugraph1 = type_of_variable uri ugraph in
330 CicSubstitution.subst_vars exp_named_subst' ty_uri
332 C.Var (uri,exp_named_subst'),ty,subst',metasenv',ugraph1
335 let (canonical_context, term,ty) =
336 CicUtil.lookup_subst n subst
338 let l',subst',metasenv',ugraph1 =
339 check_metasenv_consistency n subst metasenv context
340 canonical_context l ugraph
342 (* trust or check ??? *)
343 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
344 subst', metasenv', ugraph1
345 (* type_of_aux subst metasenv
346 context (CicSubstitution.subst_meta l term) *)
347 with CicUtil.Subst_not_found _ ->
348 let (_,canonical_context,ty) = CicUtil.lookup_meta n metasenv in
349 let l',subst',metasenv', ugraph1 =
350 check_metasenv_consistency n subst metasenv context
351 canonical_context l ugraph
353 C.Meta (n,l'),CicSubstitution.subst_meta l' ty,
354 subst', metasenv',ugraph1)
355 | C.Sort (C.Type tno) ->
356 let tno' = CicUniv.fresh() in
357 let ugraph1 = CicUniv.add_gt tno' tno ugraph in
358 t,(C.Sort (C.Type tno')),subst,metasenv,ugraph1
360 t,C.Sort (C.Type (CicUniv.fresh())),subst,metasenv,ugraph
361 | C.Implicit _ -> raise (AssertFailure (lazy "21"))
363 let ty',_,subst',metasenv',ugraph1 =
364 type_of_aux subst metasenv context ty ugraph
366 let te',inferredty,subst'',metasenv'',ugraph2 =
367 type_of_aux subst' metasenv' context te ugraph1
369 let subst''',metasenv''',ugraph3 =
370 fo_unif_subst subst'' context metasenv''
371 inferredty ty' ugraph2
373 C.Cast (te',ty'),ty',subst''',metasenv''',ugraph3
374 | C.Prod (name,s,t) ->
375 let carr t subst context = CicMetaSubst.apply_subst subst t in
377 in_source tgt_sort t type_to_coerce subst ctx metasenv uragph
379 let coercion_src = carr type_to_coerce subst ctx in
380 match coercion_src with
382 t,type_to_coerce,subst,metasenv,ugraph
384 | Cic.Meta _ as meta when not in_source ->
385 let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
386 let subst, metasenv, ugraph =
388 subst ctx metasenv meta coercion_tgt ugraph
390 t, Cic.Sort tgt_sort, subst, metasenv, ugraph
392 | Cic.Meta _ as meta ->
393 t, meta, subst, metasenv, ugraph
394 | Cic.Cast _ as cast ->
395 t, cast, subst, metasenv, ugraph
397 let coercion_tgt = carr (Cic.Sort tgt_sort) subst ctx in
398 let search = CoercGraph.look_for_coercion in
399 let boh = search coercion_src coercion_tgt in
401 | CoercGraph.NoCoercion
402 | CoercGraph.NotHandled _ ->
404 (RefineFailure (lazy (CicMetaSubst.ppterm subst coercion_src ^ " is not a sort and cannoted be coerced to a sort")))
405 | CoercGraph.NotMetaClosed ->
407 (Uncertain (lazy (CicMetaSubst.ppterm subst coercion_src ^ " is not a sort and cannoted be coerced to a sort")))
408 | CoercGraph.SomeCoercion c ->
409 Cic.Appl [c;t],Cic.Sort tgt_sort,subst, metasenv, ugraph)
411 let s',sort1,subst',metasenv',ugraph1 =
412 type_of_aux subst metasenv context s ugraph
414 let s',sort1,subst', metasenv',ugraph1 =
415 coerce_to_sort true (Cic.Type(CicUniv.fresh()))
416 s' sort1 subst' context metasenv' ugraph1
418 let context_for_t = ((Some (name,(C.Decl s')))::context) in
419 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
420 let t',sort2,subst'',metasenv'',ugraph2 =
421 type_of_aux subst' metasenv'
422 context_for_t t ugraph1
424 let t',sort2,subst'',metasenv'',ugraph2 =
425 coerce_to_sort false (Cic.Type(CicUniv.fresh()))
426 t' sort2 subst'' context_for_t metasenv'' ugraph2
428 let sop,subst''',metasenv''',ugraph3 =
429 sort_of_prod subst'' metasenv''
430 context (name,s') (sort1,sort2) ugraph2
432 C.Prod (name,s',t'),sop,subst''',metasenv''',ugraph3
433 | C.Lambda (n,s,t) ->
435 let s',sort1,subst',metasenv',ugraph1 =
436 type_of_aux subst metasenv context s ugraph in
438 match CicReduction.whd ~subst:subst' context sort1 with
440 | C.Sort _ -> s',sort1
442 let coercion_tgt = Cic.Sort (Cic.Type (CicUniv.fresh ())) in
443 let search = CoercGraph.look_for_coercion in
444 let boh = search coercion_src coercion_tgt in
446 | CoercGraph.SomeCoercion c ->
447 Cic.Appl [c;s'], coercion_tgt
448 | CoercGraph.NoCoercion
449 | CoercGraph.NotHandled _
450 | CoercGraph.NotMetaClosed ->
451 raise (RefineFailure (lazy (sprintf
452 "Not well-typed lambda-abstraction: the source %s should be a type; instead it is a term of type %s" (CicPp.ppterm s) (CicPp.ppterm sort1))))
454 let context_for_t = ((Some (n,(C.Decl s')))::context) in
455 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
456 let t',type2,subst'',metasenv'',ugraph2 =
457 type_of_aux subst' metasenv' context_for_t t ugraph1
459 C.Lambda (n,s',t'),C.Prod (n,s',type2),
460 subst'',metasenv'',ugraph2
462 (* only to check if s is well-typed *)
463 let s',ty,subst',metasenv',ugraph1 =
464 type_of_aux subst metasenv context s ugraph
466 let context_for_t = ((Some (n,(C.Def (s',Some ty))))::context) in
467 let metasenv',t = exp_impl metasenv' subst' context_for_t t in
469 let t',inferredty,subst'',metasenv'',ugraph2 =
470 type_of_aux subst' metasenv'
471 context_for_t t ugraph1
473 (* One-step LetIn reduction.
474 * Even faster than the previous solution.
475 * Moreover the inferred type is closer to the expected one.
477 C.LetIn (n,s',t'),CicSubstitution.subst s' inferredty,
478 subst'',metasenv'',ugraph2
479 | C.Appl (he::((_::_) as tl)) ->
480 let he',hetype,subst',metasenv',ugraph1 =
481 type_of_aux subst metasenv context he ugraph
483 let tlbody_and_type,subst'',metasenv'',ugraph2 =
485 (fun x (res,subst,metasenv,ugraph) ->
486 let x',ty,subst',metasenv',ugraph1 =
487 type_of_aux subst metasenv context x ugraph
489 (x', ty)::res,subst',metasenv',ugraph1
490 ) tl ([],subst',metasenv',ugraph1)
492 let tl',applty,subst''',metasenv''',ugraph3 =
494 eat_prods true subst'' metasenv'' context
495 hetype tlbody_and_type ugraph2
500 lazy ("The application " ^
501 CicMetaSubst.ppterm_in_context subst'' t context ^
502 " is not well typed:\n" ^ Lazy.force msg)) exn
504 C.Appl (he'::tl'), applty,subst''',metasenv''',ugraph3
505 | C.Appl _ -> raise (RefineFailure (lazy "Appl: no arguments"))
506 | C.Const (uri,exp_named_subst) ->
507 let exp_named_subst',subst',metasenv',ugraph1 =
508 check_exp_named_subst subst metasenv context
509 exp_named_subst ugraph in
510 let ty_uri,ugraph2 = type_of_constant uri ugraph1 in
512 CicSubstitution.subst_vars exp_named_subst' ty_uri
514 C.Const (uri,exp_named_subst'),cty,subst',metasenv',ugraph2
515 | C.MutInd (uri,i,exp_named_subst) ->
516 let exp_named_subst',subst',metasenv',ugraph1 =
517 check_exp_named_subst subst metasenv context
518 exp_named_subst ugraph
520 let ty_uri,ugraph2 = type_of_mutual_inductive_defs uri i ugraph1 in
522 CicSubstitution.subst_vars exp_named_subst' ty_uri in
523 C.MutInd (uri,i,exp_named_subst'),cty,subst',metasenv',ugraph2
524 | C.MutConstruct (uri,i,j,exp_named_subst) ->
525 let exp_named_subst',subst',metasenv',ugraph1 =
526 check_exp_named_subst subst metasenv context
527 exp_named_subst ugraph
530 type_of_mutual_inductive_constr uri i j ugraph1
533 CicSubstitution.subst_vars exp_named_subst' ty_uri
535 C.MutConstruct (uri,i,j,exp_named_subst'),cty,subst',
537 | C.MutCase (uri, i, outtype, term, pl) ->
538 (* first, get the inductive type (and noparams)
539 * in the environment *)
540 let (_,b,arity,constructors), expl_params, no_left_params,ugraph =
541 let _ = CicTypeChecker.typecheck uri in
542 let obj,u = CicEnvironment.get_cooked_obj ugraph uri in
544 C.InductiveDefinition (l,expl_params,parsno,_) ->
545 List.nth l i , expl_params, parsno, u
549 (lazy ("Unkown mutual inductive definition " ^
550 U.string_of_uri uri)))
552 let rec count_prod t =
553 match CicReduction.whd ~subst context t with
554 C.Prod (_, _, t) -> 1 + (count_prod t)
557 let no_args = count_prod arity in
558 (* now, create a "generic" MutInd *)
559 let metasenv,left_args =
560 CicMkImplicit.n_fresh_metas metasenv subst context no_left_params
562 let metasenv,right_args =
563 let no_right_params = no_args - no_left_params in
564 if no_right_params < 0 then assert false
565 else CicMkImplicit.n_fresh_metas
566 metasenv subst context no_right_params
568 let metasenv,exp_named_subst =
569 CicMkImplicit.fresh_subst metasenv subst context expl_params in
572 C.MutInd (uri,i,exp_named_subst)
575 (C.MutInd (uri,i,exp_named_subst)::(left_args @ right_args))
577 (* check consistency with the actual type of term *)
578 let term',actual_type,subst,metasenv,ugraph1 =
579 type_of_aux subst metasenv context term ugraph in
580 let expected_type',_, subst, metasenv,ugraph2 =
581 type_of_aux subst metasenv context expected_type ugraph1
583 let actual_type = CicReduction.whd ~subst context actual_type in
584 let subst,metasenv,ugraph3 =
585 fo_unif_subst subst context metasenv
586 expected_type' actual_type ugraph2
588 let rec instantiate_prod t =
592 match CicReduction.whd ~subst context t with
594 instantiate_prod (CicSubstitution.subst he t') tl
597 let arity_instantiated_with_left_args =
598 instantiate_prod arity left_args in
599 (* TODO: check if the sort elimination
600 * is allowed: [(I q1 ... qr)|B] *)
601 let (pl',_,outtypeinstances,subst,metasenv,ugraph4) =
603 (fun (pl,j,outtypeinstances,subst,metasenv,ugraph) p ->
605 if left_args = [] then
606 (C.MutConstruct (uri,i,j,exp_named_subst))
609 (C.MutConstruct (uri,i,j,exp_named_subst)::left_args))
611 let p',actual_type,subst,metasenv,ugraph1 =
612 type_of_aux subst metasenv context p ugraph
614 let constructor',expected_type, subst, metasenv,ugraph2 =
615 type_of_aux subst metasenv context constructor ugraph1
617 let outtypeinstance,subst,metasenv,ugraph3 =
618 check_branch 0 context metasenv subst no_left_params
619 actual_type constructor' expected_type ugraph2
622 outtypeinstance::outtypeinstances,subst,metasenv,ugraph3))
623 ([],1,[],subst,metasenv,ugraph3) pl
626 (* we are left to check that the outype matches his instances.
627 The easy case is when the outype is specified, that amount
628 to a trivial check. Otherwise, we should guess a type from
634 (let candidate,ugraph5,metasenv,subst =
635 let exp_name_subst, metasenv =
637 CicEnvironment.get_cooked_obj CicUniv.empty_ugraph uri
639 let uris = CicUtil.params_of_obj o in
641 fun uri (acc,metasenv) ->
642 let metasenv',new_meta =
643 CicMkImplicit.mk_implicit metasenv subst context
646 CicMkImplicit.identity_relocation_list_for_metavariable
649 (uri, Cic.Meta(new_meta,irl))::acc, metasenv'
653 match left_args,right_args with
654 [],[] -> Cic.MutInd(uri, i, exp_name_subst)
656 let rec mk_right_args =
659 | n -> (Cic.Rel n)::(mk_right_args (n - 1))
661 let right_args_no = List.length right_args in
662 let lifted_left_args =
663 List.map (CicSubstitution.lift right_args_no) left_args
665 Cic.Appl (Cic.MutInd(uri,i,exp_name_subst)::
666 (lifted_left_args @ mk_right_args right_args_no))
669 FreshNamesGenerator.mk_fresh_name ~subst metasenv
670 context Cic.Anonymous ~typ:ty
672 match outtypeinstances with
674 let extended_context =
675 let rec add_right_args =
677 Cic.Prod (name,ty,t) ->
678 Some (name,Cic.Decl ty)::(add_right_args t)
681 (Some (fresh_name,Cic.Decl ty))::
683 (add_right_args arity_instantiated_with_left_args))@
686 let metasenv,new_meta =
687 CicMkImplicit.mk_implicit metasenv subst extended_context
690 CicMkImplicit.identity_relocation_list_for_metavariable
693 let rec add_lambdas b =
695 Cic.Prod (name,ty,t) ->
696 Cic.Lambda (name,ty,(add_lambdas b t))
697 | _ -> Cic.Lambda (fresh_name, ty, b)
700 add_lambdas (Cic.Meta (new_meta,irl))
701 arity_instantiated_with_left_args
703 (Some candidate),ugraph4,metasenv,subst
704 | (constructor_args_no,_,instance,_)::tl ->
706 let instance',subst,metasenv =
707 CicMetaSubst.delift_rels subst metasenv
708 constructor_args_no instance
710 let candidate,ugraph,metasenv,subst =
712 fun (candidate_oty,ugraph,metasenv,subst)
713 (constructor_args_no,_,instance,_) ->
714 match candidate_oty with
715 | None -> None,ugraph,metasenv,subst
718 let instance',subst,metasenv =
719 CicMetaSubst.delift_rels subst metasenv
720 constructor_args_no instance
722 let subst,metasenv,ugraph =
723 fo_unif_subst subst context metasenv
726 candidate_oty,ugraph,metasenv,subst
728 CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable
729 | CicUnification.UnificationFailure _
730 | CicUnification.Uncertain _ ->
731 None,ugraph,metasenv,subst
732 ) (Some instance',ugraph4,metasenv,subst) tl
735 | None -> None, ugraph,metasenv,subst
737 let rec add_lambdas n b =
739 Cic.Prod (name,ty,t) ->
740 Cic.Lambda (name,ty,(add_lambdas (n + 1) b t))
742 Cic.Lambda (fresh_name, ty,
743 CicSubstitution.lift (n + 1) t)
746 (add_lambdas 0 t arity_instantiated_with_left_args),
747 ugraph,metasenv,subst
748 with CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
749 None,ugraph4,metasenv,subst
752 | None -> raise (Uncertain (lazy "can't solve an higher order unification problem"))
754 let subst,metasenv,ugraph =
755 fo_unif_subst subst context metasenv
756 candidate outtype ugraph5
758 C.MutCase (uri, i, outtype, term', pl'),
759 CicReduction.head_beta_reduce
760 (CicMetaSubst.apply_subst subst
761 (Cic.Appl (outtype::right_args@[term']))),
762 subst,metasenv,ugraph)
763 | _ -> (* easy case *)
764 let outtype,outtypety, subst, metasenv,ugraph4 =
765 type_of_aux subst metasenv context outtype ugraph4
767 let tlbody_and_type,subst,metasenv,ugraph4 =
769 (fun x (res,subst,metasenv,ugraph) ->
770 let x',ty,subst',metasenv',ugraph1 =
771 type_of_aux subst metasenv context x ugraph
773 (x', ty)::res,subst',metasenv',ugraph1
774 ) (right_args @ [term']) ([],subst,metasenv,ugraph4)
776 let _,_,subst,metasenv,ugraph4 =
777 eat_prods false subst metasenv context
778 outtypety tlbody_and_type ugraph4
780 let _,_, subst, metasenv,ugraph5 =
781 type_of_aux subst metasenv context
782 (C.Appl ((outtype :: right_args) @ [term'])) ugraph4
784 let (subst,metasenv,ugraph6) =
786 (fun (subst,metasenv,ugraph)
787 (constructor_args_no,context,instance,args) ->
791 CicSubstitution.lift constructor_args_no outtype
793 C.Appl (outtype'::args)
795 CicReduction.whd ~subst context appl
797 fo_unif_subst subst context metasenv
798 instance instance' ugraph)
799 (subst,metasenv,ugraph5) outtypeinstances
801 C.MutCase (uri, i, outtype, term', pl'),
802 CicReduction.head_beta_reduce
803 (CicMetaSubst.apply_subst subst
804 (C.Appl(outtype::right_args@[term]))),
805 subst,metasenv,ugraph6)
807 let fl_ty',subst,metasenv,types,ugraph1 =
809 (fun (fl,subst,metasenv,types,ugraph) (n,_,ty,_) ->
810 let ty',_,subst',metasenv',ugraph1 =
811 type_of_aux subst metasenv context ty ugraph
813 fl @ [ty'],subst',metasenv',
814 Some (C.Name n,(C.Decl ty')) :: types, ugraph
815 ) ([],subst,metasenv,[],ugraph) fl
817 let len = List.length types in
818 let context' = types@context in
819 let fl_bo',subst,metasenv,ugraph2 =
821 (fun (fl,subst,metasenv,ugraph) ((name,x,_,bo),ty) ->
822 let metasenv, bo = exp_impl metasenv subst context' bo in
823 let bo',ty_of_bo,subst,metasenv,ugraph1 =
824 type_of_aux subst metasenv context' bo ugraph
826 let subst',metasenv',ugraph' =
827 fo_unif_subst subst context' metasenv
828 ty_of_bo (CicSubstitution.lift len ty) ugraph1
830 fl @ [bo'] , subst',metasenv',ugraph'
831 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
833 let ty = List.nth fl_ty' i in
834 (* now we have the new ty in fl_ty', the new bo in fl_bo',
835 * and we want the new fl with bo' and ty' injected in the right
838 let rec map3 f l1 l2 l3 =
841 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
844 let fl'' = map3 (fun ty' bo' (name,x,ty,bo) -> (name,x,ty',bo') )
847 C.Fix (i,fl''),ty,subst,metasenv,ugraph2
849 let fl_ty',subst,metasenv,types,ugraph1 =
851 (fun (fl,subst,metasenv,types,ugraph) (n,ty,_) ->
852 let ty',_,subst',metasenv',ugraph1 =
853 type_of_aux subst metasenv context ty ugraph
855 fl @ [ty'],subst',metasenv',
856 Some (C.Name n,(C.Decl ty')) :: types, ugraph1
857 ) ([],subst,metasenv,[],ugraph) fl
859 let len = List.length types in
860 let context' = types@context in
861 let fl_bo',subst,metasenv,ugraph2 =
863 (fun (fl,subst,metasenv,ugraph) ((name,_,bo),ty) ->
864 let metasenv, bo = exp_impl metasenv subst context' bo in
865 let bo',ty_of_bo,subst,metasenv,ugraph1 =
866 type_of_aux subst metasenv context' bo ugraph
868 let subst',metasenv',ugraph' =
869 fo_unif_subst subst context' metasenv
870 ty_of_bo (CicSubstitution.lift len ty) ugraph1
872 fl @ [bo'],subst',metasenv',ugraph'
873 ) ([],subst,metasenv,ugraph1) (List.combine fl fl_ty')
875 let ty = List.nth fl_ty' i in
876 (* now we have the new ty in fl_ty', the new bo in fl_bo',
877 * and we want the new fl with bo' and ty' injected in the right
880 let rec map3 f l1 l2 l3 =
883 | h1::tl1,h2::tl2,h3::tl3 -> (f h1 h2 h3) :: (map3 f tl1 tl2 tl3)
886 let fl'' = map3 (fun ty' bo' (name,ty,bo) -> (name,ty',bo') )
889 C.CoFix (i,fl''),ty,subst,metasenv,ugraph2
891 (* check_metasenv_consistency checks that the "canonical" context of a
892 metavariable is consitent - up to relocation via the relocation list l -
893 with the actual context *)
894 and check_metasenv_consistency
895 metano subst metasenv context canonical_context l ugraph
897 let module C = Cic in
898 let module R = CicReduction in
899 let module S = CicSubstitution in
900 let lifted_canonical_context =
904 | (Some (n,C.Decl t))::tl ->
905 (Some (n,C.Decl (S.subst_meta l (S.lift i t))))::(aux (i+1) tl)
906 | (Some (n,C.Def (t,None)))::tl ->
907 (Some (n,C.Def ((S.subst_meta l (S.lift i t)),None)))::(aux (i+1) tl)
908 | None::tl -> None::(aux (i+1) tl)
909 | (Some (n,C.Def (t,Some ty)))::tl ->
911 C.Def ((S.subst_meta l (S.lift i t)),
912 Some (S.subst_meta l (S.lift i ty))))) :: (aux (i+1) tl)
914 aux 1 canonical_context
918 (fun (l,subst,metasenv,ugraph) t ct ->
921 l @ [None],subst,metasenv,ugraph
922 | Some t,Some (_,C.Def (ct,_)) ->
923 let subst',metasenv',ugraph' =
925 fo_unif_subst subst context metasenv t ct ugraph
926 with e -> raise (RefineFailure (lazy (sprintf "The local context is not consistent with the canonical context, since %s cannot be unified with %s. Reason: %s" (CicMetaSubst.ppterm subst t) (CicMetaSubst.ppterm subst ct) (match e with AssertFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
928 l @ [Some t],subst',metasenv',ugraph'
929 | Some t,Some (_,C.Decl ct) ->
930 let t',inferredty,subst',metasenv',ugraph1 =
931 type_of_aux subst metasenv context t ugraph
933 let subst'',metasenv'',ugraph2 =
936 subst' context metasenv' inferredty ct ugraph1
937 with e -> raise (RefineFailure (lazy (sprintf "The local context is not consistent with the canonical context, since the type %s of %s cannot be unified with the expected type %s. Reason: %s" (CicMetaSubst.ppterm subst' inferredty) (CicMetaSubst.ppterm subst' t) (CicMetaSubst.ppterm subst' ct) (match e with AssertFailure msg -> Lazy.force msg | RefineFailure msg -> Lazy.force msg | _ -> (Printexc.to_string e))))))
939 l @ [Some t'], subst'',metasenv'',ugraph2
941 raise (RefineFailure (lazy (sprintf "Not well typed metavariable instance %s: the local context does not instantiate an hypothesis even if the hypothesis is not restricted in the canonical context %s" (CicMetaSubst.ppterm subst (Cic.Meta (metano, l))) (CicMetaSubst.ppcontext subst canonical_context))))) ([],subst,metasenv,ugraph) l lifted_canonical_context
943 Invalid_argument _ ->
947 "Not well typed metavariable instance %s: the length of the local context does not match the length of the canonical context %s"
948 (CicMetaSubst.ppterm subst (Cic.Meta (metano, l)))
949 (CicMetaSubst.ppcontext subst canonical_context))))
951 and check_exp_named_subst metasubst metasenv context tl ugraph =
952 let rec check_exp_named_subst_aux metasubst metasenv substs tl ugraph =
954 [] -> [],metasubst,metasenv,ugraph
955 | ((uri,t) as subst)::tl ->
956 let ty_uri,ugraph1 = type_of_variable uri ugraph in
958 CicSubstitution.subst_vars substs ty_uri in
959 (* CSC: why was this code here? it is wrong
960 (match CicEnvironment.get_cooked_obj ~trust:false uri with
961 Cic.Variable (_,Some bo,_,_) ->
964 "A variable with a body can not be explicit substituted"))
965 | Cic.Variable (_,None,_,_) -> ()
969 ("Unkown variable definition " ^ UriManager.string_of_uri uri)))
972 let t',typeoft,metasubst',metasenv',ugraph2 =
973 type_of_aux metasubst metasenv context t ugraph1
975 let metasubst'',metasenv'',ugraph3 =
978 metasubst' context metasenv' typeoft typeofvar ugraph2
980 raise (RefineFailure (lazy
981 ("Wrong Explicit Named Substitution: " ^
982 CicMetaSubst.ppterm metasubst' typeoft ^
983 " not unifiable with " ^
984 CicMetaSubst.ppterm metasubst' typeofvar)))
986 (* FIXME: no mere tail recursive! *)
987 let exp_name_subst, metasubst''', metasenv''', ugraph4 =
988 check_exp_named_subst_aux
989 metasubst'' metasenv'' (substs@[subst]) tl ugraph3
991 ((uri,t')::exp_name_subst), metasubst''', metasenv''', ugraph4
993 check_exp_named_subst_aux metasubst metasenv [] tl ugraph
996 and sort_of_prod subst metasenv context (name,s) (t1, t2) ugraph =
997 let module C = Cic in
998 let context_for_t2 = (Some (name,C.Decl s))::context in
999 let t1'' = CicReduction.whd ~subst context t1 in
1000 let t2'' = CicReduction.whd ~subst context_for_t2 t2 in
1001 match (t1'', t2'') with
1002 (C.Sort s1, C.Sort s2)
1003 when (s2 = C.Prop or s2 = C.Set or s2 = C.CProp) ->
1004 (* different than Coq manual!!! *)
1005 C.Sort s2,subst,metasenv,ugraph
1006 | (C.Sort (C.Type t1), C.Sort (C.Type t2)) ->
1007 let t' = CicUniv.fresh() in
1008 let ugraph1 = CicUniv.add_ge t' t1 ugraph in
1009 let ugraph2 = CicUniv.add_ge t' t2 ugraph1 in
1010 C.Sort (C.Type t'),subst,metasenv,ugraph2
1011 | (C.Sort _,C.Sort (C.Type t1)) ->
1012 C.Sort (C.Type t1),subst,metasenv,ugraph
1013 | (C.Meta _, C.Sort _) -> t2'',subst,metasenv,ugraph
1014 | (C.Sort _,C.Meta _) | (C.Meta _,C.Meta _) ->
1015 (* TODO how can we force the meta to become a sort? If we don't we
1016 * brake the invariant that refine produce only well typed terms *)
1017 (* TODO if we check the non meta term and if it is a sort then we
1018 * are likely to know the exact value of the result e.g. if the rhs
1019 * is a Sort (Prop | Set | CProp) then the result is the rhs *)
1020 let (metasenv,idx) =
1021 CicMkImplicit.mk_implicit_sort metasenv subst in
1022 let (subst, metasenv,ugraph1) =
1023 fo_unif_subst subst context_for_t2 metasenv
1024 (C.Meta (idx,[])) t2'' ugraph
1026 t2'',subst,metasenv,ugraph1
1032 ("Two sorts were expected, found %s " ^^
1033 "(that reduces to %s) and %s (that reduces to %s)")
1034 (CicPp.ppterm t1) (CicPp.ppterm t1'') (CicPp.ppterm t2)
1035 (CicPp.ppterm t2''))))
1038 allow_coercions subst metasenv context hetype tlbody_and_type ugraph
1040 let rec mk_prod metasenv context =
1043 let (metasenv, idx) =
1044 CicMkImplicit.mk_implicit_type metasenv subst context
1047 CicMkImplicit.identity_relocation_list_for_metavariable context
1049 metasenv,Cic.Meta (idx, irl)
1051 let (metasenv, idx) =
1052 CicMkImplicit.mk_implicit_type metasenv subst context
1055 CicMkImplicit.identity_relocation_list_for_metavariable context
1057 let meta = Cic.Meta (idx,irl) in
1059 (* The name must be fresh for context. *)
1060 (* Nevertheless, argty is well-typed only in context. *)
1061 (* Thus I generate a name (name_hint) in context and *)
1062 (* then I generate a name --- using the hint name_hint *)
1063 (* --- that is fresh in (context'@context). *)
1065 (* Cic.Name "pippo" *)
1066 FreshNamesGenerator.mk_fresh_name ~subst metasenv
1067 (* (CicMetaSubst.apply_subst_metasenv subst metasenv) *)
1068 (CicMetaSubst.apply_subst_context subst context)
1070 ~typ:(CicMetaSubst.apply_subst subst argty)
1072 (* [] and (Cic.Sort Cic.prop) are dummy: they will not be used *)
1073 FreshNamesGenerator.mk_fresh_name ~subst
1074 [] context name_hint ~typ:(Cic.Sort Cic.Prop)
1076 let metasenv,target =
1077 mk_prod metasenv ((Some (name, Cic.Decl meta))::context) tl
1079 metasenv,Cic.Prod (name,meta,target)
1081 let metasenv,hetype' = mk_prod metasenv context tlbody_and_type in
1082 let (subst, metasenv,ugraph1) =
1084 fo_unif_subst subst context metasenv hetype hetype' ugraph
1086 debug_print (lazy (Printf.sprintf "hetype=%s\nhetype'=%s\nmetasenv=%s\nsubst=%s"
1087 (CicPp.ppterm hetype)
1088 (CicPp.ppterm hetype')
1089 (CicMetaSubst.ppmetasenv [] metasenv)
1090 (CicMetaSubst.ppsubst subst)));
1094 let rec eat_prods metasenv subst context hetype ugraph =
1096 | [] -> [],metasenv,subst,hetype,ugraph
1097 | (hete, hety)::tl ->
1100 let arg,subst,metasenv,ugraph1 =
1102 let subst,metasenv,ugraph1 =
1103 fo_unif_subst subst context metasenv hety s ugraph
1105 hete,subst,metasenv,ugraph1
1106 with exn when allow_coercions ->
1107 (* we search a coercion from hety to s *)
1109 let carr t subst context =
1110 CicMetaSubst.apply_subst subst t
1112 let c_hety = carr hety subst context in
1113 let c_s = carr s subst context in
1114 CoercGraph.look_for_coercion c_hety c_s
1117 | CoercGraph.NoCoercion
1118 | CoercGraph.NotHandled _ ->
1121 CicMetaSubst.ppterm_in_context subst hete
1122 context ^ " has type " ^
1123 CicMetaSubst.ppterm_in_context subst hety
1124 context ^ " but is here used with type " ^
1125 CicMetaSubst.ppterm_in_context subst s context
1126 (* "\nReason: " ^ Lazy.force e*))
1129 | CoercGraph.NotMetaClosed ->
1130 raise (Uncertain (lazy "Coercions on meta"))
1131 | CoercGraph.SomeCoercion c ->
1132 (Cic.Appl [ c ; hete ]), subst, metasenv, ugraph
1134 let coerced_args,metasenv',subst',t',ugraph2 =
1135 eat_prods metasenv subst context
1136 (CicSubstitution.subst arg t) ugraph1 tl
1138 arg::coerced_args,metasenv',subst',t',ugraph2
1142 let coerced_args,metasenv,subst,t,ugraph2 =
1143 eat_prods metasenv subst context hetype' ugraph1 tlbody_and_type
1145 coerced_args,t,subst,metasenv,ugraph2
1148 (* eat prods ends here! *)
1150 let t',ty,subst',metasenv',ugraph1 =
1151 type_of_aux [] metasenv context t ugraph
1153 let substituted_t = CicMetaSubst.apply_subst subst' t' in
1154 let substituted_ty = CicMetaSubst.apply_subst subst' ty in
1155 (* Andrea: ho rimesso qui l'applicazione della subst al
1156 metasenv dopo che ho droppato l'invariante che il metsaenv
1157 e' sempre istanziato *)
1158 let substituted_metasenv =
1159 CicMetaSubst.apply_subst_metasenv subst' metasenv' in
1161 (* substituted_t,substituted_ty,substituted_metasenv *)
1162 (* ANDREA: spostare tutta questa robaccia da un altra parte *)
1164 FreshNamesGenerator.clean_dummy_dependent_types substituted_t in
1166 FreshNamesGenerator.clean_dummy_dependent_types substituted_ty in
1167 let cleaned_metasenv =
1169 (function (n,context,ty) ->
1170 let ty' = FreshNamesGenerator.clean_dummy_dependent_types ty in
1175 | Some (n, Cic.Decl t) ->
1177 Cic.Decl (FreshNamesGenerator.clean_dummy_dependent_types t))
1178 | Some (n, Cic.Def (bo,ty)) ->
1179 let bo' = FreshNamesGenerator.clean_dummy_dependent_types bo in
1184 Some (FreshNamesGenerator.clean_dummy_dependent_types ty)
1186 Some (n, Cic.Def (bo',ty'))
1190 ) substituted_metasenv
1192 (cleaned_t,cleaned_ty,cleaned_metasenv,ugraph1)
1195 let type_of_aux' metasenv context term ugraph =
1197 type_of_aux' metasenv context term ugraph
1199 CicUniv.UniverseInconsistency msg -> raise (RefineFailure (lazy msg))
1201 let undebrujin uri typesno tys t =
1204 (fun (name,_,_,_) (i,t) ->
1205 (* here the explicit_named_substituion is assumed to be *)
1207 let t' = Cic.MutInd (uri,i,[]) in
1208 let t = CicSubstitution.subst t' t in
1210 ) tys (typesno - 1,t))
1212 let map_first_n n start f g l =
1213 let rec aux acc k l =
1216 | [] -> raise (Invalid_argument "map_first_n")
1217 | hd :: tl -> f hd k (aux acc (k+1) tl)
1223 (*CSC: this is a very rough approximation; to be finished *)
1224 let are_all_occurrences_positive metasenv ugraph uri tys leftno =
1225 let number_of_types = List.length tys in
1226 let subst,metasenv,ugraph,tys =
1228 (fun (name,ind,arity,cl) (subst,metasenv,ugraph,acc) ->
1229 let subst,metasenv,ugraph,cl =
1231 (fun (name,ty) (subst,metasenv,ugraph,acc) ->
1232 let rec aux ctx k subst = function
1233 | Cic.Appl((Cic.MutInd (uri',_,_)as hd)::tl) when uri = uri'->
1234 let subst,metasenv,ugraph,tl =
1236 (subst,metasenv,ugraph,[])
1237 (fun t n (subst,metasenv,ugraph,acc) ->
1238 let subst,metasenv,ugraph =
1240 subst ctx metasenv t (Cic.Rel (k-n)) ugraph
1242 subst,metasenv,ugraph,(t::acc))
1243 (fun (s,m,g,acc) tl -> assert(acc=[]);(s,m,g,tl))
1246 subst,metasenv,ugraph,(Cic.Appl (hd::tl))
1247 | Cic.MutInd(uri',_,_) as t when uri = uri'->
1248 subst,metasenv,ugraph,t
1249 | Cic.Prod (name,s,t) ->
1250 let ctx = (Some (name,Cic.Decl s))::ctx in
1251 let subst,metasenv,ugraph,t = aux ctx (k+1) subst t in
1252 subst,metasenv,ugraph,Cic.Prod (name,s,t)
1256 (lazy "not well formed constructor type"))
1258 let subst,metasenv,ugraph,ty = aux [] 0 subst ty in
1259 subst,metasenv,ugraph,(name,ty) :: acc)
1260 cl (subst,metasenv,ugraph,[])
1262 subst,metasenv,ugraph,(name,ind,arity,cl)::acc)
1263 tys ([],metasenv,ugraph,[])
1265 let substituted_tys =
1267 (fun (name,ind,arity,cl) ->
1269 List.map (fun (name, ty) -> name,CicMetaSubst.apply_subst subst ty) cl
1271 name,ind,CicMetaSubst.apply_subst subst arity,cl)
1274 metasenv,ugraph,substituted_tys
1276 let typecheck metasenv uri obj =
1277 let ugraph = CicUniv.empty_ugraph in
1279 Cic.Constant (name,Some bo,ty,args,attrs) ->
1280 let bo',boty,metasenv,ugraph = type_of_aux' metasenv [] bo ugraph in
1281 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1282 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1283 let bo' = CicMetaSubst.apply_subst subst bo' in
1284 let ty' = CicMetaSubst.apply_subst subst ty' in
1285 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1286 Cic.Constant (name,Some bo',ty',args,attrs),metasenv,ugraph
1287 | Cic.Constant (name,None,ty,args,attrs) ->
1288 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1289 Cic.Constant (name,None,ty',args,attrs),metasenv,ugraph
1290 | Cic.CurrentProof (name,metasenv',bo,ty,args,attrs) ->
1291 assert (metasenv' = metasenv);
1292 (* Here we do not check the metasenv for correctness *)
1293 let bo',boty,metasenv,ugraph = type_of_aux' metasenv [] bo ugraph in
1294 let ty',sort,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1298 (* instead of raising Uncertain, let's hope that the meta will become
1301 | _ -> raise (RefineFailure (lazy "The term provided is not a type"))
1303 let subst,metasenv,ugraph = fo_unif_subst [] [] metasenv boty ty' ugraph in
1304 let bo' = CicMetaSubst.apply_subst subst bo' in
1305 let ty' = CicMetaSubst.apply_subst subst ty' in
1306 let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
1307 Cic.CurrentProof (name,metasenv,bo',ty',args,attrs),metasenv,ugraph
1308 | Cic.Variable _ -> assert false (* not implemented *)
1309 | Cic.InductiveDefinition (tys,args,paramsno,attrs) ->
1310 (*CSC: this code is greately simplified and many many checks are missing *)
1311 (*CSC: e.g. the constructors are not required to build their own types, *)
1312 (*CSC: the arities are not required to have as type a sort, etc. *)
1313 let uri = match uri with Some uri -> uri | None -> assert false in
1314 let typesno = List.length tys in
1315 (* first phase: we fix only the types *)
1316 let metasenv,ugraph,tys =
1318 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
1319 let ty',_,metasenv,ugraph = type_of_aux' metasenv [] ty ugraph in
1320 metasenv,ugraph,(name,b,ty',cl)::res
1321 ) tys (metasenv,ugraph,[]) in
1323 List.rev_map (fun (name,_,ty,_)-> Some (Cic.Name name,Cic.Decl ty)) tys in
1324 (* second phase: we fix only the constructors *)
1325 let metasenv,ugraph,tys =
1327 (fun (name,b,ty,cl) (metasenv,ugraph,res) ->
1328 let metasenv,ugraph,cl' =
1330 (fun (name,ty) (metasenv,ugraph,res) ->
1331 let ty = CicTypeChecker.debrujin_constructor uri typesno ty in
1332 let ty',_,metasenv,ugraph =
1333 type_of_aux' metasenv con_context ty ugraph in
1334 let ty' = undebrujin uri typesno tys ty' in
1335 metasenv,ugraph,(name,ty')::res
1336 ) cl (metasenv,ugraph,[])
1338 metasenv,ugraph,(name,b,ty,cl')::res
1339 ) tys (metasenv,ugraph,[]) in
1340 (* third phase: we check the positivity condition *)
1341 let metasenv,ugraph,tys =
1342 are_all_occurrences_positive metasenv ugraph uri tys paramsno
1344 Cic.InductiveDefinition (tys,args,paramsno,attrs),metasenv,ugraph
1347 let type_of_aux' metasenv context term =
1350 type_of_aux' metasenv context term in
1352 ("@@@ REFINE SUCCESSFUL: " ^ CicPp.ppterm t ^ " : " ^ CicPp.ppterm ty));
1354 ("@@@ REFINE SUCCESSFUL (metasenv):\n" ^ CicMetaSubst.ppmetasenv ~sep:";" m []));
1357 | RefineFailure msg as e ->
1358 debug_print (lazy ("@@@ REFINE FAILED: " ^ msg));
1360 | Uncertain msg as e ->
1361 debug_print (lazy ("@@@ REFINE UNCERTAIN: " ^ msg));
1365 let profiler2 = HExtlib.profile "CicRefine"
1367 let type_of_aux' metasenv context term ugraph =
1368 profiler2.HExtlib.profile (type_of_aux' metasenv context term) ugraph
1370 let typecheck metasenv uri obj =
1371 profiler2.HExtlib.profile (typecheck metasenv uri) obj