cap_machine.proofmode.tactics_helpers
From iris.algebra Require Import frac.
From iris.proofmode Require Import proofmode.
From iris.base_logic Require Import invariants.
Require Import Eqdep_dec List.
From cap_machine Require Import cap_lang region contiguous.
From cap_machine.rules_binary Require Import rules_binary_base.
Section helpers.
(* ---------------------------- Helper Lemmas --------------------------------------- *)
Definition isCorrectPC_range p b e a0 an :=
∀ ai, (a0 <= ai)%a ∧ (ai < an)%a → isCorrectPC (WCap p b e ai).
Lemma isCorrectPC_inrange p b (e a0 an a: Addr) :
isCorrectPC_range p b e a0 an →
(a0 <= a < an)%Z →
isCorrectPC (WCap p b e a).
Proof.
unfold isCorrectPC_range. move=> /(_ a) HH ?. apply HH. eauto.
Unshelve. Fail idtac. Admitted.
Lemma isCorrectPC_contiguous_range p b e a0 an a l :
isCorrectPC_range p b e a0 an →
contiguous_between l a0 an →
a ∈ l →
isCorrectPC (WCap p b e a).
Proof.
intros Hr Hc Hin.
eapply isCorrectPC_inrange; eauto.
eapply contiguous_between_middle_bounds'; eauto.
Unshelve. Fail idtac. Admitted.
Lemma isCorrectPC_range_perm p b e a0 an :
isCorrectPC_range p b e a0 an →
(a0 < an)%a →
p = RX ∨ p = RWX.
Proof.
intros Hr H0n.
assert (isCorrectPC (WCap p b e a0)) as HH by (apply Hr; solve_addr).
inversion HH; auto.
Unshelve. Fail idtac. Admitted.
Lemma isCorrectPC_range_npE p b e a0 an :
isCorrectPC_range p b e a0 an →
(a0 < an)%a →
p ≠ E.
Proof.
intros HH1 HH2.
destruct (isCorrectPC_range_perm _ _ _ _ _ HH1 HH2) as [?| ? ];
congruence.
Unshelve. Fail idtac. Admitted.
End helpers.
(* Ltacs *)
(* Tactic for destructing a list into elements *)
Ltac destruct_list l :=
match goal with
| H : length l = _ |- _ =>
let a := fresh "a" in
let l' := fresh "l" in
destruct l as [|a l']; [inversion H|];
repeat (let a' := fresh "a" in
destruct l' as [|a' l'];[by inversion H|]);
destruct l'; [|by inversion H]
end.
Ltac iPrologue_pre :=
match goal with
| Hlen : length ?a = ?n |- _ =>
let a' := fresh "a" in
destruct a as [| a' a]; inversion Hlen; simpl
end.
Ltac iPrologue prog :=
(try iPrologue_pre);
iDestruct prog as "[Hi Hprog]";
iApply (wp_bind (fill [SeqCtx])).
Ltac iPrologue_both prog prog' :=
iDestruct prog as "[Hi Hprog]";
iDestruct prog' as "[Hsi Hsprog]";
iApply (wp_bind (fill [SeqCtx])).
Ltac iEpilogue prog :=
iNext; iIntros prog; iSimpl;
iApply wp_pure_step_later;auto;iNext;iIntros "_".
Ltac iEpilogue_both prog :=
iNext; iIntros prog; iSimpl;
iApply wp_pure_step_later;auto;iNext;iIntros "_";
iMod (do_step_pure _ [] with "[$Hspec $Hj]") as "Hj";auto;
iSimpl in "Hj".
Ltac iCombinePtrn :=
iCombine "Hi" "Hprog_done" as "Hprog_done";
iCombine "Hsi" "Hsprog_done" as "Hsprog_done".
Ltac consider_next_reg_both r1 r2 :=
destruct (decide (r1 = r2));[subst;rewrite !(lookup_insert _ r2);eauto|rewrite !(lookup_insert_ne _ r2);auto].
(* Inline version *)
Ltac consider_next_reg_both1 r1 r2 H1 H2 :=
destruct (decide (r1 = r2));
[ subst; rewrite !(lookup_insert _ r2) in H1, H2; eauto | rewrite !(lookup_insert_ne _ r2) in H1, H2; auto ].
Ltac iCorrectPC i j :=
eapply isCorrectPC_contiguous_range with (a0 := i) (an := j); eauto; [];
cbn; solve [ repeat constructor ].
Ltac iContiguous_next Ha index :=
generalize (contiguous_between_spec _ _ _ Ha index); auto.
Ltac disjoint_from_rmap rmap :=
match goal with
| Hsub : _ ⊆ dom rmap |- _ !! ?r = _ =>
assert (is_Some (rmap !! r)) as [x Hx];[apply elem_of_dom;apply Hsub;constructor|];
apply map_disjoint_Some_l with rmap x;auto;apply map_disjoint_union_r_2;auto
end.
Ltac iContiguous_le Ha index :=
eapply contiguous_between_middle_bounds with (i:=index) in Ha;eauto;clear -Ha;solve_addr.
Ltac consider_next_reg r1 r2 :=
destruct (decide (r1 = r2));[subst;rewrite lookup_insert;eauto|rewrite lookup_insert_ne;auto].
From iris.proofmode Require Import proofmode.
From iris.base_logic Require Import invariants.
Require Import Eqdep_dec List.
From cap_machine Require Import cap_lang region contiguous.
From cap_machine.rules_binary Require Import rules_binary_base.
Section helpers.
(* ---------------------------- Helper Lemmas --------------------------------------- *)
Definition isCorrectPC_range p b e a0 an :=
∀ ai, (a0 <= ai)%a ∧ (ai < an)%a → isCorrectPC (WCap p b e ai).
Lemma isCorrectPC_inrange p b (e a0 an a: Addr) :
isCorrectPC_range p b e a0 an →
(a0 <= a < an)%Z →
isCorrectPC (WCap p b e a).
Proof.
unfold isCorrectPC_range. move=> /(_ a) HH ?. apply HH. eauto.
Unshelve. Fail idtac. Admitted.
Lemma isCorrectPC_contiguous_range p b e a0 an a l :
isCorrectPC_range p b e a0 an →
contiguous_between l a0 an →
a ∈ l →
isCorrectPC (WCap p b e a).
Proof.
intros Hr Hc Hin.
eapply isCorrectPC_inrange; eauto.
eapply contiguous_between_middle_bounds'; eauto.
Unshelve. Fail idtac. Admitted.
Lemma isCorrectPC_range_perm p b e a0 an :
isCorrectPC_range p b e a0 an →
(a0 < an)%a →
p = RX ∨ p = RWX.
Proof.
intros Hr H0n.
assert (isCorrectPC (WCap p b e a0)) as HH by (apply Hr; solve_addr).
inversion HH; auto.
Unshelve. Fail idtac. Admitted.
Lemma isCorrectPC_range_npE p b e a0 an :
isCorrectPC_range p b e a0 an →
(a0 < an)%a →
p ≠ E.
Proof.
intros HH1 HH2.
destruct (isCorrectPC_range_perm _ _ _ _ _ HH1 HH2) as [?| ? ];
congruence.
Unshelve. Fail idtac. Admitted.
End helpers.
(* Ltacs *)
(* Tactic for destructing a list into elements *)
Ltac destruct_list l :=
match goal with
| H : length l = _ |- _ =>
let a := fresh "a" in
let l' := fresh "l" in
destruct l as [|a l']; [inversion H|];
repeat (let a' := fresh "a" in
destruct l' as [|a' l'];[by inversion H|]);
destruct l'; [|by inversion H]
end.
Ltac iPrologue_pre :=
match goal with
| Hlen : length ?a = ?n |- _ =>
let a' := fresh "a" in
destruct a as [| a' a]; inversion Hlen; simpl
end.
Ltac iPrologue prog :=
(try iPrologue_pre);
iDestruct prog as "[Hi Hprog]";
iApply (wp_bind (fill [SeqCtx])).
Ltac iPrologue_both prog prog' :=
iDestruct prog as "[Hi Hprog]";
iDestruct prog' as "[Hsi Hsprog]";
iApply (wp_bind (fill [SeqCtx])).
Ltac iEpilogue prog :=
iNext; iIntros prog; iSimpl;
iApply wp_pure_step_later;auto;iNext;iIntros "_".
Ltac iEpilogue_both prog :=
iNext; iIntros prog; iSimpl;
iApply wp_pure_step_later;auto;iNext;iIntros "_";
iMod (do_step_pure _ [] with "[$Hspec $Hj]") as "Hj";auto;
iSimpl in "Hj".
Ltac iCombinePtrn :=
iCombine "Hi" "Hprog_done" as "Hprog_done";
iCombine "Hsi" "Hsprog_done" as "Hsprog_done".
Ltac consider_next_reg_both r1 r2 :=
destruct (decide (r1 = r2));[subst;rewrite !(lookup_insert _ r2);eauto|rewrite !(lookup_insert_ne _ r2);auto].
(* Inline version *)
Ltac consider_next_reg_both1 r1 r2 H1 H2 :=
destruct (decide (r1 = r2));
[ subst; rewrite !(lookup_insert _ r2) in H1, H2; eauto | rewrite !(lookup_insert_ne _ r2) in H1, H2; auto ].
Ltac iCorrectPC i j :=
eapply isCorrectPC_contiguous_range with (a0 := i) (an := j); eauto; [];
cbn; solve [ repeat constructor ].
Ltac iContiguous_next Ha index :=
generalize (contiguous_between_spec _ _ _ Ha index); auto.
Ltac disjoint_from_rmap rmap :=
match goal with
| Hsub : _ ⊆ dom rmap |- _ !! ?r = _ =>
assert (is_Some (rmap !! r)) as [x Hx];[apply elem_of_dom;apply Hsub;constructor|];
apply map_disjoint_Some_l with rmap x;auto;apply map_disjoint_union_r_2;auto
end.
Ltac iContiguous_le Ha index :=
eapply contiguous_between_middle_bounds with (i:=index) in Ha;eauto;clear -Ha;solve_addr.
Ltac consider_next_reg r1 r2 :=
destruct (decide (r1 = r2));[subst;rewrite lookup_insert;eauto|rewrite lookup_insert_ne;auto].