2 Declaration of Cic.name * Cic.term
3 | Definition of Cic.name * Cic.term
6 type metasenv = (int * Cic.term) list;;
8 type named_context = binder_type list;;
10 type sequent = named_context * Cic.term;;
13 ref (None : (UriManager.uri * metasenv * Cic.term * Cic.term) option)
15 (*CSC: Quando facciamo Clear di una ipotesi, cosa succede? *)
16 (* Note: the sequent is redundant: it can be computed from the type of the *)
17 (* metavariable and its context in the proof. We keep it just for efficiency *)
18 (* because computing the context of a term may be quite expensive. *)
19 let goal = ref (None : (int * sequent) option);;
21 exception NotImplemented
23 let cic_context_of_named_context =
26 Declaration (_,t) -> Cic.Decl t
27 | Definition (_,t) -> Cic.Def t
31 (* refine_meta_with_brand_new_metasenv meta term apply_subst_replacing *)
33 (* This (heavy) function must be called when a tactic can instantiate old *)
34 (* metavariables (i.e. existential variables). It substitues the metasenv *)
35 (* of the proof with the result of removing [meta] from the domain of *)
36 (* [newmetasenv]. Then it replaces Cic.Meta [meta] with [term] everywhere *)
37 (* in the current proof. Finally it applies [apply_subst_replacing] to *)
39 (*CSC: A questo punto perche' passare un bo' gia' istantiato, se tanto poi *)
40 (*CSC: ci ripasso sopra apply_subst!!! *)
41 (*CSC: Inoltre, potrebbe essere questa funzione ad applicare apply_subst a *)
42 (*CSC: newmetasenv!!! *)
43 let refine_meta_with_brand_new_metasenv meta term apply_subst_replacing
49 | Some (uri,_,bo,ty) -> uri,bo,ty
52 ProofEngineReduction.replace ~what:(Cic.Meta meta) ~with_what:term ~where:t
54 let bo' = apply_subst_replacing (subst_in bo) in
55 let metasenv' = List.remove_assoc meta newmetasenv in
56 proof := Some (uri,metasenv',bo',ty)
59 let refine_meta meta term newmetasenv =
60 let (uri,metasenv,bo,ty) =
63 | Some (uri,metasenv,bo,ty) -> uri,metasenv,bo,ty
66 ProofEngineReduction.replace ~what:(Cic.Meta meta) ~with_what:term ~where:t
68 let metasenv' = newmetasenv @ (List.remove_assoc meta metasenv) in
69 let metasenv'' = List.map (function i,ty -> i,(subst_in ty)) metasenv' in
70 let bo' = subst_in bo in
71 proof := Some (uri,metasenv'',bo',ty)
74 (* Returns the first meta whose number is above the *)
75 (* number of the higher meta. *)
80 | Some (_,metasenv,_,_) -> metasenv
86 | None,(n,_)::tl -> aux (Some n,tl)
87 | Some m,(n,_)::tl -> if n > m then aux (Some n,tl) else aux (Some m,tl)
89 1 + aux (None,metasenv)
92 (* metas_in_term term *)
93 (* Returns the ordered list of the metas that occur in [term]. *)
94 (* Duplicates are removed. The implementation is not very efficient. *)
95 let metas_in_term term =
104 | C.Cast (te,ty) -> (aux te) @ (aux ty)
105 | C.Prod (_,s,t) -> (aux s) @ (aux t)
106 | C.Lambda (_,s,t) -> (aux s) @ (aux t)
107 | C.LetIn (_,s,t) -> (aux s) @ (aux t)
108 | C.Appl l -> List.fold_left (fun i t -> i @ (aux t)) [] l
112 | C.MutConstruct _ -> []
113 | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
114 (aux outt) @ (aux t) @
115 (List.fold_left (fun i t -> i @ (aux t)) [] pl)
117 List.fold_left (fun i (_,_,ty,bo) -> i @ (aux bo) @ (aux ty)) [] fl
119 List.fold_left (fun i (_,ty,bo) -> i @ (aux bo) @ (aux ty)) [] fl
121 let metas = aux term in
122 let rec elim_duplicates =
126 he::(elim_duplicates (List.filter (function el -> he <> el) tl))
128 elim_duplicates metas
131 (* perforate context term ty *)
132 (* replaces the term [term] in the proof with a new metavariable whose type *)
133 (* is [ty]. [context] must be the context of [term] in the whole proof. This *)
134 (* could be easily computed; so the only reasons to have it as an argument *)
135 (* are efficiency reasons. *)
136 let perforate context term ty =
137 let module C = Cic in
138 let newmeta = new_meta () in
141 | Some (uri,metasenv,bo,gty) ->
142 (* We push the new meta at the end of the list for pretty-printing *)
143 (* purposes: in this way metas are ordered. *)
144 let metasenv' = metasenv@[newmeta,ty] in
145 let bo' = ProofEngineReduction.replace term (C.Meta newmeta) bo in
146 (* It may be possible that some metavariables occurred only in *)
147 (* the term we are perforating and they now occurs no more. We *)
148 (* get rid of them, collecting the really useful metavariables *)
150 let newmetas = metas_in_term bo' in
152 List.filter (function (n,_) -> List.mem n newmetas) metasenv'
154 proof := Some (uri,metasenv'',bo',gty) ;
155 goal := Some (newmeta,(context,ty)) ;
159 (************************************************************)
160 (* Some easy tactics. *)
161 (************************************************************)
163 exception Fail of string;;
165 (*CSC: generatore di nomi? Chiedere il nome? *)
167 let next_fresh_index = ref 0
170 incr next_fresh_index ;
171 "fresh_name" ^ string_of_int !next_fresh_index
174 (* lambda_abstract newmeta ty *)
175 (* returns a triple [bo],[context],[ty'] where *)
176 (* [ty] = Pi/LetIn [context].[ty'] ([context] is a vector!) *)
177 (* and [bo] = Lambda/LetIn [context].(Meta [newmeta]) *)
178 (* So, lambda_abstract is the core of the implementation of *)
179 (* the Intros tactic. *)
180 let lambda_abstract newmeta ty =
181 let module C = Cic in
182 let rec collect_context =
184 C.Cast (te,_) -> collect_context te
186 let (ctx,ty,bo) = collect_context t in
190 (*CSC: generatore di nomi? Chiedere il nome? *)
191 | C.Anonimous -> C.Name (fresh_name ())
193 ((Declaration (n',s))::ctx,ty,C.Lambda(n',s,bo))
195 let (ctx,ty,bo) = collect_context t in
196 ((Definition (n,s))::ctx,ty,C.LetIn(n,s,bo))
197 | _ as t -> [], t, (C.Meta newmeta)
199 let revcontext,ty',bo = collect_context ty in
200 bo,(List.rev revcontext),ty'
204 let module C = Cic in
205 let module R = CicReduction in
209 | Some (_,metasenv,_,_) -> metasenv
211 let (metano,context,ty) =
214 | Some (metano,(context,ty)) -> metano,context,ty
216 let newmeta = new_meta () in
217 let (bo',newcontext,ty') = lambda_abstract newmeta ty in
218 let context'' = newcontext @ context in
219 refine_meta metano bo' [newmeta,ty'] ;
220 goal := Some (newmeta,(context'',ty'))
223 (* The term bo must be closed in the current context *)
225 let module T = CicTypeChecker in
226 let module R = CicReduction in
230 | Some (_,metasenv,_,_) -> metasenv
232 let (metano,context,ty) =
235 | Some (metano,(context,ty)) ->
236 assert (ty = List.assoc metano metasenv) ;
237 (* Invariant: context is the actual context of the meta in the proof *)
240 let context = cic_context_of_named_context context in
241 if R.are_convertible context (T.type_of_aux' metasenv context bo) ty then
243 refine_meta metano bo [] ;
247 raise (Fail "The type of the provided term is not the one expected.")
250 (*CSC: The call to the Intros tactic is embedded inside the code of the *)
251 (*CSC: Elim tactic. Do we already need tacticals? *)
252 (* Auxiliary function for apply: given a type (a backbone), it returns its *)
253 (* head, a META environment in which there is new a META for each hypothesis,*)
254 (* a list of arguments for the new applications and the indexes of the first *)
255 (* and last new METAs introduced. The nth argument in the list of arguments *)
256 (* is the nth new META lambda-abstracted as much as possible. Hence, this *)
257 (* functions already provides the behaviour of Intros on the new goals. *)
258 let new_metasenv_for_apply_intros ty =
259 let module C = Cic in
260 let module S = CicSubstitution in
261 let rec aux newmeta =
263 C.Cast (he,_) -> aux newmeta he
265 let newargument,newcontext,ty' = lambda_abstract newmeta s in
266 let (res,newmetasenv,arguments,lastmeta) =
267 aux (newmeta + 1) (S.subst newargument t)
269 res,(newmeta,ty')::newmetasenv,newargument::arguments,lastmeta
270 | t -> t,[],[],newmeta
272 let newmeta = new_meta () in
273 (* WARNING: here we are using the invariant that above the most *)
274 (* recente new_meta() there are no used metas. *)
275 let (res,newmetasenv,arguments,lastmeta) = aux newmeta ty in
276 res,newmetasenv,arguments,newmeta,lastmeta
279 (* Auxiliary function for apply: given a type (a backbone), it returns its *)
280 (* head, a META environment in which there is new a META for each hypothesis,*)
281 (* a list of arguments for the new applications and the indexes of the first *)
282 (* and last new METAs introduced. The nth argument in the list of arguments *)
283 (* is just the nth new META. *)
284 let new_metasenv_for_apply ty =
285 let module C = Cic in
286 let module S = CicSubstitution in
287 let rec aux newmeta =
289 C.Cast (he,_) -> aux newmeta he
291 let newargument = C.Meta newmeta in
292 let (res,newmetasenv,arguments,lastmeta) =
293 aux (newmeta + 1) (S.subst newargument t)
295 res,(newmeta,s)::newmetasenv,newargument::arguments,lastmeta
296 | t -> t,[],[],newmeta
298 let newmeta = new_meta () in
299 (* WARNING: here we are using the invariant that above the most *)
300 (* recente new_meta() there are no used metas. *)
301 let (res,newmetasenv,arguments,lastmeta) = aux newmeta ty in
302 res,newmetasenv,arguments,newmeta,lastmeta
306 (*CSC: ma serve solamente la prima delle new_uninst e l'unione delle due!!! *)
307 let classify_metas newmeta in_subst_domain apply_subst metasenv =
309 (fun (i,ty) (old_uninst,new_uninst) ->
310 if in_subst_domain i then
311 old_uninst,new_uninst
313 let ty' = apply_subst ty in
315 ((i,ty')::old_uninst),new_uninst
317 old_uninst,((i,ty')::new_uninst)
321 (* The term bo must be closed in the current context *)
323 let module T = CicTypeChecker in
324 let module R = CicReduction in
325 let module C = Cic in
329 | Some (_,metasenv,_,_) -> metasenv
331 let (metano,context,ty) =
334 | Some (metano,(context,ty)) ->
335 assert (ty = List.assoc metano metasenv) ;
336 (* Invariant: context is the actual context of the meta in the proof *)
339 let ciccontext = cic_context_of_named_context context in
340 let termty = CicTypeChecker.type_of_aux' metasenv ciccontext term in
341 (* newmeta is the lowest index of the new metas introduced *)
342 let (consthead,newmetas,arguments,newmeta,_) =
343 new_metasenv_for_apply termty
345 let newmetasenv = newmetas@metasenv in
346 let subst = CicUnification.fo_unif newmetasenv ciccontext consthead ty in
347 let in_subst_domain i = List.exists (function (j,_) -> i=j) subst in
348 let apply_subst = CicUnification.apply_subst subst in
349 (*CSC: estremamente inefficiente: fare una passata sola per rimpiazzarle tutte*)
350 let apply_subst_replacing t =
353 ProofEngineReduction.replace
354 ~what:(Cic.Meta i) ~with_what:bo ~where:t)
357 let old_uninstantiatedmetas,new_uninstantiatedmetas =
358 classify_metas newmeta in_subst_domain apply_subst newmetasenv
361 if List.length newmetas = 0 then
364 let arguments' = List.map apply_subst arguments in
365 Cic.Appl (term::arguments')
367 refine_meta_with_brand_new_metasenv metano bo' apply_subst_replacing
368 (new_uninstantiatedmetas@old_uninstantiatedmetas) ;
369 match new_uninstantiatedmetas with
371 | (i,ty)::_ -> goal := Some (i,(context,ty))
374 let eta_expand metasenv ciccontext t arg =
375 let module T = CicTypeChecker in
376 let module S = CicSubstitution in
377 let module C = Cic in
380 t' when t' = S.lift n arg -> C.Rel (1 + n)
381 | C.Rel m -> if m <= n then C.Rel m else C.Rel (m+1)
385 | C.Implicit as t -> t
386 | C.Cast (te,ty) -> C.Cast (aux n te, aux n ty)
387 | C.Prod (nn,s,t) -> C.Prod (nn, aux n s, aux (n+1) t)
388 | C.Lambda (nn,s,t) -> C.Lambda (nn, aux n s, aux (n+1) t)
389 | C.LetIn (nn,s,t) -> C.LetIn (nn, aux n s, aux (n+1) t)
390 | C.Appl l -> C.Appl (List.map (aux n) l)
391 | C.Const _ as t -> t
392 | C.Abst _ -> assert false
394 | C.MutConstruct _ as t -> t
395 | C.MutCase (sp,cookingsno,i,outt,t,pl) ->
396 C.MutCase (sp,cookingsno,i,aux n outt, aux n t,
399 let tylen = List.length fl in
402 (fun (name,i,ty,bo) -> (name, i, aux n ty, aux (n+tylen) bo))
405 C.Fix (i, substitutedfl)
407 let tylen = List.length fl in
410 (fun (name,ty,bo) -> (name, aux n ty, aux (n+tylen) bo))
413 C.CoFix (i, substitutedfl)
416 T.type_of_aux' metasenv ciccontext arg
418 (C.Appl [C.Lambda ((C.Name "dummy"),argty,aux 0 t) ; arg])
421 exception NotAnInductiveTypeToEliminate;;
422 exception NotTheRightEliminatorShape;;
423 exception NoHypothesesFound;;
425 let elim_intros term =
426 let module T = CicTypeChecker in
427 let module U = UriManager in
428 let module R = CicReduction in
429 let module C = Cic in
433 | Some (curi,metasenv,_,_) -> curi,metasenv
435 let (metano,context,ty) =
438 | Some (metano,(context,ty)) ->
439 assert (ty = List.assoc metano metasenv) ;
440 (* Invariant: context is the actual context of the meta in the proof *)
443 let ciccontext = cic_context_of_named_context context in
444 let termty = T.type_of_aux' metasenv ciccontext term in
445 let uri,cookingno,typeno,args =
447 C.MutInd (uri,cookingno,typeno) -> (uri,cookingno,typeno,[])
448 | C.Appl ((C.MutInd (uri,cookingno,typeno))::args) ->
449 (uri,cookingno,typeno,args)
450 | _ -> raise NotAnInductiveTypeToEliminate
453 let buri = U.buri_of_uri uri in
455 match CicEnvironment.get_cooked_obj uri cookingno with
456 C.InductiveDefinition (tys,_,_) ->
457 let (name,_,_,_) = List.nth tys typeno in
462 match T.type_of_aux' metasenv ciccontext ty with
463 C.Sort C.Prop -> "_ind"
464 | C.Sort C.Set -> "_rec"
465 | C.Sort C.Type -> "_rect"
468 U.uri_of_string (buri ^ "/" ^ name ^ ext ^ ".con")
470 let eliminator_cookingno =
471 UriManager.relative_depth curi eliminator_uri 0
473 let eliminator_ref = C.Const (eliminator_uri,eliminator_cookingno) in
475 T.type_of_aux' [] [] eliminator_ref
477 let (econclusion,newmetas,arguments,newmeta,lastmeta) =
478 new_metasenv_for_apply ety
480 (* Here we assume that we have only one inductive hypothesis to *)
481 (* eliminate and that it is the last hypothesis of the theorem. *)
482 (* A better approach would be fingering the hypotheses in some *)
484 let meta_of_corpse = Cic.Meta (lastmeta - 1) in
485 let newmetasenv = newmetas @ metasenv in
486 prerr_endline ("ECONCLUSION: " ^ CicPp.ppterm econclusion) ;
489 CicUnification.fo_unif newmetasenv ciccontext term meta_of_corpse
491 let ueconclusion = CicUnification.apply_subst subst1 econclusion in
492 prerr_endline ("ECONCLUSION DOPO UNWIND: " ^ CicPp.ppterm ueconclusion) ;
494 (* The conclusion of our elimination principle is *)
495 (* (?i farg1 ... fargn) *)
496 (* The conclusion of our goal is ty. So, we can *)
497 (* eta-expand ty w.r.t. farg1 .... fargn to get *)
498 (* a new ty equal to (P farg1 ... fargn). Now *)
499 (* ?i can be instantiated with P and we are ready *)
500 (* to refine the term. *)
502 match ueconclusion with
503 (*CSC: Code to be used for Apply *)
504 C.Appl ((C.Meta emeta)::fargs) -> emeta,fargs
505 | C.Meta emeta -> emeta,[]
506 (*CSC: Code to be used for ApplyIntros
507 C.Appl (he::fargs) ->
510 C.Meta emeta -> emeta
511 | C.Lambda (_,_,t) -> find_head t
512 | C.LetIn (_,_,t) -> find_head t
513 | _ ->raise NotTheRightEliminatorShape
517 | _ -> raise NotTheRightEliminatorShape
519 let ty' = CicUnification.apply_subst subst1 ty in
520 let eta_expanded_ty =
521 List.fold_left (eta_expand metasenv ciccontext) ty' fargs
523 prerr_endline ("ETAEXPANDEDTY:" ^ CicPp.ppterm eta_expanded_ty) ; flush stdout ;
525 (*CSC: passo newmetasenv, ma alcune variabili sono gia' state sostituite
526 da subst1!!!! Dovrei rimuoverle o sono innocue?*)
527 CicUnification.fo_unif
528 newmetasenv ciccontext ueconclusion eta_expanded_ty
530 prerr_endline "Dopo la seconda unificazione" ; flush stdout ;
531 prerr_endline "unwind"; flush stderr;
532 let in_subst_domain i =
533 let eq_to_i = function (j,_) -> i=j in
534 List.exists eq_to_i subst1 ||
535 List.exists eq_to_i subst2
537 (* When unwinding the META that corresponds to the elimination *)
538 (* predicate (which is emeta), we must also perform one-step *)
539 (* beta-reduction. *)
541 let t' = CicUnification.apply_subst subst1 t in
542 CicUnification.apply_subst_reducing
543 subst2 (Some (emeta,List.length fargs)) t'
545 (*CSC: estremamente inefficiente: fare una passata sola per rimpiazzarle tutte*)
546 let apply_subst_replacing t =
550 ProofEngineReduction.replace
551 ~what:(Cic.Meta i) ~with_what:bo ~where:t)
556 ProofEngineReduction.replace
557 ~what:(Cic.Meta i) ~with_what:bo ~where:t)
561 List.map (function (i,ty) -> i, apply_subst ty) newmetasenv
563 let old_uninstantiatedmetas,new_uninstantiatedmetas =
564 classify_metas newmeta in_subst_domain apply_subst newmetasenv
566 let arguments' = List.map apply_subst arguments in
567 let bo' = Cic.Appl (eliminator_ref::arguments') in
568 prerr_endline ("BODY': " ^ CicPp.ppterm bo') ; flush stdout ;
569 List.iter (function (i,t) -> prerr_endline ("?" ^ string_of_int i ^ ": " ^ CicPp.ppterm t)) (new_uninstantiatedmetas@old_uninstantiatedmetas) ; flush stderr ;
570 refine_meta_with_brand_new_metasenv metano bo'
571 apply_subst_replacing
572 (new_uninstantiatedmetas@old_uninstantiatedmetas) ;
573 match new_uninstantiatedmetas with
575 | (i,ty)::_ -> goal := Some (i,(context,ty))
578 let reduction_tactic reduction_function term =
579 let curi,metasenv,pbo,pty =
582 | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
584 let (metano,context,ty) =
587 | Some (metano,(context,ty)) -> metano,context,ty
589 let ciccontext = cic_context_of_named_context context in
590 let term' = reduction_function ciccontext term in
591 (* We don't know if [term] is a subterm of [ty] or a subterm of *)
592 (* the type of one metavariable. So we replace it everywhere. *)
593 (*CSC: ma si potrebbe ovviare al problema. Ma non credo *)
594 (*CSC: che si guadagni nulla in fatto di efficienza. *)
595 let replace = ProofEngineReduction.replace ~what:term ~with_what:term' in
596 let ty' = replace ty in
600 Definition (n,t) -> Definition (n,replace t)
601 | Declaration (n,t) -> Declaration (n,replace t)
607 (n,_) when n = metano -> (metano,ty')
611 proof := Some (curi,metasenv',pbo,pty) ;
612 goal := Some (metano,(context',ty'))
615 let reduction_tactic_in_scratch reduction_function ty term =
619 | Some (_,metasenv,_,_) -> metasenv
624 | Some (_,(context,_)) -> context
626 let ciccontext = cic_context_of_named_context context in
627 let term' = reduction_function ciccontext term in
628 ProofEngineReduction.replace ~what:term ~with_what:term' ~where:ty
631 let whd = reduction_tactic CicReduction.whd;;
632 let reduce = reduction_tactic ProofEngineReduction.reduce;;
633 let simpl = reduction_tactic ProofEngineReduction.simpl;;
635 let whd_in_scratch = reduction_tactic_in_scratch CicReduction.whd;;
636 let reduce_in_scratch =
637 reduction_tactic_in_scratch ProofEngineReduction.reduce;;
638 let simpl_in_scratch =
639 reduction_tactic_in_scratch ProofEngineReduction.simpl;;
641 (* It is just the opposite of whd. The code should probably be merged. *)
643 let curi,metasenv,pbo,pty =
646 | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
648 let (metano,context,ty) =
651 | Some (metano,(context,ty)) -> metano,context,ty
653 let ciccontext = cic_context_of_named_context context in
654 let term' = CicReduction.whd ciccontext term in
655 (* We don't know if [term] is a subterm of [ty] or a subterm of *)
656 (* the type of one metavariable. So we replace it everywhere. *)
657 (*CSC: ma si potrebbe ovviare al problema. Ma non credo *)
658 (*CSC: che si guadagni nulla in fatto di efficienza. *)
659 let replace = ProofEngineReduction.replace ~what:term' ~with_what:term in
660 let ty' = replace ty in
664 Declaration (n,t) -> Declaration (n,replace t)
665 | Definition (n,t) -> Definition (n,replace t)
671 (n,_) when n = metano -> (metano,ty')
675 proof := Some (curi,metasenv',pbo,pty) ;
676 goal := Some (metano,(context',ty'))
680 let module C = Cic in
681 let curi,metasenv,pbo,pty =
684 | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
686 let (metano,context,ty) =
689 | Some (metano,(context,ty)) -> metano,context,ty
691 let newmeta1 = new_meta () in
692 let newmeta2 = newmeta1 + 1 in
693 let newmeta1ty = CicSubstitution.lift 1 ty in
696 [C.Lambda (C.Name "dummy_for_cut",term,C.Meta newmeta1) ;
699 prerr_endline ("BO': " ^ CicPp.ppterm bo') ; flush stderr ;
700 refine_meta metano bo' [newmeta2,term; newmeta1,newmeta1ty];
703 (newmeta1,((Declaration (C.Name "dummy_for_cut", term))::context,
708 let module C = Cic in
709 let curi,metasenv,pbo,pty =
712 | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
714 let (metano,context,ty) =
717 | Some (metano,(context,ty)) -> metano,context,ty
719 let ciccontext = cic_context_of_named_context context in
720 let _ = CicTypeChecker.type_of_aux' metasenv ciccontext term in
721 let newmeta = new_meta () in
722 let newmetaty = CicSubstitution.lift 1 ty in
723 let bo' = C.LetIn (C.Name "dummy_for_letin",term,C.Meta newmeta) in
724 refine_meta metano bo' [newmeta,newmetaty];
728 ((Definition (C.Name "dummy_for_letin", term))::context, newmetaty))
731 exception NotConvertible;;
733 (*CSC: Bug (or feature?). [input] is parsed in the context of the goal, *)
734 (*CSC: while [goal_input] can have a richer context (because of binders) *)
735 (*CSC: So it is _NOT_ possible to use those binders in the [input] term. *)
736 (*CSC: Is that evident? Is that right? Or should it be changed? *)
737 let change ~goal_input ~input =
738 let curi,metasenv,pbo,pty =
741 | Some (curi,metasenv,bo,ty) -> curi,metasenv,bo,ty
743 let (metano,context,ty) =
746 | Some (metano,(context,ty)) -> metano,context,ty
748 let ciccontext = cic_context_of_named_context context in
749 (* are_convertible works only on well-typed terms *)
750 ignore (CicTypeChecker.type_of_aux' metasenv ciccontext input) ;
751 if CicReduction.are_convertible ciccontext goal_input input then
753 let ty' = ProofEngineReduction.replace goal_input input ty in
757 (n,_) when n = metano -> (metano,ty')
761 proof := Some (curi,metasenv',pbo,pty) ;
762 goal := Some (metano,(context,ty'))