Library zoo.program_logic.state_interp

Require Import iris.base_logic.lib.invariants.

Require Import zoo.prelude.
Require Import zoo.iris.diaframe.
Require Import zoo.language.notations.
Require Export zoo.program_logic.ghost_state.
Require Import zoo.options.

Implicit Type cnt ns nt : nat.
Implicit Type pid : prophet_id.
Implicit Type tid : thread_id.
Implicit Type l : location.
Implicit Type v : val.
Implicit Type vs : list val.
Implicit Type hdr : header.
Implicit Type hdrs : gmap location header.
Implicit Type σ : state.
Implicit Type proph : val × val.
Implicit Type prophs : list (val × val).
Implicit Type prophets : gmap prophet_id (list (val × val)).
Implicit Type κ κs : list observation.

Record state۰wf σ v :=
  { state۰wflocals :
      σ.(state۰locals) = [v]
  ; state۰wfcounter :
      σ.(state۰heap) !! zoo_counter = Some 0%V
  }.

Section zoo۰G.
  Context `{zoo۰G : !ZooG Σ}.

  Definition state_interp ns nt σ κs : iProp Σ :=
    headers۰auth σ.(state۰headers)
    heap۰auth σ.(state۰heap)
    prophets۰auth κs σ.(state۰prophets)
    steps۰auth ns
    locals۰auth σ.(state۰locals)
    length σ.(state۰locals) = nt
    zoo_counter۰inv.

  Definition fork_post (_ : val) : iProp Σ :=
    True.
End zoo۰G.

#[local] Instance : CustomIpat "state_interp" :=
  " ( Hheaders_auth & Hheap_auth & Hprophets_auth & Hsteps_auth & Hlocals_auth & %Hlocals & Hcounter_inv ) ".

Section zoo۰G.
  Context `{zoo۰G : !ZooG Σ}.

  Lemma state_interpmono ns nt σ κs :
    state_interp ns nt σ κs |==>
    state_interp ˖ns nt σ κs.

  Lemma state_interpzoo_counter۰inv ns nt σ κs :
    state_interp ns nt σ κs
    zoo_counter۰inv.
End zoo۰G.

Section zoo۰G.
  Context `{zoo۰G : !ZooG Σ}.

  #[local] Lemma big_sepMchunk {A} (Φ : location A iProp Σ) l xs :
    ([∗ map] l x chunk l xs, Φ l x)
    [∗ list] i x xs, Φ (l +ₗ i) x.

  Lemma state_interpalloc {ns nt σ κs} l tag vs :
    σ.(state۰headers) !! l = None
    ( i,
      i < length vs
      σ.(state۰heap) !! (l +ₗ i) = None
    )
    state_interp ns nt σ κs |==>
      let hdr := Header tag (length vs) in
      state_interp ns nt (state۰alloc l hdr vs σ) κs
      l ↦ₕ hdr
      meta_token l
      l ↦∗ vs.

  Lemma state_interpheaders۰atvalid ns nt σ κs l hdr :
    state_interp ns nt σ κs -∗
    l ↦ₕ hdr -∗
    σ.(state۰headers) !! l = Some hdr.

  Lemma state_interppointstovalid ns nt σ κs l dq v :
    state_interp ns nt σ κs -∗
    l {dq} v -∗
    σ.(state۰heap) !! l = Some v.
  Lemma state_interppointstosvalid ns nt σ κs l dq vs :
    state_interp ns nt σ κs -∗
    l ↦∗{dq} vs -∗
     (i : nat) v,
      vs !! i = Some v
      σ.(state۰heap) !! (l +ₗ i) = Some v
    .
  Lemma state_interppointstoupdate {ns nt σ κs l w} v :
    state_interp ns nt σ κs -∗
    l w ==∗
      state_interp ns nt (state۰set_location l v σ) κs
      l v.

  Lemma state_interpsteps۰lbget ns nt σ κs :
    state_interp ns nt σ κs
     ns.
  Lemma state_interpsteps۰lbvalid ns1 nt σ κs ns2 :
    state_interp ns1 nt σ κs -∗
     ns2 -∗
    ns2 ns1.

  Lemma state_interplocal_pointstovalid ns nt σ κs tid dq v :
    state_interp ns nt σ κs -∗
    tid ↦ₗ{dq} v -∗
    σ.(state۰locals) !! tid = Some v.
  Lemma state_interpfork {ns nt σ κs} v :
    state_interp ns nt σ κs |==>
      state_interp ns (nt + 1) (state۰add_local v σ) κs
      nt ↦ₗ v.
  Lemma state_interplocal_pointstoupdate {ns nt σ κs tid w} v :
    state_interp ns nt σ κs -∗
    tid ↦ₗ w ==∗
      state_interp ns nt (state۰set_local tid v σ) κs
      tid ↦ₗ v.

  Lemma state_interpprophetnew {ns nt σ κs} pid :
    pid σ.(state۰prophets)
    state_interp ns nt σ κs |==>
       prophs,
      state_interp ns nt (state۰add_prophet pid σ) κs
      prophet۰model pid prophs.
  Lemma state_interpprophetresolve ns nt σ κs pid proph prophs :
    state_interp ns nt σ ((pid, proph) :: κs) -∗
    prophet۰model pid prophs ==∗
       prophs',
      prophs = proph :: prophs'
      state_interp ns nt σ κs
      prophet۰model pid prophs'.
End zoo۰G.

Definition state۰heap۰initial σ :=
  delete zoo_counter σ.(state۰heap).

Lemma state_interpinit `{zoo۰Gpre : !ZooGpre Σ} `{inv۰G : !invGS Σ} σ v κs :
  state۰wf σ v
   |={}=>
     zoo۰G : ZooG Σ,
    zoo۰G.(zoo۰G۰inv۰G) = inv۰G
    state_interp 0 1 σ κs
    ([∗ map] l v state۰heap۰initial σ, l v)
    0 ↦ₗ v.

#[global] Opaque state_interp.