Library zoo_boxroot.boxroot

Require Import iris.base_logic.lib.ghost_map.

Require Import zoo.prelude.
Require Import zoo.common.list.
Require Import zoo.common.fin_maps.
Require Import zoo.iris.bi.big_op.
Require Import zoo.base.
Require Import zoo_std.xdeque.
Require Export zoo_boxroot.gc.
Require Import zoo.options.

Section list_to_set.
  Lemma list_to_setdelete `{Countable A} {l i} x :
    NoDup l
    l !! i = Some x
    list_to_set (C := gset A) (delete i l) list_to_set l {[x]}.
End list_to_set.

Section list_to_map.
  Lemma list_to_mapziplist_to_set `{Countable K} `{!Inhabited A} (m : gmap K A) (l : list K) :
    NoDup l
    dom m list_to_set l
    list_to_map (zip l ((λ x, m !!! x) <$> l)) = m.
End list_to_map.

Implicit Type l l_global root : location.
Implicit Type roots : list location.
Implicit Type v t global : val.
Implicit Type ω : gc۰location.
Implicit Type map : gmap location gc۰location.

Definition boxroot٠init : val :=
  𝗳𝘂𝗻
    𝗹𝗲𝘁 "global" = xdeque٠create () 𝗶𝗻
    gc٠set_roots (𝗳𝘂𝗻 "fn" xdeque٠iter "fn" "global") #2%nat
    "global".

Definition boxroot٠create : val :=
  𝗳𝘂𝗻 "global" "v"
    𝗹𝗲𝘁 "t" = { (), (), "v" } 𝗶𝗻
    xdeque٠push_back "global" "t"
    "t".

Definition boxroot٠remove : val :=
  𝗳𝘂𝗻 "global" "t"
    xdeque٠remove "t".

Definition boxroot٠get : val :=
  𝗳𝘂𝗻 "t"
    "t".{xdeque٠data}.

Definition boxroot٠set : val :=
  𝗳𝘂𝗻 "t" "v"
    "t" <-{xdeque٠data} "v".

Class BoxrootG Σ `{zoo۰G : !ZooG Σ} :=
  { #[local] boxroot۰G۰roots۰G :: ghost_mapG Σ location gc۰location
  }.

Definition boxroot۰Σ :=
  #[ghost_mapΣ location gc۰location
  ].
#[global] Instance subGboxroot۰Σ Σ `{zoo۰G : !ZooG Σ} :
  subG boxroot۰Σ Σ
  BoxrootG Σ.

Section boxroot۰G.
  Context `{boxroot۰G : BoxrootG Σ}.

  #[local] Definition metadata :=
    gname.
  Implicit Type γ : metadata.

  #[local] Definition roots۰auth γ map :=
    ghost_map_auth γ 1 map.
  #[local] Definition roots۰elem γ root ω :=
    ghost_map_elem γ root (DfracOwn 1) ω.

  Definition boxroot۰global global gc : iProp Σ :=
     l_global γ roots map,
    global = #l_global
    l_global γ
    dom map list_to_set roots
    roots۰auth γ map
    xdeque۰model global roots
    [∗ map] root ω map,
      root.[xdeque٠data] root[gc] ω.

  Definition boxroot۰model t global ω : iProp Σ :=
     root l_global γ,
    t = #root
    global = #l_global
    l_global γ
    roots۰elem γ root ω.

  #[local] Lemma rootsalloc :
     |==>
       γ,
      roots۰auth γ .
  #[local] Lemma rootslookup γ map root ω :
    roots۰auth γ map -∗
    roots۰elem γ root ω -∗
    map !! root = Some ω.
  #[local] Lemma rootsinsert {γ map} root ω :
    map !! root = None
    roots۰auth γ map |==>
      roots۰auth γ (<[root := ω]> map)
      roots۰elem γ root ω.
  #[local] Lemma rootsdelete γ map root ω :
    roots۰auth γ map -∗
    roots۰elem γ root ω ==∗
      roots۰auth γ (delete root map).
  #[local] Lemma rootsupdate {γ map root ω} ω' :
    roots۰auth γ map -∗
    roots۰elem γ root ω ==∗
      roots۰auth γ (<[root := ω']> map)
      roots۰elem γ root ω'.

  Lemma boxroot٠initspec gc Χ :
    {{{
      gc۰model gc
      gc۰roots Χ
    }}}
      boxroot٠init ()
    {{{
      global
    , RET global;
      gc۰model gc
      gc۰roots (boxroot۰global global)
      boxroot۰global global gc
    }}}.

  Lemma boxroot٠createspec {gc global l} ω :
    ω gc[gc] l
    {{{
      boxroot۰global global gc
    }}}
      boxroot٠create global #l
    {{{
      t
    , RET t;
      boxroot۰global global gc
      boxroot۰model t global ω
    }}}.

  Lemma boxroot٠removespec gc global t ω :
    {{{
      boxroot۰global global gc
      boxroot۰model t global ω
    }}}
      boxroot٠remove global t
    {{{
      RET ();
      boxroot۰global global gc
    }}}.

  Lemma boxroot٠getspec gc global t ω :
    {{{
      boxroot۰global global gc
      boxroot۰model t global ω
    }}}
      boxroot٠get t
    {{{
      l
    , RET #l;
      ω gc[gc] l
      boxroot۰global global gc
      boxroot۰model t global ω
    }}}.

  Lemma boxroot٠setspec {gc global t ω'} ω l :
    ω gc[gc] l
    {{{
      boxroot۰global global gc
      boxroot۰model t global ω'
    }}}
      boxroot٠set t #l
    {{{
      RET ();
      boxroot۰global global gc
      boxroot۰model t global ω
    }}}.
End boxroot۰G.

#[global] Opaque boxroot٠create.
#[global] Opaque boxroot٠remove.
#[global] Opaque boxroot٠get.
#[global] Opaque boxroot٠set.

#[global] Opaque boxroot۰global.
#[global] Opaque boxroot۰model.