Commit e059aa12 authored by Robbert Krebbers's avatar Robbert Krebbers
Browse files

Better implementation of iPoseProof.

The new implementation ensures that type class arguments are only infered
in the very end. This avoids the need for the inG hack in a0348d7c.
parent 7e477f28
...@@ -28,7 +28,6 @@ Class inG (Λ : language) (Σ : gFunctors) (A : cmraT) := InG { ...@@ -28,7 +28,6 @@ Class inG (Λ : language) (Σ : gFunctors) (A : cmraT) := InG {
inG_prf : A = projT2 Σ inG_id (iPreProp Λ (globalF Σ)) inG_prf : A = projT2 Σ inG_id (iPreProp Λ (globalF Σ))
}. }.
Arguments inG_id {_ _ _} _. Arguments inG_id {_ _ _} _.
Hint Mode inG - - + : typeclass_instances.
Definition to_globalF `{i : inG Λ Σ A} (γ : gname) (a : A) : iGst Λ (globalF Σ) := Definition to_globalF `{i : inG Λ Σ A} (γ : gname) (a : A) : iGst Λ (globalF Σ) :=
iprod_singleton (inG_id i) {[ γ := cmra_transport inG_prf a ]}. iprod_singleton (inG_id i) {[ γ := cmra_transport inG_prf a ]}.
......
...@@ -43,7 +43,7 @@ Lemma inv_open E N P : ...@@ -43,7 +43,7 @@ Lemma inv_open E N P :
|={E,E'}=> P ( P ={E',E}= True). |={E,E'}=> P ( P ={E',E}= True).
Proof. Proof.
rewrite inv_eq /inv. iDestruct 1 as (i) "[% #Hi]". rewrite inv_eq /inv. iDestruct 1 as (i) "[% #Hi]".
iExists (E {[ i ]}). iSplit. { iPureIntro. set_solver. } iExists (E {[ i ]}). iSplit; first (iPureIntro; set_solver).
iPvs (pvs_openI' with "Hi") as "HP"; [set_solver..|]. iPvs (pvs_openI' with "Hi") as "HP"; [set_solver..|].
iPvsIntro. iSplitL "HP"; first done. iIntros "HP". iPvsIntro. iSplitL "HP"; first done. iIntros "HP".
iPvs (pvs_closeI' _ _ P with "[HP]"); [set_solver|iSplit; done|set_solver|]. iPvs (pvs_closeI' _ _ P with "[HP]"); [set_solver|iSplit; done|set_solver|].
......
...@@ -549,25 +549,13 @@ Proof. ...@@ -549,25 +549,13 @@ Proof.
by rewrite right_id {1}(persistentP P) always_and_sep_l wand_elim_r. by rewrite right_id {1}(persistentP P) always_and_sep_l wand_elim_r.
Qed. Qed.
(** Whenever posing [lem : True ⊢ Q] as [H] we want it to appear as [H : Q] and Lemma tac_pose_proof Δ Δ' j P Q :
not as [H : True -★ Q]. The class [IntoPosedProof] is used to strip off the (True P)
[True]. Note that [to_posed_proof_True] is declared using a [Hint Extern] to envs_app true (Esnoc Enil j P) Δ = Some Δ'
make sure it is not used while posing [lem : ?P ⊢ Q] with [?P] an evar. *)
Class IntoPosedProof (P1 P2 R : uPred M) :=
into_pose_proof : (P1 P2) True R.
Arguments into_pose_proof : clear implicits.
Instance to_posed_proof_True P : IntoPosedProof True P P.
Proof. by rewrite /IntoPosedProof. Qed.
Global Instance to_posed_proof_wand P Q : IntoPosedProof P Q (P - Q).
Proof. rewrite /IntoPosedProof. apply entails_wand. Qed.
Lemma tac_pose_proof Δ Δ' j P1 P2 R Q :
(P1 P2) IntoPosedProof P1 P2 R
envs_app true (Esnoc Enil j R) Δ = Some Δ'
(Δ' Q) Δ Q. (Δ' Q) Δ Q.
Proof. Proof.
intros HP ?? <-. rewrite envs_app_sound //; simpl. intros HP ? <-. rewrite envs_app_sound //; simpl.
by rewrite right_id -(into_pose_proof P1 P2 R) // always_pure wand_True. by rewrite right_id -HP always_pure wand_True.
Qed. Qed.
Lemma tac_pose_proof_hyp Δ Δ' Δ'' i p j P Q : Lemma tac_pose_proof_hyp Δ Δ' Δ'' i p j P Q :
...@@ -745,6 +733,3 @@ Proof. ...@@ -745,6 +733,3 @@ Proof.
rewrite envs_simple_replace_sound' //; simpl. by rewrite right_id wand_elim_r. rewrite envs_simple_replace_sound' //; simpl. by rewrite right_id wand_elim_r.
Qed. Qed.
End tactics. End tactics.
Hint Extern 0 (IntoPosedProof True _ _) =>
class_apply @to_posed_proof_True : typeclass_instances.
...@@ -112,45 +112,45 @@ Tactic Notation "iPvsCore" constr(H) := ...@@ -112,45 +112,45 @@ Tactic Notation "iPvsCore" constr(H) :=
|env_cbv; reflexivity|simpl] |env_cbv; reflexivity|simpl]
end. end.
Tactic Notation "iPvs" open_constr(H) := Tactic Notation "iPvs" open_constr(lem) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as "?"). iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as "?").
Tactic Notation "iPvs" open_constr(H) "as" constr(pat) := Tactic Notation "iPvs" open_constr(lem) "as" constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as pat). iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) ")" Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1) ")"
constr(pat) := constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as ( x1 ) pat). iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as ( x1 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) ")" constr(pat) := simple_intropattern(x2) ")" constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 ) pat). iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) ")" constr(pat) := simple_intropattern(x2) simple_intropattern(x3) ")" constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 x3 ) pat). iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 x3 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) ")" simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) ")"
constr(pat) := constr(pat) :=
iDestructHelp H as (fun H => iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 ) pat). iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) ")" constr(pat) := simple_intropattern(x5) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 ) pat). iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) ")" constr(pat) := simple_intropattern(x5) simple_intropattern(x6) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 ) pat). iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) ")" simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) ")"
constr(pat) := constr(pat) :=
iDestructHelp H as (fun H => iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 x7 ) pat). iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 x7 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7)
simple_intropattern(x8) ")" constr(pat) := simple_intropattern(x8) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 x7 x8 ) pat). iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 x7 x8 ) pat).
Hint Extern 2 (of_envs _ _) => Hint Extern 2 (of_envs _ _) =>
......
...@@ -208,31 +208,62 @@ Tactic Notation "iSpecialize" open_constr(t) := ...@@ -208,31 +208,62 @@ Tactic Notation "iSpecialize" open_constr(t) :=
end. end.
(** * Pose proof *) (** * Pose proof *)
Local Tactic Notation "iPoseProofCore" open_constr(H1) "as" constr(H2) := (* The tactic [iIntoEntails] tactic solves a goal [True ⊢ Q]. The arguments [t]
lazymatch type of H1 with is a Coq term whose type is of the following shape:
| string =>
eapply tac_pose_proof_hyp with _ _ H1 _ H2 _; - [∀ (x_1 : A_1) .. (x_n : A_n), True ⊢ Q]
[env_cbv; reflexivity || fail "iPoseProof:" H1 "not found" - [∀ (x_1 : A_1) .. (x_n : A_n), P1 ⊢ P2], in which case [Q] becomes [P1 -★ P2]
|env_cbv; reflexivity || fail "iPoseProof:" H2 "not fresh"|] - [∀ (x_1 : A_1) .. (x_n : A_n), P1 ⊣⊢ P2], in which case [Q] becomes [P1 ↔ P2]
| _ =>
eapply tac_pose_proof with _ H2 _ _ _; (* (j:=H) *) The tactic instantiates each dependent argument [x_i] with an evar and generates
[first [eapply H1|apply uPred.equiv_iff; eapply H1] a goal [P] for non-dependent arguments [x_i : P]. *)
|apply _ Tactic Notation "iIntoEntails" open_constr(t) :=
|env_cbv; reflexivity || fail "iPoseProof:" H2 "not fresh"|] let rec go t :=
lazymatch type of t with
| True _ => apply t
| _ _ => apply (uPred.entails_wand _ _ t)
| _ _ => apply (uPred.equiv_iff _ _ t)
| ?P ?Q => let H := fresh in assert P as H; [|go uconstr:(t H)]
| _ : ?T, _ =>
(* Put [T] inside an [id] to avoid TC inference from being invoked. *)
(* This is a workarround for Coq bug #4969. *)
let e := fresh in evar (e:id T);
let e' := eval unfold e in e in clear e; go (t e')
end
in go t.
Tactic Notation "iPoseProofCore" open_constr(lem) "as" tactic(tac) :=
let pose_trm t tac :=
let Htmp := iFresh in
lazymatch type of t with
| string =>
eapply tac_pose_proof_hyp with _ _ t _ Htmp _;
[env_cbv; reflexivity || fail "iPoseProof:" t "not found"
|env_cbv; reflexivity || fail "iPoseProof:" Htmp "not fresh"
|tac Htmp]
| _ =>
eapply tac_pose_proof with _ Htmp _; (* (j:=H) *)
[iIntoEntails t
|env_cbv; reflexivity || fail "iPoseProof:" Htmp "not fresh"
|tac Htmp]
end;
try (apply _) (* solve TC constraints. It is essential that this happens
after the continuation [tac] has been called. *)
in lazymatch lem with
| ITrm ?t ?xs ?pat =>
pose_trm t ltac:(fun Htmp =>
iSpecializeArgs Htmp xs; iSpecializePat Htmp pat; last (tac Htmp))
| _ => pose_trm lem tac
end. end.
Tactic Notation "iPoseProof" open_constr(t) "as" constr(H) := Tactic Notation "iPoseProof" open_constr(lem) "as" constr(H) :=
lazymatch t with iPoseProofCore lem as (fun Htmp => iRename Htmp into H).
| ITrm ?H1 ?xs ?pat =>
iPoseProofCore H1 as H; last (iSpecializeArgs H xs; iSpecializePat H pat)
| _ => iPoseProofCore t as H
end.
Tactic Notation "iPoseProof" open_constr(t) := Tactic Notation "iPoseProof" open_constr(lem) :=
let H := iFresh in iPoseProof t as H. iPoseProofCore lem as (fun _ => idtac).
(** * Apply *) (** * Apply *)
Tactic Notation "iApply" open_constr(t) := Tactic Notation "iApply" open_constr(lem) :=
let finish H := first let finish H := first
[iExact H [iExact H
|eapply tac_apply with _ H _ _ _; |eapply tac_apply with _ H _ _ _;
...@@ -240,18 +271,17 @@ Tactic Notation "iApply" open_constr(t) := ...@@ -240,18 +271,17 @@ Tactic Notation "iApply" open_constr(t) :=
|let P := match goal with |- IntoWand ?P _ _ => P end in |let P := match goal with |- IntoWand ?P _ _ => P end in
apply _ || fail 1 "iApply: cannot apply" H ":" P apply _ || fail 1 "iApply: cannot apply" H ":" P
|lazy beta (* reduce betas created by instantiation *)]] in |lazy beta (* reduce betas created by instantiation *)]] in
let Htmp := iFresh in lazymatch lem with
lazymatch t with | ITrm ?t ?xs ?pat =>
| ITrm ?H ?xs ?pat => iPoseProofCore t as (fun Htmp =>
iPoseProofCore H as Htmp; last (
iSpecializeArgs Htmp xs; iSpecializeArgs Htmp xs;
try (iSpecializeArgs Htmp (hcons _ _)); try (iSpecializeArgs Htmp (hcons _ _));
iSpecializePat Htmp pat; last finish Htmp) iSpecializePat Htmp pat; last finish Htmp)
| _ => | _ =>
iPoseProofCore t as Htmp; last ( iPoseProofCore lem as (fun Htmp =>
try (iSpecializeArgs Htmp (hcons _ _)); try (iSpecializeArgs Htmp (hcons _ _));
finish Htmp) finish Htmp)
end; try apply _. end.
(** * Revert *) (** * Revert *)
Local Tactic Notation "iForallRevert" ident(x) := Local Tactic Notation "iForallRevert" ident(x) :=
...@@ -647,7 +677,7 @@ Tactic Notation "iIntros" "(" simple_intropattern(x1) simple_intropattern(x2) ...@@ -647,7 +677,7 @@ Tactic Notation "iIntros" "(" simple_intropattern(x1) simple_intropattern(x2)
iIntros ( x1 x2 x3 x4 x5 x6 x7 x8 ); iIntros p. iIntros ( x1 x2 x3 x4 x5 x6 x7 x8 ); iIntros p.
(** * Destruct tactic *) (** * Destruct tactic *)
Tactic Notation "iDestructHelp" open_constr(lem) "as" tactic(tac) := Tactic Notation "iDestructCore" open_constr(lem) "as" tactic(tac) :=
let intro_destruct n := let intro_destruct n :=
let rec go n' := let rec go n' :=
lazymatch n' with lazymatch n' with
...@@ -663,49 +693,48 @@ Tactic Notation "iDestructHelp" open_constr(lem) "as" tactic(tac) := ...@@ -663,49 +693,48 @@ Tactic Notation "iDestructHelp" open_constr(lem) "as" tactic(tac) :=
| string => tac lem | string => tac lem
| iTrm => | iTrm =>
lazymatch lem with lazymatch lem with
| @iTrm string ?H _ hnil ?pat => | @iTrm string ?H _ hnil ?pat => iSpecializePat H pat; last (tac H)
iSpecializePat H pat; last tac H | _ => iPoseProofCore lem as tac
| _ => let H := iFresh in iPoseProof lem as H; last tac H; try apply _
end end
| _ => let H := iFresh in iPoseProof lem as H; last tac H; try apply _ | _ => iPoseProofCore lem as tac
end. end.
Tactic Notation "iDestruct" open_constr(H) "as" constr(pat) := Tactic Notation "iDestruct" open_constr(lem) "as" constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as pat). iDestructCore lem as (fun H => iDestructHyp H as pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) ")" Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1) ")"
constr(pat) := constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) ")" constr(pat) := simple_intropattern(x2) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) ")" constr(pat) := simple_intropattern(x2) simple_intropattern(x3) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 x3 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 x3 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) ")" simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) ")"
constr(pat) := constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 x3 x4 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 x3 x4 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) ")" constr(pat) := simple_intropattern(x5) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) ")" constr(pat) := simple_intropattern(x5) simple_intropattern(x6) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 x6 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 x6 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) ")" simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) ")"
constr(pat) := constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 x6 x7 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 x6 x7 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "(" simple_intropattern(x1) Tactic Notation "iDestruct" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7)
simple_intropattern(x8) ")" constr(pat) := simple_intropattern(x8) ")" constr(pat) :=
iDestructHelp H as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 x6 x7 x8 ) pat). iDestructCore lem as (fun H => iDestructHyp H as ( x1 x2 x3 x4 x5 x6 x7 x8 ) pat).
Tactic Notation "iDestruct" open_constr(H) "as" "%" simple_intropattern(pat) := Tactic Notation "iDestruct" open_constr(lem) "as" "%" simple_intropattern(pat) :=
let Htmp := iFresh in iDestruct H as Htmp; last iPure Htmp as pat. iDestructCore lem as (fun H => iPure H as pat).
(* This is pretty ugly, but without Ltac support for manipulating lists of (* This is pretty ugly, but without Ltac support for manipulating lists of
idents I do not know how to do this better. *) idents I do not know how to do this better. *)
...@@ -781,33 +810,33 @@ Local Ltac iRewriteFindPred := ...@@ -781,33 +810,33 @@ Local Ltac iRewriteFindPred :=
match goal with |- ( y, @?Ψ y _) => unify Φ Ψ; reflexivity end match goal with |- ( y, @?Ψ y _) => unify Φ Ψ; reflexivity end
end. end.
Local Tactic Notation "iRewriteCore" constr(lr) open_constr(t) := Local Tactic Notation "iRewriteCore" constr(lr) open_constr(lem) :=
let Heq := iFresh in iPoseProof t as Heq; last ( iPoseProofCore lem as (fun Heq =>
eapply (tac_rewrite _ Heq _ _ lr); eapply (tac_rewrite _ Heq _ _ lr);
[env_cbv; reflexivity || fail "iRewrite:" Heq "not found" [env_cbv; reflexivity || fail "iRewrite:" Heq "not found"
|let P := match goal with |- ?P _ => P end in |let P := match goal with |- ?P _ => P end in
reflexivity || fail "iRewrite:" Heq ":" P "not an equality" reflexivity || fail "iRewrite:" Heq ":" P "not an equality"
|iRewriteFindPred |iRewriteFindPred
|intros ??? ->; reflexivity|lazy beta; iClear Heq]). |intros ??? ->; reflexivity|lazy beta; iClear Heq]).
Tactic Notation "iRewrite" open_constr(t) := iRewriteCore false t. Tactic Notation "iRewrite" open_constr(lem) := iRewriteCore false lem.
Tactic Notation "iRewrite" "-" open_constr(t) := iRewriteCore true t. Tactic Notation "iRewrite" "-" open_constr(lem) := iRewriteCore true lem.
Local Tactic Notation "iRewriteCore" constr(lr) open_constr(t) "in" constr(H) := Local Tactic Notation "iRewriteCore" constr(lr) open_constr(lem) "in" constr(H) :=
let Heq := iFresh in iPoseProof t as Heq; last ( iPoseProofCore lem as (fun Heq =>
eapply (tac_rewrite_in _ Heq _ _ H _ _ lr); eapply (tac_rewrite_in _ Heq _ _ H _ _ lr);
[env_cbv; reflexivity || fail "iRewrite:" Heq "not found" [env_cbv; reflexivity || fail "iRewrite:" Heq "not found"
|env_cbv; reflexivity || fail "iRewrite:" H "not found" |env_cbv; reflexivity || fail "iRewrite:" H "not found"
|let P := match goal with |- ?P _ => P end in |let P := match goal with |- ?P _ => P end in
reflexivity || fail "iRewrite:" Heq ":" P "not an equality" reflexivity || fail "iRewrite:" Heq ":" P "not an equality"
|iRewriteFindPred |iRewriteFindPred
|intros ??? ->; reflexivity |intros ??? ->; reflexivity
|env_cbv; reflexivity|lazy beta; iClear Heq]). |env_cbv; reflexivity|lazy beta; iClear Heq]).
Tactic Notation "iRewrite" open_constr(t) "in" constr(H) := Tactic Notation "iRewrite" open_constr(lem) "in" constr(H) :=
iRewriteCore false t in H. iRewriteCore false lem in H.
Tactic Notation "iRewrite" "-" open_constr(t) "in" constr(H) := Tactic Notation "iRewrite" "-" open_constr(lem) "in" constr(H) :=
iRewriteCore true t in H. iRewriteCore true lem in H.
Ltac iSimplifyEq := repeat ( Ltac iSimplifyEq := repeat (
iMatchGoal ltac:(fun H P => match P with (_ = _)%I => iDestruct H as %? end) iMatchGoal ltac:(fun H P => match P with (_ = _)%I => iDestruct H as %? end)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment