(* FG: we find the predicate for the eliminator as in the rewrite tactic ****)
let argty, _ugraph = TC.type_of_aux' metasenv context arg ugraph in
let argty = CicReduction.whd context argty in
- let fresh_name =
+ let fresh_name =
FreshNamesGenerator.mk_fresh_name
- ~subst:[] metasenv context' C.Anonymous ~typ:argty
- in
+ ~subst:[] metasenv context' C.Anonymous ~typ:argty in
let hyp = Some (fresh_name, C.Decl argty) in
let lazy_term c m u =
- let distance = List.length c - List.length context in
- S.lift distance arg, m, u
- in
+ let distance = List.length c - List.length context in
+ S.lift distance arg, m, u in
let pattern = Some lazy_term, [], Some cpattern' in
let subst, metasenv, _ugraph, _conjecture, selected_terms =
- ProofEngineHelpers.select
- ~metasenv ~ugraph ~conjecture:(0, context, pred) ~pattern
- in
+ ProofEngineHelpers.select ~metasenv ~ugraph
+ ~conjecture:(0, context, pred) ~pattern in
let metasenv = MS.apply_subst_metasenv subst metasenv in
let map (_context_of_t, t) l = t :: l in
let what = List.fold_right map selected_terms [] in
PET.apply_tactic tactic status
in
PET.mk_tactic beta_after_elim_tac
-
+
+(* ANCORA DA DEBUGGARE *)
+
+exception UnableToDetectTheTermThatMustBeGeneralizedYouMustGiveItExplicitly;;
+exception TheSelectedTermsMustLiveInTheGoalContext
+exception AllSelectedTermsMustBeConvertible;;
+exception GeneralizationInHypothesesNotImplementedYet;;
+
+let generalize_tac
+ ?(mk_fresh_name_callback = FreshNamesGenerator.mk_fresh_name ~subst:[])
+ pattern
+ =
+ let module PET = ProofEngineTypes in
+ let generalize_tac mk_fresh_name_callback
+ ~pattern:(term,hyps_pat,concl_pat) status
+ =
+ if hyps_pat <> [] then raise GeneralizationInHypothesesNotImplementedYet;
+ let (proof, goal) = status in
+ let module C = Cic in
+ let module T = Tacticals in
+ let uri,metasenv,_subst,pbo,pty, attrs = proof in
+ let (_,context,ty) as conjecture = CicUtil.lookup_meta goal metasenv in
+ let subst,metasenv,u,selected_hyps,terms_with_context =
+ ProofEngineHelpers.select ~metasenv ~ugraph:CicUniv.oblivion_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
+ of a well-typed term in the well-typed context of the well-typed
+ term
+ 2. whether they are convertible
+ *)
+ ignore (
+ List.fold_left
+ (fun u (context_of_t,t) ->
+ (* 1 *)
+ 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');
+ (* 2 *)
+ let b,u1 = CicReduction.are_convertible ~subst context term t u in
+ if not b then
+ raise AllSelectedTermsMustBeConvertible
+ else
+ u1
+ ) u terms_with_context) ;
+ let status = (uri,metasenv',_subst,pbo,pty, attrs),goal in
+ let proof,goals =
+ PET.apply_tactic
+ (T.thens
+ ~start:
+ (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:
+ [(apply_tac ~term:(C.Appl [C.Rel 1; CicSubstitution.lift 1 term])) ;
+ T.id_tac])
+ status
+ in
+ let _,metasenv'',_subst,_,_, _ = 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)
+;;
+
+let generalize_pattern_tac pattern =
+ let generalize_pattern_tac (proof,goal) =
+ let _,metasenv,_,_,_,_ = proof in
+ let conjecture = CicUtil.lookup_meta goal metasenv in
+ let _,context,_ = conjecture in
+ let generalize_hyps =
+ let _,hpatterns,_ = ProofEngineHelpers.sort_pattern_hyps context pattern in
+ List.map fst hpatterns in
+ let ids_and_patterns =
+ List.map
+ (fun id ->
+ let rel,_ = ProofEngineHelpers.find_hyp id context in
+ id,(Some (PET.const_lazy_term rel), [], None)
+ ) generalize_hyps in
+ let tactics =
+ List.map
+ (function (id,pattern) ->
+ Tacticals.then_ ~start:(generalize_tac pattern)
+ ~continuation:(Tacticals.try_tactic
+ (ProofEngineStructuralRules.clear [id]))
+ ) ids_and_patterns
+ in
+ PET.apply_tactic (Tacticals.seq tactics) (proof,goal)
+ in
+ PET.mk_tactic (generalize_pattern_tac)
+;;
+
+let pattern_after_generalize_pattern_tac (tp, hpatterns, cpattern) =
+ let cpattern =
+ match cpattern with
+ None -> ProofEngineTypes.hole
+ | Some t -> t
+ in
+ let cpattern =
+ List.fold_left
+ (fun t (_,ty) -> Cic.Prod (Cic.Anonymous, ty, t)) cpattern hpatterns
+ in
+ tp, [], Some cpattern
+;;
+
let elim_tac ?using ?(pattern = PET.conclusion_pattern None) term =
- let elim_tac (proof, goal) =
- let cpattern = match pattern with
- | None, [], Some cpattern -> cpattern
- | _ -> raise (PET.Fail (lazy "not implemented"))
- in
+ let elim_tac pattern (proof, goal) =
let ugraph = CicUniv.oblivion_ugraph in
let curi, metasenv, _subst, proofbo, proofty, attrs = proof in
let conjecture = CicUtil.lookup_meta goal metasenv in
let metano, context, ty = conjecture in
+ let pattern = pattern_after_generalize_pattern_tac pattern in
+ let cpattern =
+ match pattern with
+ | None, [], Some cpattern -> cpattern
+ | _ -> raise (PET.Fail (lazy "not implemented")) in
let termty,_ugraph = TC.type_of_aux' metasenv context term ugraph in
let termty = CicReduction.whd context termty in
let termty, metasenv', arguments, _fresh_meta =
(T.then_ ~start:(PET.mk_tactic (fun _ -> res)) ~continuation)
dummy_status
in
- PET.mk_tactic elim_tac
+ let reorder_pattern ((proof, goal) as status) =
+ let _,metasenv,_,_,_,_ = proof in
+ let conjecture = CicUtil.lookup_meta goal metasenv in
+ let _,context,_ = conjecture in
+ let pattern = ProofEngineHelpers.sort_pattern_hyps context pattern in
+ PET.apply_tactic
+ (Tacticals.then_ ~start:(generalize_pattern_tac pattern)
+ ~continuation:(PET.mk_tactic (elim_tac pattern))) status
+ in
+ PET.mk_tactic reorder_pattern
;;
let cases_intros_tac ?(howmany=(-1)) ?(mk_fresh_name_callback = FreshNamesGenerator.mk_fresh_name ~subst:[]) term =
in
PET.mk_tactic assumption_tac
;;
-
-(* ANCORA DA DEBUGGARE *)
-
-exception UnableToDetectTheTermThatMustBeGeneralizedYouMustGiveItExplicitly;;
-exception TheSelectedTermsMustLiveInTheGoalContext
-exception AllSelectedTermsMustBeConvertible;;
-exception GeneralizationInHypothesesNotImplementedYet;;
-
-let generalize_tac
- ?(mk_fresh_name_callback = FreshNamesGenerator.mk_fresh_name ~subst:[])
- pattern
- =
- let module PET = ProofEngineTypes in
- let generalize_tac mk_fresh_name_callback
- ~pattern:(term,hyps_pat,concl_pat) status
- =
- if hyps_pat <> [] then raise GeneralizationInHypothesesNotImplementedYet;
- let (proof, goal) = status in
- let module C = Cic in
- let module P = PrimitiveTactics in
- let module T = Tacticals in
- let uri,metasenv,_subst,pbo,pty, attrs = proof in
- let (_,context,ty) as conjecture = CicUtil.lookup_meta goal metasenv in
- let subst,metasenv,u,selected_hyps,terms_with_context =
- ProofEngineHelpers.select ~metasenv ~ugraph:CicUniv.oblivion_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
- of a well-typed term in the well-typed context of the well-typed
- term
- 2. whether they are convertible
- *)
- ignore (
- List.fold_left
- (fun u (context_of_t,t) ->
- (* 1 *)
- 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');
- (* 2 *)
- let b,u1 = CicReduction.are_convertible ~subst context term t u in
- if not b then
- raise AllSelectedTermsMustBeConvertible
- else
- u1
- ) u terms_with_context) ;
- let status = (uri,metasenv',_subst,pbo,pty, attrs),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'',_subst,_,_, _ = 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)
-;;