Require Export permissions bits.
Notation pbit K := (
tagged perm (@
BIndet K)).
Notation PBit := (
Tagged (
d:=
BIndet)).
Hint Extern 0 (
Separation _) =>
apply (
_ :
Separation (
pbit _)).
Section operations.
Context `{
Env K}.
Global Instance pbit_valid:
Valid (
env K *
memenv K) (
pbit K) := λ ΓΔ γ
b,
✓{ΓΔ} (
tagged_tag γ
b) ∧
sep_valid γ
b.
Definition pbit_indetify (γ
b :
pbit K) :
pbit K :=
PBit (
tagged_perm γ
b)
BIndet.
Definition pbit_kind :
pbit K →
option pkind :=
perm_kind ∘
tagged_perm.
Definition pbit_full :
pbit K :=
PBit perm_full BIndet.
Definition pbit_token :
pbit K :=
PBit perm_token BIndet.
Definition pbit_locked :
pbit K →
bool :=
perm_locked ∘
tagged_perm.
Definition pbit_lock (γ
b :
pbit K) :
pbit K :=
PBit (
perm_lock (
tagged_perm γ
b)) (
tagged_tag γ
b).
Definition pbit_unlock (γ
b :
pbit K) :
pbit K :=
PBit (
perm_unlock (
tagged_perm γ
b)) (
tagged_tag γ
b).
Definition pbit_unlock_if (γ
b :
pbit K) (β :
bool) :
pbit K :=
if β
then pbit_unlock γ
b else γ
b.
End operations.
Arguments pbit_kind _ !
_ /.
Arguments pbit_indetify _ !
_ /.
Arguments pbit_locked _ !
_ /.
Arguments pbit_lock _ !
_ /.
Arguments pbit_unlock _ !
_ /.
Section permission_bits.
Context `{
EnvSpec K}.
Implicit Types Γ :
env K.
Implicit Types Δ :
memenv K.
Implicit Types α :
bool.
Implicit Types b :
bit K.
Implicit Types bs :
list (
bit K).
Implicit Types γ :
perm.
Implicit Types γ
s :
list perm.
Implicit Types γ
b :
pbit K.
Implicit Types γ
bs :
list (
pbit K).
Lemma pbits_tag γ
bs :
tagged_tag <$>
PBit γ <$>
bs =
bs.
Proof.
induction bs; f_equal'; auto. Qed.
Lemma PBits_perm_tag γ
bs :
zip_with PBit (
tagged_perm <$> γ
bs) (
tagged_tag <$> γ
bs) = γ
bs.
Proof.
by induction γbs as [|[]]; f_equal'. Qed.
Lemma pbit_empty_valid Γ Δ : ✓{Γ,Δ} (∅ :
pbit K).
Proof.
repeat split; auto using BIndet_valid, sep_empty_valid. Qed.
Lemma PBit_valid Γ Δ γ
b :
sep_valid γ → ¬
sep_unmapped γ → ✓{Γ,Δ}
b → ✓{Γ,Δ} (
PBit γ
b).
Proof.
by repeat split. Qed.
Lemma PBits_valid Γ Δ γ
s bs :
Forall sep_valid γ
s →
Forall (
not ∘
sep_unmapped) γ
s →
✓{Γ,Δ}*
bs → ✓{Γ,Δ}* (
zip_with PBit γ
s bs).
Proof.
intros Hγs. revert bs. induction Hγs; intros ?? [|????];
decompose_Forall_hyps; auto using PBit_valid.
Qed.
Lemma pbit_mapped γ
b :
Some Readable ⊆
pbit_kind γ
b → ¬
sep_unmapped γ
b.
Proof.
intros ? [? _]. by apply (perm_mapped (tagged_perm γb)). Qed.
Lemma pbit_perm_mapped γ
b :
sep_valid γ
b →
sep_unmapped (
tagged_perm γ
b) →
sep_unmapped γ
b.
Proof.
intros [??]; split; auto. Qed.
Lemma pbits_perm_mapped γ
bs :
Forall sep_valid γ
bs →
Forall (
not ∘
sep_unmapped) γ
bs →
Forall (
not ∘
sep_unmapped) (
tagged_perm <$> γ
bs).
Proof.
induction 1; inversion_clear 1; constructor; auto using pbit_perm_mapped.
Qed.
Lemma pbits_perm_mapped' γ
bs :
Forall sep_valid γ
bs →
Forall sep_unmapped (
tagged_perm <$> γ
bs) →
Forall sep_unmapped γ
bs.
Proof.
induction 1; inversion_clear 1; constructor; auto using pbit_perm_mapped.
Qed.
Lemma pbits_perm_unshared γ
bs :
Forall sep_unshared γ
bs →
Forall sep_unshared (
tagged_perm <$> γ
bs).
Proof.
by induction 1; constructor. Qed.
Lemma PBits_mapped γ
s bs :
Forall (
not ∘
sep_unmapped) γ
s →
Forall (
not ∘
sep_unmapped) (
zip_with PBit γ
s bs).
Proof.
intros Hγs. revert bs. induction Hγs; intros [|??]; constructor; auto.
by intros [??].
Qed.
Lemma pbits_tag_valid Γ Δ γ
bs :
✓{Γ,Δ}* γ
bs → ✓{Γ,Δ}* (
tagged_tag <$> γ
bs).
Proof.
induction 1 as [|?? (?&?&?)]; csimpl; eauto. Qed.
Lemma pbits_valid_perm_valid Γ Δ γ
bs :
✓{Γ,Δ}* γ
bs →
Forall sep_valid (
tagged_perm <$> γ
bs).
Proof.
induction 1 as [|?? (?&?&?)]; csimpl; eauto. Qed.
Lemma pbit_valid_weaken Γ1 Γ2 Δ1 Δ2 γ
b :
✓ Γ1 → ✓{Γ1,Δ1} γ
b → Γ1 ⊆ Γ2 → Δ1 ⇒ₘ Δ2 → ✓{Γ2,Δ2} γ
b.
Proof.
intros ? (?&?&?); repeat split; eauto using bit_valid_weaken. Qed.
Lemma pbit_valid_sep_valid Γ Δ γ
b : ✓{Γ,Δ} γ
b →
sep_valid γ
b.
Proof.
by intros (?&?&?); repeat split. Qed.
Lemma pbits_valid_sep_valid Γ Δ γ
bs : ✓{Γ,Δ}* γ
bs →
Forall sep_valid γ
bs.
Proof.
induction 1; eauto using pbit_valid_sep_valid. Qed.
Lemma pbit_unlock_valid Γ Δ γ
b : ✓{Γ,Δ} γ
b → ✓{Γ,Δ} (
pbit_unlock γ
b).
Proof.
unfold pbit_unlock; intros (?&?&?); repeat split; naive_solver
auto using perm_unlock_valid, perm_unlock_mapped.
Qed.
Lemma pbit_unlock_if_empty β :
pbit_unlock_if (∅ :
pbit K) β = ∅.
Proof.
by destruct β. Qed.
Lemma pbit_unlock_unshared γ
b :
sep_unshared γ
b →
sep_unshared (
pbit_unlock γ
b).
Proof.
apply perm_unlock_unshared. Qed.
Lemma pbits_unlock_unshared γ
bs β
s :
Forall sep_unshared γ
bs →
Forall sep_unshared (
zip_with pbit_unlock_if γ
bs β
s).
Proof.
intros Hγbs. revert βs. induction Hγbs; intros [|[] ?];
simpl; constructor; auto using pbit_unlock_unshared.
Qed.
Lemma pbit_unlock_unmapped γ
b :
sep_unmapped γ
b →
sep_unmapped (
pbit_unlock γ
b).
Proof.
destruct γb; sep_unfold; naive_solver auto using perm_unlock_unmapped.
Qed.
Lemma pbit_unlock_mapped γ
b :
sep_valid γ
b →
sep_unmapped (
pbit_unlock γ
b) →
sep_unmapped γ
b.
Proof.
destruct γb; sep_unfold; naive_solver auto using perm_unlock_mapped. Qed.
Lemma pbits_kind_weaken γ
bs k1 k2 :
Forall (λ γ
b,
k2 ⊆
pbit_kind γ
b) γ
bs →
k1 ⊆
k2 →
Forall (λ γ
b,
k1 ⊆
pbit_kind γ
b) γ
bs.
Proof.
intros. eapply Forall_impl; eauto. intros γb ?. by transitivity k2. Qed.
Lemma pbits_mapped γ
bs :
Forall (λ γ
b,
Some Readable ⊆
pbit_kind γ
b) γ
bs →
Forall (
not ∘
sep_unmapped) γ
bs.
Proof.
induction 1 as [|[x b]]; constructor; auto.
intros [??]; simplify_equality'; eapply perm_mapped; eauto.
Qed.
Lemma PBits_unshared γ
s bs :
Forall sep_unshared γ
s →
Forall sep_unshared (
zip_with PBit γ
s bs).
Proof.
intros Hγs. revert bs. induction Hγs; intros [|??]; constructor; eauto.
Qed.
Lemma pbits_unshared γ
bs :
Forall sep_valid γ
bs →
Forall (λ γ
b,
Some Locked ⊆
pbit_kind γ
b) γ
bs →
Forall sep_unshared γ
bs.
Proof.
induction 1 as [|[x b] ? [??]]; intros; decompose_Forall_hyps;
repeat constructor; sep_unfold; auto using perm_unshared.
Qed.
Lemma PBits_indetify γ
s :
pbit_indetify <$>
flip PBit (@
BIndet K) <$> γ
s =
flip PBit BIndet <$> γ
s.
Proof.
induction γs; f_equal'; auto. Qed.
Lemma pbit_indetify_valid Γ Δ γ
b : ✓{Γ,Δ} γ
b → ✓{Γ,Δ} (
pbit_indetify γ
b).
Proof.
destruct γb; intros (?&?&?); repeat split; eauto using BIndet_valid. Qed.
Lemma pbits_indetify_valid Γ Δ γ
bs :
✓{Γ,Δ}* γ
bs → ✓{Γ,Δ}* (
pbit_indetify <$> γ
bs).
Proof.
induction 1; csimpl; auto using pbit_indetify_valid. Qed.
Lemma pbits_indetify_idempotent γ
bs :
pbit_indetify <$>
pbit_indetify <$> γ
bs =
pbit_indetify <$> γ
bs.
Proof.
by induction γbs; f_equal'. Qed.
Lemma pbit_indetify_unmapped γ
b :
sep_unmapped γ
b →
pbit_indetify γ
b = γ
b.
Proof.
destruct γb; intros [??]; naive_solver. Qed.
Lemma pbit_unmapped_indetify γ
b :
sep_unmapped γ
b →
sep_unmapped (
pbit_indetify γ
b).
Proof.
destruct γb; intros [??]; split; naive_solver. Qed.
Lemma pbits_unmapped_tag γ
bs :
Forall sep_unmapped γ
bs →
tagged_tag <$> γ
bs =
replicate (
length γ
bs)
BIndet.
Proof.
by induction 1 as [|?? []]; f_equal'. Qed.
Lemma pbit_unmapped_indetify_inv γ
b :
sep_valid γ
b →
sep_unmapped (
pbit_indetify γ
b) →
sep_unmapped γ
b.
Proof.
destruct γb; intros [??] [??]; split; naive_solver. Qed.
Lemma pbits_unmapped_indetify_inv β
s γ
bs :
Forall sep_valid γ
bs →
Forall sep_unmapped (
mask pbit_indetify β
s γ
bs) →
Forall sep_unmapped γ
bs.
Proof.
intros Hγbs. revert βs. induction Hγbs; intros [|[] ?] ?;
decompose_Forall_hyps; eauto using pbit_unmapped_indetify_inv.
Qed.
Lemma pbits_indetify_unmapped γ
bs :
Forall sep_unmapped γ
bs →
pbit_indetify <$> γ
bs = γ
bs.
Proof.
induction 1; f_equal'; auto using pbit_indetify_unmapped. Qed.
Lemma pbits_indetify_mask_unmapped β
s γ
bs :
Forall sep_unmapped γ
bs →
mask pbit_indetify β
s γ
bs = γ
bs.
Proof.
intros Hγbs. revert βs. induction Hγbs;
intros [|[] ?]; f_equal'; auto using pbit_indetify_unmapped.
Qed.
Lemma pbit_indetify_unshared γ
b :
sep_unshared γ
b →
sep_unshared (
pbit_indetify γ
b).
Proof.
done. Qed.
Lemma pbit_full_valid Γ Δ : ✓{Γ,Δ}
pbit_full.
Proof.
by apply (bool_decide_unpack _). Qed.
Lemma pbit_full_unshared :
sep_unshared (@
pbit_full K).
Proof.
done. Qed.
Lemma PBits_BIndet_tag γ
bs :
Forall sep_unmapped γ
bs →
flip PBit BIndet <$>
tagged_perm <$> γ
bs = γ
bs.
Proof.
induction 1 as [|[] ? [??]]; simplify_equality'; f_equal; auto. Qed.
Lemma pbit_Readable_locked γ
b :
Some Readable ⊆
pbit_kind γ
b →
pbit_locked γ
b =
false.
Proof.
by destruct γb; f_equal'; auto using perm_Readable_locked. Qed.
Lemma pbits_Readable_locked γ
bs i :
Forall (λ γ
b,
Some Readable ⊆
pbit_kind γ
b) γ
bs →
i <
length γ
bs →
pbit_locked <$> γ
bs !!
i =
Some false.
Proof.
intros Hγbs. revert i. induction Hγbs; intros [|?] ?;
f_equal'; auto using pbit_Readable_locked with lia.
Qed.
Lemma pbits_unlock_sep_valid γ
bs β
s :
Forall sep_valid γ
bs →
Forall sep_valid (
zip_with pbit_unlock_if γ
bs β
s).
Proof.
sep_unfold; intros Hγbs; revert βs.
induction Hγbs as [|[]]; intros [|[] ?]; constructor;
naive_solver eauto using perm_unlock_valid, perm_unlock_mapped.
Qed.
Lemma pbits_locks_unlock β
s γ
bs :
β
s =.>*
pbit_locked <$> γ
bs →
pbit_locked <$>
zip_with pbit_unlock_if γ
bs β
s = (
pbit_locked <$> γ
bs) ∖* β
s.
Proof.
revert βs. induction γbs as [|[[[]|]] ?]; intros [|[] ?] ?;
decompose_Forall_hyps; f_equal; auto.
Qed.
Lemma pbits_unlock_empty_inv γ
bs β
s :
Forall (∅ =) (
zip_with pbit_unlock_if γ
bs β
s) →
Forall sep_valid γ
bs →
length γ
bs =
length β
s →
Forall (∅ =) γ
bs.
Proof.
assert (∀ γ, sep_valid γ → perm_unlock γ = ∅ → γ = ∅).
{ intros [[]|]; repeat sep_unfold; naive_solver. }
intros Hγbs Hγbs'. revert βs Hγbs.
induction Hγbs' as [|[] ? []]; intros [|[] ?]; sep_unfold;
intros; decompose_Forall_hyps; constructor; eauto.
f_equal; eauto using eq_sym.
Qed.
Lemma pbits_unlock_mapped γ
bs β
s :
Forall sep_unmapped (
zip_with pbit_unlock_if γ
bs β
s) →
Forall sep_valid γ
bs →
length γ
bs =
length β
s →
Forall sep_unmapped γ
bs.
Proof.
intros Hγbs Hγbs'. revert βs Hγbs. induction Hγbs' as [|[] ? []]; sep_unfold;
intros [|[] ?] ??; decompose_Forall_hyps; constructor;
intuition eauto using perm_unlock_mapped.
Qed.
Lemma pbits_unlock_valid Γ Δ γ
bs β
s :
✓{Γ,Δ}* γ
bs → ✓{Γ,Δ}* (
zip_with pbit_unlock_if γ
bs β
s).
Proof.
intros Hγs. revert βs.
induction Hγs; intros [|[] ?]; simpl; auto using pbit_unlock_valid.
Qed.
Lemma pbit_indetify_unlock γ
bs β
s :
pbit_indetify <$>
zip_with pbit_unlock_if γ
bs β
s
=
zip_with pbit_unlock_if (
pbit_indetify <$> γ
bs) β
s.
Proof.
revert βs. induction γbs; intros [|[] ?]; f_equal'; auto. Qed.
Lemma pbits_unlock_orb γ
bs β
s1 β
s2 :
zip_with pbit_unlock_if γ
bs (β
s1 ||* β
s2)
=
zip_with pbit_unlock_if (
zip_with pbit_unlock_if γ
bs β
s1) β
s2.
Proof.
revert βs1 βs2. induction γbs as [|[]]; intros [|[] ?] [|[] ?];
f_equal'; auto using perm_unlock_unlock with f_equal.
Qed.
Lemma pbits_lock_mapped γ
bs :
Forall (
not ∘
sep_unmapped) γ
bs →
Forall (
not ∘
sep_unmapped) (
pbit_lock <$> γ
bs).
Proof.
sep_unfold. induction 1; constructor; simpl in *;
intuition eauto using perm_lock_mapped.
Qed.
Lemma pbit_lock_indetified γ
b :
pbit_indetify γ
b = γ
b →
pbit_indetify (
pbit_lock γ
b) =
pbit_lock γ
b.
Proof.
by intros <-. Qed.
Lemma pbits_lock_valid Γ Δ γ
bs :
✓{Γ,Δ}* γ
bs →
Forall (λ γ
b,
Some Writable ⊆
pbit_kind γ
b) γ
bs →
✓{Γ,Δ}* (
pbit_lock <$> γ
bs).
Proof.
induction 1 as [|[??] ? (?&?&?)]; repeat constructor; decompose_Forall_hyps;
eauto using perm_lock_valid, perm_lock_mapped.
Qed.
Lemma pbit_lock_unmapped γ
b :
Some Writable ⊆
pbit_kind γ
b →
sep_unmapped γ
b →
sep_unmapped (
pbit_lock γ
b).
Proof.
intros ? [??]; split; auto. by apply perm_lock_unmapped. Qed.
Lemma pbit_lock_mapped γ
b :
sep_unmapped (
pbit_lock γ
b) →
sep_unmapped γ
b.
Proof.
intros [??]; split; auto using perm_lock_mapped. Qed.
Lemma pbit_lock_unshared γ
b :
sep_unshared γ
b →
sep_unshared (
pbit_lock γ
b).
Proof.
apply perm_lock_unshared. Qed.
Lemma pbits_perm_mask β
s γ
bs :
tagged_perm <$>
mask pbit_indetify β
s γ
bs =
tagged_perm <$> γ
bs.
Proof.
revert βs. induction γbs; intros [|[] ?]; f_equal'; auto. Qed.
Lemma pbits_locked_mask β
s γ
bs :
pbit_locked <$>
mask pbit_indetify β
s γ
bs =
pbit_locked <$> γ
bs.
Proof.
revert βs. induction γbs; intros [|[] ?]; f_equal'; auto. Qed.
End permission_bits.