Commit 10752ffb authored by Dan Frumin's avatar Dan Frumin
Browse files

Some valuable comments and invaluable proofs in flock.v

parent 612e3938
...@@ -50,19 +50,23 @@ Record flock_name := { ...@@ -50,19 +50,23 @@ Record flock_name := {
flock_state_name : gname; flock_state_name : gname;
(** -//- for keeping track of all propositions in the flock *) (** -//- for keeping track of all propositions in the flock *)
flock_props_name : gname; flock_props_name : gname;
(** -//- for keeping track of the "active" propositions, (** -//- for keeping track of the "active" propositions.
once you relase the lock you need to know that the set of the active propositions Once you relase the lock you need to know that the set of the active propositions
has not changed since you have acquired it *) has not changed since you have acquired it *)
flock_props_active_name : gname flock_props_active_name : gname
}. }.
(* Defined as `positive` so that we have a `Fresh` instance for `gset positive`. (** The data about pending and active propositions will be stored in
the maps `prop_id -> _` *)
(* `prop_id` is fefined as `positive` so that we have a `Fresh` instance for `gset positive`.
Doubles as an invariant name. *) Doubles as an invariant name. *)
Definition prop_id := positive. Definition prop_id := positive.
Canonical Structure gnameC := leibnizC gname. Canonical Structure gnameC := leibnizC gname.
(** The trick here is to store only ghost names associated with a 'flock resource' in the flock invariant. (** One of the tricks in this lock is to store only ghost names associated with a 'flock resource' in the flock invariant.
If we start storing propositions, then we end up in the LATER HELL *) If we start storing propositions, then we end up in the LATER HELL.
The `lock_res_name` datastructure contains all the ghosts names needed to manage an individual proposition.
*)
Record lock_res_name := { Record lock_res_name := {
flock_cinv_name : gname; flock_cinv_name : gname;
flock_token1_name : gname; flock_token1_name : gname;
...@@ -70,6 +74,22 @@ Record lock_res_name := { ...@@ -70,6 +74,22 @@ Record lock_res_name := {
}. }.
Canonical Structure lock_res_nameC := leibnizC lock_res_name. Canonical Structure lock_res_nameC := leibnizC lock_res_name.
(** Before we define the type of flock resources, we need to have
access to the appropriate CMRAs.
The totality of propositions , and the pending propositions will be
represented as a map:
`prop_id → frac * ag (flock_res_name)`,
so a standart ghost heap. Active propositions will be modelled by a map
`excl (prop_id → frac * ag (flock_res_name))`.
In other words, this map will contain *exact* information of which propositions are active and with what fractions were they activated.
*)
Class flockG Σ := Class flockG Σ :=
FlockG { FlockG {
flock_stateG :> inG Σ (authR (optionUR (exclR lockstateC))); flock_stateG :> inG Σ (authR (optionUR (exclR lockstateC)));
...@@ -81,27 +101,26 @@ Class flockG Σ := ...@@ -81,27 +101,26 @@ Class flockG Σ :=
flock_tokens :> inG Σ (exclR unitC); flock_tokens :> inG Σ (exclR unitC);
}. }.
Definition flockΣ : gFunctors :=
#[GFunctor (authR (optionUR (exclR lockstateC)))
;lockΣ
;cinvΣ
;GFunctor (authR (optionUR (exclR (gmapC prop_id (prodC fracC lock_res_nameC)))))
;GFunctor (authR (gmapUR prop_id (prodR fracR (agreeR lock_res_nameC))))%CF].
Instance subG_flockΣ Σ : subG flockΣ Σ flockG Σ.
Proof. solve_inG. Qed.
Record lock_res `{flockG Σ} := { Record lock_res `{flockG Σ} := {
res_prop : iProp Σ; res_prop : iProp Σ;
res_frac : frac; res_frac : frac;
res_name : lock_res_name; res_name : lock_res_name;
}. }.
(** A "smart constructor" for `lock_res` *)
Definition LockRes `{flockG Σ} (R : iProp Σ) (π : frac) (ρ : lock_res_name) := Definition LockRes `{flockG Σ} (R : iProp Σ) (π : frac) (ρ : lock_res_name) :=
{| res_prop := R; res_frac := π; res_name := ρ |}. {| res_prop := R; res_frac := π; res_name := ρ |}.
(* TODO: DF, finish this *)
(* Definition flockΣ : gFunctors := *)
(* #[GFunctor (authR (optionUR (exclR lockstateC))) *)
(* ;lockΣ *)
(* ;savedPropΣ *)
(* ;GFunctor fracR *)
(* ;GFunctor (authR (optionUR (exclR (gmapC prop_id PropPermC)))) *)
(* ;GFunctor (authR (gmapUR prop_id (prodR fracR (agreeR (prodC gnameC gnameC)))))%CF]. *)
(* Instance subG_flockΣ Σ : subG flockΣ Σ → flockG Σ. *)
(* Proof. solve_inG. Qed. *)
Section flock. Section flock.
Context `{heapG Σ, flockG Σ}. Context `{heapG Σ, flockG Σ}.
Variable N : namespace. Variable N : namespace.
...@@ -115,13 +134,10 @@ Section flock. ...@@ -115,13 +134,10 @@ Section flock.
Definition token (ρ : lock_res_name) : iProp Σ := Definition token (ρ : lock_res_name) : iProp Σ :=
own (flock_token2_name ρ) (Excl ()). own (flock_token2_name ρ) (Excl ()).
(* Definition C' (X : lock_res) : iProp Σ := *)
(* (res_prop X ∗ token₁ (res_name X) ∨ token₂ (res_name X))%I. *)
Definition C (R : iProp Σ) (ρ : lock_res_name) : iProp Σ := Definition C (R : iProp Σ) (ρ : lock_res_name) : iProp Σ :=
(R token ρ token ρ)%I. (R token ρ token ρ)%I.
(* Tokens that allow you to get all the propositions from `A` out of the invariants *) (** Tokens that allow you to get all the propositions from `A` out of the invariants *)
Definition all_tokens (P : gmap prop_id lock_res_name) : iProp Σ := Definition all_tokens (P : gmap prop_id lock_res_name) : iProp Σ :=
([ map] i X P, token X)%I. ([ map] i X P, token X)%I.
...@@ -129,11 +145,22 @@ Section flock. ...@@ -129,11 +145,22 @@ Section flock.
Definition from_active (A : gmap prop_id (frac * lock_res_name)) Definition from_active (A : gmap prop_id (frac * lock_res_name))
:= fmap snd A. := fmap snd A.
(** A flock resource `s ↦ X,π,γ` contains:
- Knowledge that the `s ↦{π} γ` is in the set of propositions managed by the flock;
- There is a cancellable invariant `C X γ`;
- We have π- permissiones to access that invariant.
*)
Definition flock_res (γ : flock_name) (s : prop_id) (X : lock_res) : iProp Σ := Definition flock_res (γ : flock_name) (s : prop_id) (X : lock_res) : iProp Σ :=
(own (flock_props_name γ) ( {[s := (res_frac X, to_agree (res_name X))]}) (own (flock_props_name γ) ( {[s := (res_frac X, to_agree (res_name X))]})
cinv (resN.@s) (flock_cinv_name (res_name X)) (C (res_prop X) (res_name X)) cinv (resN.@s) (flock_cinv_name (res_name X)) (C (res_prop X) (res_name X))
cinv_own (flock_cinv_name (res_name X)) (res_frac X))%I. cinv_own (flock_cinv_name (res_name X)) (res_frac X))%I.
(** Basically says that the propositions from the map `A` are active.
This predicate is designed to contain enough information to deactivate those propositions.
When we are deactivating the propositions we need to make sure that the set of the active propositions has not changed. That's why we need a CMRA to keep track of the exact contents of that set.
*)
Definition flocked Definition flocked
(γ : flock_name) (A : gmap prop_id lock_res) : iProp Σ := (γ : flock_name) (A : gmap prop_id lock_res) : iProp Σ :=
( fa : gmap prop_id (frac * lock_res_name), ( fa : gmap prop_id (frac * lock_res_name),
...@@ -151,22 +178,38 @@ Section flock. ...@@ -151,22 +178,38 @@ Section flock.
: gmapUR prop_id (prodR fracR (agreeR lock_res_nameC)) := : gmapUR prop_id (prodR fracR (agreeR lock_res_nameC)) :=
fmap (λ X, (1%Qp, to_agree X)) f. fmap (λ X, (1%Qp, to_agree X)) f.
(** TODO: can we actually get rid of the `to_props_map` here? *)
Definition flock_inv (γ : flock_name) : iProp Σ := Definition flock_inv (γ : flock_name) : iProp Σ :=
( (s : lockstate) ( (s : lockstate)
(** fa -- active propositions, fp -- pending propositions *) (** fa -- active propositions, fp -- pending propositions *)
(fa : gmap prop_id (frac * lock_res_name)) (fa : gmap prop_id (frac * lock_res_name))
(fp : gmap prop_id lock_res_name), (fp : gmap prop_id lock_res_name),
(** ... and those sets are disjoint *)
fp ## from_active fa fp ## from_active fa
own (flock_state_name γ) ( (Excl' s)) own (flock_state_name γ) ( (Excl' s))
(** the totality of resources: fp ∪ fa *)
own (flock_props_name γ) ( to_props_map (fp from_active fa)) own (flock_props_name γ) ( to_props_map (fp from_active fa))
(** but we also need to know the exact contents of fa *)
own (flock_props_active_name γ) ( Excl' fa) own (flock_props_active_name γ) ( Excl' fa)
(** the invariant keeps track of the tokens (token₂) for the
pending resource; when we activate a resource, we transfer
this token to the client, which uses it to open the
cinvariant and get the actual proposition. *)
all_tokens fp all_tokens fp
match s with match s with
| Locked => | Locked =>
(** If the lock is acuired, then we hold on to the token from the "old" specification *)
locked (flock_lock_name γ) locked (flock_lock_name γ)
([ map] i πX fa, own (flock_props_name γ) ( {[i:=(πX.1,to_agree πX.2)]})) (** .. and we take hold of all the ghost pointsto `s ↦{π} ρ`.
This is necessary to have if we want to free the
resources. If we wish to free the resource `s ↦{1} ρ`,
then we need to know that it is not currently active (has
not been acquired). The predicate below ensures that. *)
([ map] i πρ fa, own (flock_props_name γ) ( {[i:=(πρ.1,to_agree πρ.2)]}))
| Unlocked => | Unlocked =>
(* there are no active proposition *) (** If the lock is NOT acquired, then there are no active
proposition *)
own (flock_props_active_name γ) ( Excl' ) own (flock_props_active_name γ) ( Excl' )
end)%I. end)%I.
...@@ -178,34 +221,46 @@ Section flock. ...@@ -178,34 +221,46 @@ Section flock.
(** * Lemmata **) (** * Lemmata **)
(** ** Basic properties of the CAPs *) (** ** Basic properties of the CAPs *)
(* Lemma flock_res_op (γ : flock_name) (s : prop_id) (R : iProp Σ) (π1 π2 : frac) : *) (* TODO, we only have this for the "smart constructor" *)
(* flock_res γ s R (π1+π2) ⊣⊢ flock_res γ s R π1 ∗ flock_res γ s R π2. *) Lemma flock_res_agree (γ : flock_name) (s : prop_id) (R1 R2 : iProp Σ) ρ1 ρ2 (π1 π2 : frac) :
(* Proof. *) flock_res γ s (LockRes R1 π1 ρ1) -
(* rewrite /flock_res. iSplit. *) flock_res γ s (LockRes R2 π2 ρ2) ==
(* - iDestruct 1 as (ρ) "(Hs & #Hinv & Hρ)". *) ⌜ρ1 = ρ2.
(* iDestruct "Hρ" as "[Hρ1 Hρ2]". *) Proof.
(* iDestruct "Hs" as "[Hs1 Hs2]". *) rewrite /flock_res.
(* iSplitL "Hρ1 Hs1"; iExists _; by iFrame. *) iDestruct 1 as "(Hs1 & #Hinv1 & Hρ1)".
(* - iIntros "[H1 H2]". *) iDestruct 1 as "(Hs2 & #Hinv2 & Hρ2)".
(* iDestruct "H1" as (ρ) "(Hs1 & #Hinv1 & Hρ1)". *) iCombine "Hs1 Hs2" as "Hs".
(* iDestruct "H2" as (ρ') "(Hs2 & #Hinv2 & Hρ2)". *) iDestruct (own_valid with "Hs")
(* iCombine "Hs1 Hs2" as "Hs". *) as %Hfoo%auth_valid_discrete.
(* iDestruct (own_valid with "Hs") *) simpl in Hfoo. apply singleton_valid in Hfoo.
(* as %Hfoo%auth_valid_discrete. *) destruct Hfoo as [_ Hfoo%agree_op_inv']. eauto.
(* simpl in Hfoo. apply singleton_valid in Hfoo. *) Qed.
(* destruct Hfoo as [_ Hfoo%agree_op_inv']. *)
(* fold_leibniz. rewrite -!Hfoo. *) Lemma flock_res_op (γ : flock_name) (s : prop_id) (R : iProp Σ) ρ (π1 π2 : frac) :
(* iCombine "Hρ1 Hρ2" as "Hρ". *) flock_res γ s (LockRes R (π1+π2) ρ)
(* rewrite !frac_op' agree_idemp. *) flock_res γ s (LockRes R π1 ρ) flock_res γ s (LockRes R π2 ρ).
(* iExists ρ. by iFrame. *) Proof.
(* Qed. *) rewrite /flock_res. iSplit.
- iDestruct 1 as "(Hs & #Hinv & Hρ)".
(* Global Instance flock_res_fractional γ s R : Fractional (flock_res γ s R). *) iDestruct "Hρ" as "[Hρ1 Hρ2]".
(* Proof. intros p q. apply flock_res_op. Qed. *) iDestruct "Hs" as "[Hs1 Hs2]".
iSplitL "Hρ1 Hs1"; by iFrame.
(* Global Instance flock_res_as_fractional γ s R π : *) - iIntros "[H1 H2]".
(* AsFractional (flock_res γ s R π) (flock_res γ s R) π. *) iDestruct "H1" as "(Hs1 & #Hinv1 & Hρ1)".
(* Proof. split. done. apply _. Qed. *) iDestruct "H2" as "(Hs2 & #Hinv2 & Hρ2)".
iCombine "Hs1 Hs2" as "Hs". iFrame.
rewrite /C /=. iFrame "Hinv1".
Qed.
Global Instance flock_res_fractional γ s R ρ :
Fractional (λ π, flock_res γ s (LockRes R π ρ)).
Proof. intros p q. apply flock_res_op. Qed.
Global Instance flock_res_as_fractional γ s R π ρ :
AsFractional (flock_res γ s (LockRes R π ρ))
(λ π, flock_res γ s (LockRes R π ρ)) π.
Proof. split. done. apply _. Qed.
Lemma to_props_map_singleton_included fp i q ρ: Lemma to_props_map_singleton_included fp i q ρ:
{[i := (q, to_agree ρ)]} to_props_map fp fp !! i = Some ρ. {[i := (q, to_agree ρ)]} to_props_map fp fp !! i = Some ρ.
...@@ -596,15 +651,6 @@ Section flock. ...@@ -596,15 +651,6 @@ Section flock.
by apply auth_update_alloc. by apply auth_update_alloc.
Qed. Qed.
(* THIS IS NOT TRUE *)
Global Instance snd_cmramorphism :
CmraMorphism (@snd Qp (agree lock_res_name)).
Proof.
split; first apply _.
- move=> n [? ?] [// ?].
- move=> [a b]/=. admit.
Admitted.
Lemma acquire_flock_spec γ lk (I : gmap prop_id lock_res) : Lemma acquire_flock_spec γ lk (I : gmap prop_id lock_res) :
{{{ is_flock γ lk [ map] i X I, flock_res γ i X }}} {{{ is_flock γ lk [ map] i X I, flock_res γ i X }}}
acquire lk acquire lk
...@@ -681,11 +727,11 @@ Section flock. ...@@ -681,11 +727,11 @@ Section flock.
snd <$> f <$> I ≼ snd <$> g <$> fp snd <$> f <$> I ≼ snd <$> g <$> fp
= to_agree o res_name <$> I ≼ to_agree <$> fp *) = to_agree o res_name <$> I ≼ to_agree <$> fp *)
assert (((snd <$> (f <$> I)) : gmapUR prop_id (agreeR lock_res_nameC)) (snd <$> (g <$> fp))) as Hbar. assert (((snd <$> (f <$> I)) : gmapUR prop_id (agreeR lock_res_nameC)) (snd <$> (g <$> fp))) as Hbar.
{ (* TODO: this is the /proper/ proof of the statement, but { (* TODO DOESN"T WORK SAD *)
the proof is incorrect because currently projections are (* Check (gmap_fmap_mono snd (f <$> I) (g <$> fp)). *)
not morphisms *) admit.
eapply cmra_morphism_monotone; last exact: Hfoo. (* eapply cmra_morphism_monotone; last exact: Hfoo. *)
apply gmap_fmap_cmra_morphism. apply _. (* apply gmap_fmap_cmra_morphism. apply _. *)
} }
rewrite -!map_fmap_compose in Hbar. rewrite -!map_fmap_compose in Hbar.
assert ((to_agree res_name <$> I) to_agree <$> fp) as Hbaz by exact: Hbar. assert ((to_agree res_name <$> I) to_agree <$> fp) as Hbaz by exact: Hbar.
...@@ -748,7 +794,7 @@ Section flock. ...@@ -748,7 +794,7 @@ Section flock.
iFrame. iSplit; eauto. iFrame. iSplit; eauto.
rewrite big_sepM_fmap. rewrite big_sepM_fmap.
iApply (big_sepM_own_frag with "Hemp HI"). iApply (big_sepM_own_frag with "Hemp HI").
Qed. Admitted.
Lemma release_cancel_spec' γ lk I : Lemma release_cancel_spec' γ lk I :
{{{ is_flock γ lk flocked γ I }}} {{{ is_flock γ lk flocked γ I }}}
......
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