aneris_examples.ccddb.proof.proof_of_init
Proof the causal memory implementation w.r.t. modular specification.
From RecordUpdate Require Import RecordSet.
From iris.algebra Require Import agree auth excl gmap.
From iris.base_logic Require Import invariants.
From aneris.aneris_lang Require Import lang network notation tactics proofmode lifting.
From aneris_examples.ccddb Require Import code.
From aneris_examples.ccddb.spec Require Import base.
From aneris_examples.ccddb.model Require Import
model_lst model_gst model_update_system.
From aneris_examples.ccddb.resources Require Import
base resources_gmem resources_lhst resources_local_inv resources_global_inv.
From aneris_examples.ccddb.proof Require Import
proof_of_read proof_of_write proof_of_apply proof_of_network.
Import Network.
Section proof.
Context `{!anerisG Σ, !DB_params, !internal_DBG Σ}.
Context (γGauth γGsnap γGkeep : gname) (γLs : list (gname * gname)).
Lemma internal_init_spec_holds :
Global_Inv γGauth γGsnap γGkeep γLs ⊢
□ ∀ (A : gset socket_address) (i: nat) (z : socket_address)
(v : base_lang.val),
⌜list_coh (map (λ x : socket_address, #x) DB_addresses) v⌝ →
⌜DB_addresses !! i = Some z⌝ →
⌜z ∈ A⌝ →
{{{ fixed A ∗ ([∗ list] i ↦ z ∈ DB_addresses, z ⤇ socket_proto γGsnap) ∗
free_ports (ip_of_address z) {[port_of_address z]} ∗
local_history_Local_inv γLs i ∅ }}}
ccddb_init
(DBS_ser DB_serialization) (DBS_deser DB_serialization) v #i
@[ip_of_address z]
{{{ rd wr, RET (rd, wr);
local_history_seen γLs i ∅ ∗
internal_read_spec γGsnap γLs rd i z ∗
internal_write_spec γGauth γGsnap γGkeep γLs wr i z}}}.
Proof.
iIntros "#Hinv !#" (A i z v Hv Hiz HzA Φ)
"!# (#HA & #Hz & Hfp & Hliv) HΦ".
remember (ip_of_address z) as ip.
rewrite /ccddb_init.
wp_pures.
wp_apply empty_str_spec; first done.
iIntros (db Hdb); simpl.
wp_alloc ℓDB as "HDB".
wp_pures.
wp_apply list_length_spec; first done.
iIntros (? ->).
rewrite map_length.
wp_pures.
replace #0 with #0%nat; last done.
wp_apply vect_make_spec; first done.
iIntros (t Ht).
wp_alloc ℓT as "HT".
wp_pures.
wp_apply list_make_spec; first done.
iIntros (iq Hiq).
wp_alloc ℓIQ as "HIQ".
wp_pures.
wp_apply list_make_spec; first done.
iIntros (oq Hoq).
wp_alloc ℓOQ as "HOQ".
wp_pures.
iApply fupd_aneris_wp.
iMod (observe_local_history with "Hinv Hliv") as "[Hliv #Hseen]";
first done.
iModIntro.
wp_apply (newlock_spec
(nroot.@"lk") _ (local_inv_def γGsnap γLs i ℓDB ℓT ℓIQ ℓOQ)
with "[Hliv HDB HT HIQ HOQ]").
{iExists _, _, _, _, ∅, _, [], []. iExists ∅, _; simpl; iFrame.
repeat iSplit; [|done|done|done|done|done|done|]; iPureIntro.
- by rewrite Hiz /= Heqip.
- replace (replicate (length DB_addresses) 0) with initial_time.
+ apply DBM_Lst_valid_empty; apply lookup_lt_is_Some_1; eauto.
+ symmetry; apply replicate_as_elem_of.
rewrite /initial_time fmap_length.
set_solver. }
iIntros (lk γlk) "#Hlk".
wp_pures.
wp_socket h as "Hh".
wp_pures.
wp_apply (list_nth_spec_some).
{ iPureIntro; split; eauto with lia.
rewrite map_length. apply lookup_lt_is_Some_1; eauto. }
iIntros (ithSome ( ith & -> & Hh)). simpl.
wp_apply unSOME_spec; eauto; iIntros (_).
wp_let.
assert (ith = #z) as ->.
{ pose proof nth_error_lookup _ _ _ Hh as Ha.
apply map_lookup_Some in Ha as (a & -> & Hia).
rewrite Hiz in Hia.
inversion Hia; subst a; done. }
rewrite Heqip.
wp_apply (aneris_wp_socketbind_static with "[$]"); [done|done|done|].
rewrite -Heqip.
iIntros "[Hskt _]"; wp_seq. wp_pures.
wp_apply aneris_wp_fork.
iSplitL; last first.
{ iNext.
rewrite Heqip.
wp_apply apply_spec_holds; last done.
rewrite Hiz.
repeat iSplit; done. }
iNext.
wp_pures.
set (s := RecordSet.set saddress (λ _ : option socket_address, Some z)
{| sfamily := PF_INET; stype := SOCK_DGRAM;
sprotocol := IPPROTO_UDP; saddress := None |}).
iApply fupd_aneris_wp.
iAssert (|={⊤}=> socket_inv γGsnap z h s)%I with "[Hskt]" as ">#Hsocketinv".
{ rewrite Heqip.
iApply inv_alloc. iNext. iExists _, _; iFrame.
rewrite big_sepS_empty; done. }
iModIntro.
wp_apply aneris_wp_fork.
iSplitL; last first.
{ iNext.
rewrite Heqip.
wp_apply send_thread_spec; last done.
iDestruct (big_sepL_lookup _ _ _ _ Hiz with "Hz") as "Hz'".
iFrame "#"; done. }
iNext.
wp_pures.
wp_apply aneris_wp_fork.
iSplitL; last first.
{ iNext.
rewrite Heqip.
wp_apply (recv_thread_spec _ _ _ _ i _ _ _ _ _ _ z); last done.
rewrite Hiz /=.
iDestruct (big_sepL_lookup _ _ _ _ Hiz with "Hz") as "Hz'".
iFrame "#"; done. }
iNext.
wp_pures.
rewrite Heqip.
wp_apply internal_write_spec_holds; first by iFrame "#".
iIntros (wr) "Hwr"; simpl.
wp_apply internal_read_spec_holds; first by iFrame "#".
iIntros (rd) "Hrd"; simpl.
wp_pures.
iApply "HΦ".
iFrame; done.
Qed.
End proof.
From iris.algebra Require Import agree auth excl gmap.
From iris.base_logic Require Import invariants.
From aneris.aneris_lang Require Import lang network notation tactics proofmode lifting.
From aneris_examples.ccddb Require Import code.
From aneris_examples.ccddb.spec Require Import base.
From aneris_examples.ccddb.model Require Import
model_lst model_gst model_update_system.
From aneris_examples.ccddb.resources Require Import
base resources_gmem resources_lhst resources_local_inv resources_global_inv.
From aneris_examples.ccddb.proof Require Import
proof_of_read proof_of_write proof_of_apply proof_of_network.
Import Network.
Section proof.
Context `{!anerisG Σ, !DB_params, !internal_DBG Σ}.
Context (γGauth γGsnap γGkeep : gname) (γLs : list (gname * gname)).
Lemma internal_init_spec_holds :
Global_Inv γGauth γGsnap γGkeep γLs ⊢
□ ∀ (A : gset socket_address) (i: nat) (z : socket_address)
(v : base_lang.val),
⌜list_coh (map (λ x : socket_address, #x) DB_addresses) v⌝ →
⌜DB_addresses !! i = Some z⌝ →
⌜z ∈ A⌝ →
{{{ fixed A ∗ ([∗ list] i ↦ z ∈ DB_addresses, z ⤇ socket_proto γGsnap) ∗
free_ports (ip_of_address z) {[port_of_address z]} ∗
local_history_Local_inv γLs i ∅ }}}
ccddb_init
(DBS_ser DB_serialization) (DBS_deser DB_serialization) v #i
@[ip_of_address z]
{{{ rd wr, RET (rd, wr);
local_history_seen γLs i ∅ ∗
internal_read_spec γGsnap γLs rd i z ∗
internal_write_spec γGauth γGsnap γGkeep γLs wr i z}}}.
Proof.
iIntros "#Hinv !#" (A i z v Hv Hiz HzA Φ)
"!# (#HA & #Hz & Hfp & Hliv) HΦ".
remember (ip_of_address z) as ip.
rewrite /ccddb_init.
wp_pures.
wp_apply empty_str_spec; first done.
iIntros (db Hdb); simpl.
wp_alloc ℓDB as "HDB".
wp_pures.
wp_apply list_length_spec; first done.
iIntros (? ->).
rewrite map_length.
wp_pures.
replace #0 with #0%nat; last done.
wp_apply vect_make_spec; first done.
iIntros (t Ht).
wp_alloc ℓT as "HT".
wp_pures.
wp_apply list_make_spec; first done.
iIntros (iq Hiq).
wp_alloc ℓIQ as "HIQ".
wp_pures.
wp_apply list_make_spec; first done.
iIntros (oq Hoq).
wp_alloc ℓOQ as "HOQ".
wp_pures.
iApply fupd_aneris_wp.
iMod (observe_local_history with "Hinv Hliv") as "[Hliv #Hseen]";
first done.
iModIntro.
wp_apply (newlock_spec
(nroot.@"lk") _ (local_inv_def γGsnap γLs i ℓDB ℓT ℓIQ ℓOQ)
with "[Hliv HDB HT HIQ HOQ]").
{iExists _, _, _, _, ∅, _, [], []. iExists ∅, _; simpl; iFrame.
repeat iSplit; [|done|done|done|done|done|done|]; iPureIntro.
- by rewrite Hiz /= Heqip.
- replace (replicate (length DB_addresses) 0) with initial_time.
+ apply DBM_Lst_valid_empty; apply lookup_lt_is_Some_1; eauto.
+ symmetry; apply replicate_as_elem_of.
rewrite /initial_time fmap_length.
set_solver. }
iIntros (lk γlk) "#Hlk".
wp_pures.
wp_socket h as "Hh".
wp_pures.
wp_apply (list_nth_spec_some).
{ iPureIntro; split; eauto with lia.
rewrite map_length. apply lookup_lt_is_Some_1; eauto. }
iIntros (ithSome ( ith & -> & Hh)). simpl.
wp_apply unSOME_spec; eauto; iIntros (_).
wp_let.
assert (ith = #z) as ->.
{ pose proof nth_error_lookup _ _ _ Hh as Ha.
apply map_lookup_Some in Ha as (a & -> & Hia).
rewrite Hiz in Hia.
inversion Hia; subst a; done. }
rewrite Heqip.
wp_apply (aneris_wp_socketbind_static with "[$]"); [done|done|done|].
rewrite -Heqip.
iIntros "[Hskt _]"; wp_seq. wp_pures.
wp_apply aneris_wp_fork.
iSplitL; last first.
{ iNext.
rewrite Heqip.
wp_apply apply_spec_holds; last done.
rewrite Hiz.
repeat iSplit; done. }
iNext.
wp_pures.
set (s := RecordSet.set saddress (λ _ : option socket_address, Some z)
{| sfamily := PF_INET; stype := SOCK_DGRAM;
sprotocol := IPPROTO_UDP; saddress := None |}).
iApply fupd_aneris_wp.
iAssert (|={⊤}=> socket_inv γGsnap z h s)%I with "[Hskt]" as ">#Hsocketinv".
{ rewrite Heqip.
iApply inv_alloc. iNext. iExists _, _; iFrame.
rewrite big_sepS_empty; done. }
iModIntro.
wp_apply aneris_wp_fork.
iSplitL; last first.
{ iNext.
rewrite Heqip.
wp_apply send_thread_spec; last done.
iDestruct (big_sepL_lookup _ _ _ _ Hiz with "Hz") as "Hz'".
iFrame "#"; done. }
iNext.
wp_pures.
wp_apply aneris_wp_fork.
iSplitL; last first.
{ iNext.
rewrite Heqip.
wp_apply (recv_thread_spec _ _ _ _ i _ _ _ _ _ _ z); last done.
rewrite Hiz /=.
iDestruct (big_sepL_lookup _ _ _ _ Hiz with "Hz") as "Hz'".
iFrame "#"; done. }
iNext.
wp_pures.
rewrite Heqip.
wp_apply internal_write_spec_holds; first by iFrame "#".
iIntros (wr) "Hwr"; simpl.
wp_apply internal_read_spec_holds; first by iFrame "#".
iIntros (rd) "Hrd"; simpl.
wp_pures.
iApply "HΦ".
iFrame; done.
Qed.
End proof.