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.