Library zoo_std.xdlchain
Require Import zoo.prelude.
Require Import zoo.common.list.
Require Import zoo.base.
Require Export zoo_std.xdlchain__code.
Require Import zoo_std.xdlchain__types.
Require Import zoo.options.
Implicit Type node : location.
Implicit Type nodes : list location.
Implicit Type v next prev src dst : val.
Section zoo۰G.
Context `{zoo۰G : !ZooG Σ}.
Fixpoint xdlchain src nodes dst : iProp Σ :=
match nodes with
| [] ⇒
True
| node :: nodes ⇒
node.[prev] ↦ src ∗
match nodes with
| [] ⇒
node.[next] ↦ dst
| node' :: _ ⇒
node.[next] ↦ #node' ∗
xdlchain #node nodes dst
end
end.
#[global] Arguments xdlchain _ !_ _ / : assert.
#[global] Instance xdlchainーtimeless src nodes dst :
Timeless (xdlchain src nodes dst).
Lemma xdlchainーnil src dst :
⊢ xdlchain src [] dst.
Lemma xdlchainーsingleton src node dst :
xdlchain src [node] dst ⊣⊢
node.[prev] ↦ src ∗
node.[next] ↦ dst.
Lemma xdlchainーsingleton₁ src node dst :
xdlchain src [node] dst ⊢
node.[prev] ↦ src ∗
node.[next] ↦ dst.
Lemma xdlchainーsingleton₂ src node dst :
node.[prev] ↦ src -∗
node.[next] ↦ dst -∗
xdlchain src [node] dst.
#[local] Lemma xdlchainーconsーunfold {src} node nodes dst :
xdlchain src (node :: nodes) dst ⊣⊢
node.[prev] ↦ src ∗
match nodes with
| [] ⇒
node.[next] ↦ dst
| node' :: _ ⇒
node.[next] ↦ #node' ∗
xdlchain #node nodes dst
end.
Lemma xdlchainーcons {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊣⊢
node.[prev] ↦ src ∗
node.[next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchainーcons₁ {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊢
node.[prev] ↦ src ∗
node.[next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchainーcons₂ src node nodes dst :
node.[prev] ↦ src -∗
node.[next] ↦ from_option #@{location} dst (head nodes) -∗
xdlchain #node nodes dst -∗
xdlchain src (node :: nodes) dst.
Lemma xdlchainーapp {src} nodes nodes1 nodes2 dst :
nodes = nodes1 ++ nodes2 →
xdlchain src nodes dst ⊣⊢
xdlchain src nodes1 (from_option #@{location} dst (head nodes2)) ∗
xdlchain (from_option #@{location} src (last nodes1)) nodes2 dst.
Lemma xdlchainーapp₁ {src} nodes nodes1 nodes2 dst :
nodes = nodes1 ++ nodes2 →
xdlchain src nodes dst ⊢
xdlchain src nodes1 (from_option #@{location} dst (head nodes2)) ∗
xdlchain (from_option #@{location} src (last nodes1)) nodes2 dst.
Lemma xdlchainーapp₂ src nodes1 nodes2 dst :
xdlchain src nodes1 (from_option #@{location} dst (head nodes2)) -∗
xdlchain (from_option #@{location} src (last nodes1)) nodes2 dst -∗
xdlchain src (nodes1 ++ nodes2) dst.
Lemma xdlchainーsnoc {src} nodes nodes' node dst :
nodes = nodes' ++ [node] →
xdlchain src nodes dst ⊣⊢
xdlchain src nodes' #node ∗
node.[prev] ↦ from_option #@{location} src (last nodes') ∗
node.[next] ↦ dst.
Lemma xdlchainーsnoc₁ {src} nodes nodes' node dst :
nodes = nodes' ++ [node] →
xdlchain src nodes dst ⊢
xdlchain src nodes' #node ∗
node.[prev] ↦ from_option #@{location} src (last nodes') ∗
node.[next] ↦ dst.
Lemma xdlchainーsnoc₂ src nodes node dst :
xdlchain src nodes #node -∗
node.[prev] ↦ from_option #@{location} src (last nodes) -∗
node.[next] ↦ dst -∗
xdlchain src (nodes ++ [node]) dst.
Lemma xdlchainーlast {src nodes} node dst :
last nodes = Some node →
xdlchain src nodes dst ⊢
∃ nodes',
⌜nodes = nodes' ++ [node]⌝ ∗
xdlchain src nodes' #node ∗
node.[prev] ↦ from_option #@{location} src (last nodes') ∗
node.[next] ↦ dst.
Lemma xdlchainーlookup {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊣⊢
xdlchain src (take i nodes) #node ∗
node.[prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) ∗
xdlchain #node (drop ˖i nodes) dst.
Lemma xdlchainーlookup₁ {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊢
xdlchain src (take i nodes) #node ∗
node.[prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) ∗
xdlchain #node (drop ˖i nodes) dst.
Lemma xdlchainーlookup₂ {src nodes} i node prev next dst :
nodes !! i = Some node →
prev = from_option #@{location} src (last $ take i nodes) →
next = from_option #@{location} dst (head $ drop ˖i nodes) →
xdlchain src (take i nodes) #node -∗
node.[prev] ↦ prev -∗
node.[next] ↦ next -∗
xdlchain #node (drop ˖i nodes) dst -∗
xdlchain src nodes dst.
Lemma xdlchainーlookupーacc {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊢
node.[prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) ∗
( node.[prev] ↦ from_option #@{location} src (last $ take i nodes) -∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) -∗
xdlchain src nodes dst
).
Lemma xdlchainーexclusive src1 src2 nodes dst1 dst2 :
0 < length nodes →
xdlchain src1 nodes dst1 -∗
xdlchain src2 nodes dst2 -∗
False.
Lemma xdlchainーNoDup src nodes dst :
xdlchain src nodes dst ⊢
⌜NoDup nodes⌝.
Lemma xdlchain٠prevーspec {src nodes node} nodes' dst E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
(#node).{prev} @ E
{{{
RET src;
xdlchain src nodes dst
}}}.
Lemma xdlchain٠prevーspecーlookup {src nodes} i node dst E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{prev} @ E
{{{
RET from_option #@{location} src (last $ take i nodes);
xdlchain src nodes dst
}}}.
Lemma xdlchain٠prevーspecーhead {src nodes} node dst E :
head nodes = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{prev} @ E
{{{
RET src;
xdlchain src nodes dst
}}}.
Lemma xdlchain٠nextーspec {src nodes node} nodes' dst E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
(#node).{next} @ E
{{{
RET from_option #@{location} dst (head nodes');
xdlchain src nodes dst
}}}.
Lemma xdlchain٠nextーspecーlookup {src nodes} i node dst E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{next} @ E
{{{
RET from_option #@{location} dst (head $ drop ˖i nodes);
xdlchain src nodes dst
}}}.
Lemma xdlchain٠nextーspecーlast {src nodes} node dst E :
last nodes = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{next} @ E
{{{
RET dst;
xdlchain src nodes dst
}}}.
Lemma xdlchain٠set_prevーspec {src nodes node} nodes' dst v E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
#node <-{prev} v @ E
{{{
RET ();
xdlchain v nodes dst
}}}.
Lemma xdlchain٠set_prevーspecーlookup {src nodes} i node dst v E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{prev} v @ E
{{{
RET ();
xdlchain src (take i nodes) #node ∗
xdlchain v (drop i nodes) dst
}}}.
Lemma xdlchain٠set_prevーspecーhead {src nodes} node dst v E :
head nodes = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{prev} v @ E
{{{
RET ();
xdlchain v nodes dst
}}}.
Lemma xdlchain٠set_nextーspec {src nodes node} nodes' dst v E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
#node <-{next} v @ E
{{{
RET ();
xdlchain src [node] v ∗
xdlchain #node nodes' dst
}}}.
Lemma xdlchain٠set_nextーspecーlookup {src nodes} i node dst v E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{next} v @ E
{{{
RET ();
xdlchain src (take ˖i nodes) v ∗
xdlchain #node (drop ˖i nodes) dst
}}}.
Lemma xdlchain٠set_nextーspecーlast {src nodes} node dst v E :
last nodes = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{next} v @ E
{{{
RET ();
xdlchain src nodes v
}}}.
End zoo۰G.
Require zoo_std.xdlchain__opaque.
#[global] Opaque xdlchain.
Require Import zoo.common.list.
Require Import zoo.base.
Require Export zoo_std.xdlchain__code.
Require Import zoo_std.xdlchain__types.
Require Import zoo.options.
Implicit Type node : location.
Implicit Type nodes : list location.
Implicit Type v next prev src dst : val.
Section zoo۰G.
Context `{zoo۰G : !ZooG Σ}.
Fixpoint xdlchain src nodes dst : iProp Σ :=
match nodes with
| [] ⇒
True
| node :: nodes ⇒
node.[prev] ↦ src ∗
match nodes with
| [] ⇒
node.[next] ↦ dst
| node' :: _ ⇒
node.[next] ↦ #node' ∗
xdlchain #node nodes dst
end
end.
#[global] Arguments xdlchain _ !_ _ / : assert.
#[global] Instance xdlchainーtimeless src nodes dst :
Timeless (xdlchain src nodes dst).
Lemma xdlchainーnil src dst :
⊢ xdlchain src [] dst.
Lemma xdlchainーsingleton src node dst :
xdlchain src [node] dst ⊣⊢
node.[prev] ↦ src ∗
node.[next] ↦ dst.
Lemma xdlchainーsingleton₁ src node dst :
xdlchain src [node] dst ⊢
node.[prev] ↦ src ∗
node.[next] ↦ dst.
Lemma xdlchainーsingleton₂ src node dst :
node.[prev] ↦ src -∗
node.[next] ↦ dst -∗
xdlchain src [node] dst.
#[local] Lemma xdlchainーconsーunfold {src} node nodes dst :
xdlchain src (node :: nodes) dst ⊣⊢
node.[prev] ↦ src ∗
match nodes with
| [] ⇒
node.[next] ↦ dst
| node' :: _ ⇒
node.[next] ↦ #node' ∗
xdlchain #node nodes dst
end.
Lemma xdlchainーcons {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊣⊢
node.[prev] ↦ src ∗
node.[next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchainーcons₁ {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊢
node.[prev] ↦ src ∗
node.[next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchainーcons₂ src node nodes dst :
node.[prev] ↦ src -∗
node.[next] ↦ from_option #@{location} dst (head nodes) -∗
xdlchain #node nodes dst -∗
xdlchain src (node :: nodes) dst.
Lemma xdlchainーapp {src} nodes nodes1 nodes2 dst :
nodes = nodes1 ++ nodes2 →
xdlchain src nodes dst ⊣⊢
xdlchain src nodes1 (from_option #@{location} dst (head nodes2)) ∗
xdlchain (from_option #@{location} src (last nodes1)) nodes2 dst.
Lemma xdlchainーapp₁ {src} nodes nodes1 nodes2 dst :
nodes = nodes1 ++ nodes2 →
xdlchain src nodes dst ⊢
xdlchain src nodes1 (from_option #@{location} dst (head nodes2)) ∗
xdlchain (from_option #@{location} src (last nodes1)) nodes2 dst.
Lemma xdlchainーapp₂ src nodes1 nodes2 dst :
xdlchain src nodes1 (from_option #@{location} dst (head nodes2)) -∗
xdlchain (from_option #@{location} src (last nodes1)) nodes2 dst -∗
xdlchain src (nodes1 ++ nodes2) dst.
Lemma xdlchainーsnoc {src} nodes nodes' node dst :
nodes = nodes' ++ [node] →
xdlchain src nodes dst ⊣⊢
xdlchain src nodes' #node ∗
node.[prev] ↦ from_option #@{location} src (last nodes') ∗
node.[next] ↦ dst.
Lemma xdlchainーsnoc₁ {src} nodes nodes' node dst :
nodes = nodes' ++ [node] →
xdlchain src nodes dst ⊢
xdlchain src nodes' #node ∗
node.[prev] ↦ from_option #@{location} src (last nodes') ∗
node.[next] ↦ dst.
Lemma xdlchainーsnoc₂ src nodes node dst :
xdlchain src nodes #node -∗
node.[prev] ↦ from_option #@{location} src (last nodes) -∗
node.[next] ↦ dst -∗
xdlchain src (nodes ++ [node]) dst.
Lemma xdlchainーlast {src nodes} node dst :
last nodes = Some node →
xdlchain src nodes dst ⊢
∃ nodes',
⌜nodes = nodes' ++ [node]⌝ ∗
xdlchain src nodes' #node ∗
node.[prev] ↦ from_option #@{location} src (last nodes') ∗
node.[next] ↦ dst.
Lemma xdlchainーlookup {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊣⊢
xdlchain src (take i nodes) #node ∗
node.[prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) ∗
xdlchain #node (drop ˖i nodes) dst.
Lemma xdlchainーlookup₁ {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊢
xdlchain src (take i nodes) #node ∗
node.[prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) ∗
xdlchain #node (drop ˖i nodes) dst.
Lemma xdlchainーlookup₂ {src nodes} i node prev next dst :
nodes !! i = Some node →
prev = from_option #@{location} src (last $ take i nodes) →
next = from_option #@{location} dst (head $ drop ˖i nodes) →
xdlchain src (take i nodes) #node -∗
node.[prev] ↦ prev -∗
node.[next] ↦ next -∗
xdlchain #node (drop ˖i nodes) dst -∗
xdlchain src nodes dst.
Lemma xdlchainーlookupーacc {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊢
node.[prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) ∗
( node.[prev] ↦ from_option #@{location} src (last $ take i nodes) -∗
node.[next] ↦ from_option #@{location} dst (head $ drop ˖i nodes) -∗
xdlchain src nodes dst
).
Lemma xdlchainーexclusive src1 src2 nodes dst1 dst2 :
0 < length nodes →
xdlchain src1 nodes dst1 -∗
xdlchain src2 nodes dst2 -∗
False.
Lemma xdlchainーNoDup src nodes dst :
xdlchain src nodes dst ⊢
⌜NoDup nodes⌝.
Lemma xdlchain٠prevーspec {src nodes node} nodes' dst E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
(#node).{prev} @ E
{{{
RET src;
xdlchain src nodes dst
}}}.
Lemma xdlchain٠prevーspecーlookup {src nodes} i node dst E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{prev} @ E
{{{
RET from_option #@{location} src (last $ take i nodes);
xdlchain src nodes dst
}}}.
Lemma xdlchain٠prevーspecーhead {src nodes} node dst E :
head nodes = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{prev} @ E
{{{
RET src;
xdlchain src nodes dst
}}}.
Lemma xdlchain٠nextーspec {src nodes node} nodes' dst E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
(#node).{next} @ E
{{{
RET from_option #@{location} dst (head nodes');
xdlchain src nodes dst
}}}.
Lemma xdlchain٠nextーspecーlookup {src nodes} i node dst E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{next} @ E
{{{
RET from_option #@{location} dst (head $ drop ˖i nodes);
xdlchain src nodes dst
}}}.
Lemma xdlchain٠nextーspecーlast {src nodes} node dst E :
last nodes = Some node →
{{{
xdlchain src nodes dst
}}}
(#node).{next} @ E
{{{
RET dst;
xdlchain src nodes dst
}}}.
Lemma xdlchain٠set_prevーspec {src nodes node} nodes' dst v E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
#node <-{prev} v @ E
{{{
RET ();
xdlchain v nodes dst
}}}.
Lemma xdlchain٠set_prevーspecーlookup {src nodes} i node dst v E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{prev} v @ E
{{{
RET ();
xdlchain src (take i nodes) #node ∗
xdlchain v (drop i nodes) dst
}}}.
Lemma xdlchain٠set_prevーspecーhead {src nodes} node dst v E :
head nodes = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{prev} v @ E
{{{
RET ();
xdlchain v nodes dst
}}}.
Lemma xdlchain٠set_nextーspec {src nodes node} nodes' dst v E :
nodes = node :: nodes' →
{{{
xdlchain src nodes dst
}}}
#node <-{next} v @ E
{{{
RET ();
xdlchain src [node] v ∗
xdlchain #node nodes' dst
}}}.
Lemma xdlchain٠set_nextーspecーlookup {src nodes} i node dst v E :
nodes !! i = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{next} v @ E
{{{
RET ();
xdlchain src (take ˖i nodes) v ∗
xdlchain #node (drop ˖i nodes) dst
}}}.
Lemma xdlchain٠set_nextーspecーlast {src nodes} node dst v E :
last nodes = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{next} v @ E
{{{
RET ();
xdlchain src nodes v
}}}.
End zoo۰G.
Require zoo_std.xdlchain__opaque.
#[global] Opaque xdlchain.