From 948c51163a144f03fdd8b60ba5a8635f9a4a89ee Mon Sep 17 00:00:00 2001 From: Jacques-Henri Jourdan <jacques-henri.jourdan@normalesup.org> Date: Wed, 24 Jan 2018 19:28:23 +0100 Subject: [PATCH] Make sure all the itactics fail if the do not go through the proof mode. --- theories/heap_lang/proofmode.v | 2 +- theories/proofmode/tactics.v | 106 ++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 50 deletions(-) diff --git a/theories/heap_lang/proofmode.v b/theories/heap_lang/proofmode.v index 214c37400..e341888af 100644 --- a/theories/heap_lang/proofmode.v +++ b/theories/heap_lang/proofmode.v @@ -15,7 +15,7 @@ Lemma tac_twp_expr_eval `{heapG Σ} Δ s E Φ e e' : Proof. by intros ->. Qed. Tactic Notation "wp_expr_eval" tactic(t) := - try iStartProof; + iStartProof; try (first [eapply tac_wp_expr_eval|eapply tac_twp_expr_eval]; [t; reflexivity|]). diff --git a/theories/proofmode/tactics.v b/theories/proofmode/tactics.v index 35ddb02a5..048a44aef 100644 --- a/theories/proofmode/tactics.v +++ b/theories/proofmode/tactics.v @@ -58,12 +58,6 @@ Tactic Notation "iMatchHyp" tactic1(tac) := Tactic Notation "iStartProof" := lazymatch goal with | |- envs_entails _ _ => idtac - - (* In the case the goal starts with a let, we want [iIntros (x)] to - not unfold the variable, but instead introduce it as with Coq's - intros.*) - | |- let _ := _ in _ => fail - | |- ?φ => eapply (as_valid_2 φ); [apply _ || fail "iStartProof: not a Bi entailment" |apply tac_adequate] @@ -80,9 +74,6 @@ Tactic Notation "iStartProof" uconstr(PROP) := type_term has a non-negligeable performance impact. *) let x := type_term (eq_refl : @eq Type PROP PROP') in idtac - | |- let _ := _ in _ => intro - | |- ∀ _, _ => intro - (* We eta-expand [as_valid_2], in order to make sure that [iStartProof PROP] works even if [PROP] is the carrier type. In this case, typing this expression will end up unifying PROP with @@ -96,8 +87,7 @@ Tactic Notation "iStartProof" uconstr(PROP) := (** * Simplification *) Tactic Notation "iEval" tactic(t) := - try iStartProof; - try (eapply tac_eval; [t; reflexivity|]). + iStartProof; try (eapply tac_eval; [t; reflexivity|]). Tactic Notation "iSimpl" := iEval simpl. @@ -150,7 +140,7 @@ Tactic Notation "iClear" constr(Hs) := | ESelPure :: ?Hs => clear; go Hs | ESelIdent _ ?H :: ?Hs => iClearHyp H; go Hs end in - let Hs := iElaborateSelPat Hs in go Hs. + let Hs := iElaborateSelPat Hs in iStartProof; go Hs. Tactic Notation "iClear" "(" ident_list(xs) ")" constr(Hs) := iClear Hs; clear xs. @@ -253,12 +243,14 @@ Local Ltac iFrameFinish := end. Local Ltac iFramePure t := + iStartProof; let φ := type of t in eapply (tac_frame_pure _ _ _ _ t); [apply _ || fail "iFrame: cannot frame" φ |iFrameFinish]. Local Ltac iFrameHyp H := + iStartProof; eapply tac_frame with _ H _ _ _; [env_reflexivity || fail "iFrame:" H "not found" |apply _ || @@ -270,6 +262,7 @@ Local Ltac iFrameAnyPure := repeat match goal with H : _ |- _ => iFramePure H end. Local Ltac iFrameAnyPersistent := + iStartProof; let rec go Hs := match Hs with [] => idtac | ?H :: ?Hs => repeat iFrameHyp H; go Hs end in match goal with @@ -278,6 +271,7 @@ Local Ltac iFrameAnyPersistent := end. Local Ltac iFrameAnySpatial := + iStartProof; let rec go Hs := match Hs with [] => idtac | ?H :: ?Hs => try iFrameHyp H; go Hs end in match goal with @@ -342,16 +336,20 @@ Tactic Notation "iFrame" "(" constr(t1) constr(t2) constr(t3) constr(t4) (** * Basic introduction tactics *) Local Tactic Notation "iIntro" "(" simple_intropattern(x) ")" := - try iStartProof; - lazymatch goal with - | |- envs_entails _ _ => - eapply tac_forall_intro; - [apply _ || - let P := match goal with |- FromForall ?P _ => P end in - fail "iIntro: cannot turn" P "into a universal quantifier" - |lazy beta; intros x] - | |- _ => intros x - end. + (* In the case the goal starts with an [let x := _ in _], we do not + want to unfold x and start the proof mode. Instead, we want to + use intros. So [iStartProof] has to be called only if [intros] + fails *) + intros x || + (iStartProof; + lazymatch goal with + | |- envs_entails _ _ => + eapply tac_forall_intro; + [apply _ || + let P := match goal with |- FromForall ?P _ => P end in + fail "iIntro: cannot turn" P "into a universal quantifier" + |lazy beta; intros x] + end). Local Tactic Notation "iIntro" constr(H) := iStartProof; @@ -394,11 +392,10 @@ Local Tactic Notation "iIntro" "#" constr(H) := | fail "iIntro: nothing to introduce" ]. Local Tactic Notation "iIntro" "_" := - try iStartProof; first - [ (* (?Q → _) *) apply tac_impl_intro_drop + [ (* (?Q → _) *) iStartProof; apply tac_impl_intro_drop | (* (_ -∗ _) *) - apply tac_wand_intro_drop; + iStartProof; apply tac_wand_intro_drop; [apply _ || let P := match goal with |- TCOr (Affine ?P) _ => P end in fail 1 "iIntro:" P "not affine and the goal not absorbing" @@ -407,18 +404,25 @@ Local Tactic Notation "iIntro" "_" := | fail 1 "iIntro: nothing to introduce" ]. Local Tactic Notation "iIntroForall" := - try iStartProof; lazymatch goal with | |- ∀ _, ?P => fail (* actually an →, this is handled by iIntro below *) | |- ∀ _, _ => intro - | |- envs_entails _ (∀ x : _, _) => let x' := fresh x in iIntro (x') + | |- let _ := _ in _ => intro + | |- _ => + iStartProof; + lazymatch goal with + | |- envs_entails _ (∀ x : _, _) => let x' := fresh x in iIntro (x') + end end. Local Tactic Notation "iIntro" := - try iStartProof; lazymatch goal with | |- _ → ?P => intro - | |- envs_entails _ (_ -∗ _) => iIntro (?) || let H := iFresh in iIntro #H || iIntro H - | |- envs_entails _ (_ → _) => iIntro (?) || let H := iFresh in iIntro #H || iIntro H + | |- _ => + iStartProof; + lazymatch goal with + | |- envs_entails _ (_ -∗ _) => iIntro (?) || let H := iFresh in iIntro #H || iIntro H + | |- envs_entails _ (_ → _) => iIntro (?) || let H := iFresh in iIntro #H || iIntro H + end end. (** * Specialize *) @@ -632,7 +636,7 @@ eliminations may not be performed when type classes have not been resolved. *) Tactic Notation "iPoseProofCore" open_constr(lem) "as" constr(p) constr(lazy_tc) tactic(tac) := - try iStartProof; + iStartProof; let Htmp := iFresh in let t := lazymatch lem with ITrm ?t ?xs ?pat => t | _ => lem end in let t := lazymatch type of t with string => constr:(INamed t) | _ => t end in @@ -1011,32 +1015,36 @@ Tactic Notation "iDestructHyp" constr(H) "as" "(" simple_intropattern(x1) (** * Introduction tactic *) Tactic Notation "iIntros" constr(pat) := - let rec go pats := + let rec go pats startproof := lazymatch pats with - | [] => idtac + | [] => + lazymatch startproof with + | true => iStartProof + | false => idtac + end (* Optimizations to avoid generating fresh names *) - | IPureElim :: ?pats => iIntro (?); go pats - | IAlwaysElim (IIdent ?H) :: ?pats => iIntro #H; go pats - | IDrop :: ?pats => iIntro _; go pats - | IIdent ?H :: ?pats => iIntro H; go pats + | IPureElim :: ?pats => iIntro (?); go pats startproof + | IAlwaysElim (IIdent ?H) :: ?pats => iIntro #H; go pats false + | IDrop :: ?pats => iIntro _; go pats startproof + | IIdent ?H :: ?pats => iIntro H; go pats startproof (* Introduction patterns that can only occur at the top-level *) - | IPureIntro :: ?pats => iPureIntro; go pats - | IAlwaysIntro :: ?pats => iAlways; go pats - | IModalIntro :: ?pats => iModIntro; go pats - | IForall :: ?pats => repeat iIntroForall; go pats - | IAll :: ?pats => repeat (iIntroForall || iIntro); go pats + | IPureIntro :: ?pats => iPureIntro; go pats false + | IAlwaysIntro :: ?pats => iAlways; go pats false + | IModalIntro :: ?pats => iModIntro; go pats false + | IForall :: ?pats => repeat iIntroForall; go pats startproof + | IAll :: ?pats => repeat (iIntroForall || iIntro); go pats startproof (* Clearing and simplifying introduction patterns *) - | ISimpl :: ?pats => simpl; go pats - | IClear ?H :: ?pats => iClear H; go pats - | IClearFrame ?H :: ?pats => iFrame H; go pats - | IDone :: ?pats => try done; go pats + | ISimpl :: ?pats => simpl; go pats startproof + | IClear ?H :: ?pats => iClear H; go pats false + | IClearFrame ?H :: ?pats => iFrame H; go pats false + | IDone :: ?pats => try done; go pats startproof (* Introduction + destruct *) | IAlwaysElim ?pat :: ?pats => - let H := iFresh in iIntro #H; iDestructHyp H as pat; go pats + let H := iFresh in iIntro #H; iDestructHyp H as pat; go pats false | ?pat :: ?pats => - let H := iFresh in iIntro H; iDestructHyp H as pat; go pats + let H := iFresh in iIntro H; iDestructHyp H as pat; go pats false end - in let pats := intro_pat.parse pat in try iStartProof; go pats. + in let pats := intro_pat.parse pat in go pats true. Tactic Notation "iIntros" := iIntros [IAll]. Tactic Notation "iIntros" "(" simple_intropattern(x1) ")" := -- GitLab