Library zoo_std.xdeque

Require Import zoo.prelude.
Require Import zoo.common.option.
Require Import zoo.common.list.
Require Import zoo.base.
Require Import zoo_std.option.
Require Import zoo_std.xdlchain.
Require Export zoo_std.xdeque__code.
Require Import zoo_std.xdeque__types.
Require Import zoo.options.

Implicit Type l node : location.
Implicit Type nodes : list location.
Implicit Type fn : val.

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

  Definition xdeque۰model t nodes : iProp Σ :=
     l,
    t = #l
    l.[prev] from_option #@{location} t (last nodes)
    l.[next] from_option #@{location} t (head nodes)
    xdlchain t nodes t.

  #[global] Instance xdeque۰modeltimeless t nodes :
    Timeless (xdeque۰model t nodes).

  Lemma xdeque۰modelexclusive t nodes1 nodes2 :
    xdeque۰model t nodes1 -∗
    xdeque۰model t nodes2 -∗
    False.

  Lemma xdeque۰modelNoDup t nodes :
    xdeque۰model t nodes
    NoDup nodes.

  Lemma xdeque٠createspec :
    {{{
      True
    }}}
      xdeque٠create ()
    {{{
      t
    , RET t;
      ( l, t = #l meta_token l )
      xdeque۰model t []
    }}}.

  Lemma xdeque٠is_emptyspec t nodes :
    {{{
      xdeque۰model t nodes
    }}}
      xdeque٠is_empty t
    {{{
      RET #(bool_decide (nodes = []%list));
      xdeque۰model t nodes
    }}}.

  #[local] Lemma xdeque٠linkspec node1 v1 node2 v2 :
    {{{
      node1.[next] v1
      node2.[prev] v2
    }}}
      xdeque٠link #node1 #node2
    {{{
      RET ();
      node1.[next] #node2
      node2.[prev] #node1
    }}}.

  Lemma xdeque٠push_frontspec t nodes node prev next :
    {{{
      xdeque۰model t nodes
      node.[prev] prev
      node.[next] next
    }}}
      xdeque٠push_front t #node
    {{{
      RET ();
      xdeque۰model t (node :: nodes)
    }}}.

  Lemma xdeque٠push_backspec t nodes node prev next :
    {{{
      xdeque۰model t nodes
      node.[prev] prev
      node.[next] next
    }}}
      xdeque٠push_back t #node
    {{{
      RET ();
      xdeque۰model t (nodes ++ [node])
    }}}.

  Lemma xdeque٠pop_frontspec t nodes :
    {{{
      xdeque۰model t nodes
    }}}
      xdeque٠pop_front t
    {{{
      RET #*@{location} $ head nodes : option val;
      xdeque۰model t (tail nodes)
    }}}.

  Lemma xdeque٠pop_backspec t nodes :
    {{{
      xdeque۰model t nodes
    }}}
      xdeque٠pop_back t
    {{{
      o
    , RET #*@{location} o : option val;
      match o with
      | None
          nodes = []
          xdeque۰model t []
      | Some node
           nodes',
          nodes = nodes' ++ [node]
          xdeque۰model t nodes'
      end
    }}}.

  Lemma xdeque٠removespec {t nodes} i node :
    nodes !! i = Some node
    {{{
      xdeque۰model t nodes
    }}}
      xdeque٠remove #node
    {{{
      RET ();
      xdeque۰model t (delete i nodes)
    }}}.

  #[local] Lemma xdeque٠iter_auxspec Ψ i fn l nodes node :
    (nodes ++ [l]) !! i = Some node
    {{{
       Ψ (take i nodes)
      xdeque۰model #l nodes
       (
         nodes_done node nodes_todo,
        nodes = nodes_done ++ node :: nodes_todo -∗
        Ψ nodes_done -∗
        WP fn #node {{ res,
          res = ()%V
           Ψ (nodes_done ++ [#node])
        }}
      )
    }}}
      xdeque٠iter_aux fn #l #node
    {{{
      RET ();
      xdeque۰model #l nodes
      Ψ nodes
    }}}.
  Lemma xdeque٠iterspec Ψ fn t nodes :
    {{{
       Ψ []
      xdeque۰model t nodes
       (
         nodes_done node nodes_todo,
        nodes = nodes_done ++ node :: nodes_todo -∗
        Ψ nodes_done -∗
        WP fn #node {{ res,
          res = ()%V
           Ψ (nodes_done ++ [#node])
        }}
      )
    }}}
      xdeque٠iter fn t
    {{{
      RET ();
      xdeque۰model t nodes
      Ψ nodes
    }}}.
End zoo۰G.

Require zoo_std.xdeque__opaque.

#[global] Opaque xdeque۰model.