* http://cs.unibo.it/helm/.
*)
+(* $Id$ *)
+
(* TODO se ce n'e' piu' di una, prende la prima che trova... sarebbe meglio
chiedere: find dovrebbe restituire una lista di hyp (?) da passare all'utonto con una
if b then n else find (n+1) tl
| _ -> find (n+1) tl
)
- | [] -> raise (PET.Fail "Assumption: No such assumption")
+ | [] -> raise (PET.Fail (lazy "Assumption: No such assumption"))
in PET.apply_tactic (PT.apply_tac ~term:(C.Rel (find 1 context))) status
in
PET.mk_tactic assumption_tac
let module C = Cic in
let module P = PrimitiveTactics in
let module T = Tacticals in
- let _,metasenv,_,_ = proof in
+ let uri,metasenv,pbo,pty = proof in
let (_,context,ty) as conjecture = CicUtil.lookup_meta goal metasenv in
- let selected_hyps,terms_with_context =
- ProofEngineHelpers.select ~metasenv ~conjecture ~pattern in
- let typ,term =
- match terms_with_context, term with
- [], None ->
- raise UnableToDetectTheTermThatMustBeGeneralizedYouMustGiveItExplicitly
- | _, Some term
- | (_,term)::_, None ->
- fst
- (CicTypeChecker.type_of_aux' metasenv context term
- CicUniv.empty_ugraph),
- term in
+ let subst,metasenv,u,selected_hyps,terms_with_context =
+ ProofEngineHelpers.select ~metasenv ~ugraph:CicUniv.empty_ugraph
+ ~conjecture ~pattern in
+ let context = CicMetaSubst.apply_subst_context subst context in
+ let metasenv = CicMetaSubst.apply_subst_metasenv subst metasenv in
+ let pbo = CicMetaSubst.apply_subst subst pbo in
+ let pty = CicMetaSubst.apply_subst subst pty in
+ let term =
+ match term with
+ None -> None
+ | Some term ->
+ Some (fun context metasenv ugraph ->
+ let term, metasenv, ugraph = term context metasenv ugraph in
+ CicMetaSubst.apply_subst subst term,
+ CicMetaSubst.apply_subst_metasenv subst metasenv,
+ ugraph)
+ in
+ let u,typ,term, metasenv' =
+ let context_of_t, (t, metasenv, u) =
+ match terms_with_context, term with
+ [], None ->
+ raise
+ UnableToDetectTheTermThatMustBeGeneralizedYouMustGiveItExplicitly
+ | [], Some t -> context, t context metasenv u
+ | (context_of_t, _)::_, Some t ->
+ context_of_t, t context_of_t metasenv u
+ | (context_of_t, t)::_, None -> context_of_t, (t, metasenv, u)
+ in
+ let t,subst,metasenv' =
+ try
+ CicMetaSubst.delift_rels [] metasenv
+ (List.length context_of_t - List.length context) t
+ with
+ CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
+ raise TheSelectedTermsMustLiveInTheGoalContext
+ in
+ (*CSC: I am not sure about the following two assertions;
+ maybe I need to propagate the new subst and metasenv *)
+ assert (subst = []);
+ assert (metasenv' = metasenv);
+ let typ,u = CicTypeChecker.type_of_aux' ~subst metasenv context t u in
+ u,typ,t,metasenv
+ in
(* We need to check:
1. whether they live in the context of the goal;
if they do they are also well-typed since they are closed subterms
2. whether they are convertible
*)
ignore (
- (* TASSI: FIXME *)
List.fold_left
(fun u (context_of_t,t) ->
(* 1 *)
- begin
+ let t,subst,metasenv'' =
try
- ignore
- (CicMetaSubst.delift_rels [] metasenv
- (List.length context_of_t - List.length context) t)
+ CicMetaSubst.delift_rels [] metasenv'
+ (List.length context_of_t - List.length context) t
with
CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
- raise TheSelectedTermsMustLiveInTheGoalContext
- end;
+ raise TheSelectedTermsMustLiveInTheGoalContext in
+ (*CSC: I am not sure about the following two assertions;
+ maybe I need to propagate the new subst and metasenv *)
+ assert (subst = []);
+ assert (metasenv'' = metasenv');
(* 2 *)
- let b,u1 = CicReduction.are_convertible context term t u in
+ let b,u1 = CicReduction.are_convertible ~subst context term t u in
if not b then
raise AllSelectedTermsMustBeConvertible
else
u1
- ) CicUniv.empty_ugraph terms_with_context) ;
- PET.apply_tactic
- (T.thens
- ~start:
- (P.cut_tac
- (C.Prod(
- (mk_fresh_name_callback metasenv context C.Anonymous ~typ:typ),
- typ,
- (ProofEngineReduction.replace_lifting_csc 1
- ~equality:(==)
- ~what:(List.map snd terms_with_context)
- ~with_what:(List.map (function _ -> C.Rel 1) terms_with_context)
- ~where:ty)
- )))
- ~continuations:
- [(P.apply_tac ~term:(C.Appl [C.Rel 1; CicSubstitution.lift 1 term])) ;
- T.id_tac])
- status
+ ) u terms_with_context) ;
+ let status = (uri,metasenv',pbo,pty),goal in
+ let proof,goals =
+ PET.apply_tactic
+ (T.thens
+ ~start:
+ (P.cut_tac
+ (C.Prod(
+ (mk_fresh_name_callback metasenv context C.Anonymous ~typ:typ),
+ typ,
+ (ProofEngineReduction.replace_lifting_csc 1
+ ~equality:(==)
+ ~what:(List.map snd terms_with_context)
+ ~with_what:(List.map (function _ -> C.Rel 1) terms_with_context)
+ ~where:ty)
+ )))
+ ~continuations:
+ [(P.apply_tac ~term:(C.Appl [C.Rel 1; CicSubstitution.lift 1 term])) ;
+ T.id_tac])
+ status
+ in
+ let _,metasenv'',_,_ = proof in
+ (* CSC: the following is just a bad approximation since a meta
+ can be closed and then re-opened! *)
+ (proof,
+ goals @
+ (List.filter
+ (fun j -> List.exists (fun (i,_,_) -> i = j) metasenv'')
+ (ProofEngineHelpers.compare_metasenvs ~oldmetasenv:metasenv
+ ~newmetasenv:metasenv')))
in
PET.mk_tactic (generalize_tac mk_fresh_name_callback ~pattern)
;;