Library zoo_std.chain

Require Import zoo.prelude.
Require Import zoo.base.
Require Export zoo_std.chain__code.
Require Import zoo_std.chain__types.
Require Import zoo.options.

Implicit Type l : location.
Implicit Type v w t dst : val.

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

  Fixpoint chain۰model tag t vs dst : iProp Σ :=
    match vs with
    | []
        t = dst
    | v :: vs
         l t',
        t = #l
        from_option (λ tag, l ↦ₕ Header tag 2) True tag
        l.[next] t'
        l.[data] v
        chain۰model tag t' vs dst
    end.
  #[global] Arguments chain۰model _ _ !_ _ / : assert.
  #[local] Instance : CustomIpat "model" :=
    " ( %l{} & %t{}' & {%Heq{eq};->} & Hl{}_header & Hl{}_next & Hl{}_data & Hmodel{}' ) ".

  #[global] Instance chain۰modeltimeless tag t vs dst :
    Timeless (chain۰model tag t vs dst).

  Lemma chainphysicallydistinct tag1 t1 vs1 dst1 tag2 t2 vs2 dst2 :
    0 < length vs1
    0 < length vs2
    t1 t2
    chain۰model tag1 t1 vs1 dst1 -∗
    chain۰model tag2 t2 vs2 dst2 -∗
    t1 t2.
  Lemma chainphysicallydistinct' tag t vs dst :
    0 < length vs
    t t
    chain۰model tag t vs dst
    False.
  Lemma wpequalchain tag1 t1 vs1 dst1 tag2 t2 vs2 dst2 Φ :
    0 < length vs1
    0 < length vs2
    chain۰model tag1 t1 vs1 dst1 -∗
    chain۰model tag2 t2 vs2 dst2 -∗
    ( chain۰model tag1 t1 vs1 dst1 -∗
      chain۰model tag2 t2 vs2 dst2 -∗
        (t1 t2 -∗ Φ false%V)
        (t1 = t2 -∗ Φ true%V)
    ) -∗
    WP t1 == t2 {{ Φ }}.

  Lemma chain۰modeltag tag t vs dst :
    length vs 0
    chain۰model (Some tag) t vs dst
       l,
      t = #l
      l ↦ₕ Header tag 2.

  Lemma chain۰modelnil tag t dst :
    t = dst ⊣⊢
    chain۰model tag t [] dst.
  Lemma chain۰modelnil₁ tag v :
     chain۰model tag v [] v.
  Lemma chain۰modelnil₂ tag t dst :
    chain۰model tag t [] dst
    t = dst.

  Lemma chain۰modelapp₁ vs1 vs2 tag t vs dst :
    vs = vs1 ++ vs2
    chain۰model tag t vs dst
       t',
      chain۰model tag t vs1 t'
      chain۰model tag t' vs2 dst.
  Lemma chain۰modelapp₂ tag t1 vs1 t2 vs2 dst :
    chain۰model tag t1 vs1 t2 -∗
    chain۰model tag t2 vs2 dst -∗
    chain۰model tag t1 (vs1 ++ vs2) dst.
  Lemma chain۰modelapp tag t vs vs1 vs2 dst :
    vs = vs1 ++ vs2
    chain۰model tag t vs dst ⊣⊢
       t',
      chain۰model tag t vs1 t'
      chain۰model tag t' vs2 dst.

  Lemma chain۰modelsnoc tag t vs vs' v dst :
    vs = vs' ++ [v]
    chain۰model tag t vs dst ⊣⊢
       t',
      chain۰model tag t vs' t'
      chain۰model tag t' [v] dst.
  Lemma chain۰modelsnoc₁ tag t vs vs' v dst :
    vs = vs' ++ [v]
    chain۰model tag t (vs ++ [v]) dst
       t',
      chain۰model tag t vs t'
      chain۰model tag t' [v] dst.
  Lemma chain۰modelsnoc₂ tag t1 vs t2 v dst :
    chain۰model tag t1 vs t2 -∗
    chain۰model tag t2 [v] dst -∗
    chain۰model tag t1 (vs ++ [v]) dst.

  Lemma chain۰modelexclusive t tag1 vs1 dst1 tag2 vs2 dst2 :
    0 < length vs1
    0 < length vs2
    chain۰model tag1 t vs1 dst1 -∗
    chain۰model tag2 t vs2 dst2 -∗
    False.

  Lemma chain٠blockspec tag t vs dst v :
    {{{
      chain۰model tag t vs dst
    }}}
      Block Mutable (default 0%nat tag) [Val t; Val v]
    {{{
      t'
    , RET t';
      chain۰model tag t' (v :: vs) dst
    }}}.

  Lemma chain٠dataspec tag t v vs dst :
    {{{
      chain۰model tag t (v :: vs) dst
    }}}
      t.{data}
    {{{
      RET v;
      chain۰model tag t (v :: vs) dst
    }}}.

  Lemma chain٠nextspec tag t v vs dst :
    {{{
      chain۰model tag t (v :: vs) dst
    }}}
      t.{next}
    {{{
      t'
    , RET t';
      chain۰model tag t [v] t'
      chain۰model tag t' vs dst
    }}}.
  Lemma chain٠nextspecsingleton tag t v dst :
    {{{
      chain۰model tag t [v] dst
    }}}
      t.{next}
    {{{
      RET dst;
      chain۰model tag t [v] dst
    }}}.

  Lemma chain٠set_dataspec tag t v vs dst w :
    {{{
      chain۰model tag t (v :: vs) dst
    }}}
      t <-{data} w
    {{{
      RET ();
      chain۰model tag t (w :: vs) dst
    }}}.

  Lemma chain٠set_nextspec tag t v vs dst v' :
    {{{
      chain۰model tag t (v :: vs) dst
    }}}
      t <-{next} v'
    {{{
      t'
    , RET ();
      chain۰model tag t [v] v'
      chain۰model tag t' vs dst
    }}}.
  Lemma chain٠set_nextspecsingleton tag t v dst dst' :
    {{{
      chain۰model tag t [v] dst
    }}}
      t <-{next} dst'
    {{{
      RET ();
      chain۰model tag t [v] dst'
    }}}.
End zoo۰G.

#[global] Opaque chain۰model.