Library zoo_std.xdlchain
From zoo Require Import
prelude.
From zoo.common Require Import
list.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Export
base
xdlchain__types.
From zoo Require Import
options.
Implicit Types node : location.
Implicit Types nodes : list location.
Implicit Types 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.[xdlchain_prev] ↦ src ∗
match nodes with
| [] ⇒
node.[xdlchain_next] ↦ dst
| node' :: _ ⇒
node.[xdlchain_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.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_singleton_1 src node dst :
xdlchain src [node] dst ⊢
node.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_singleton_2 src node dst :
node.[xdlchain_prev] ↦ src -∗
node.[xdlchain_next] ↦ dst -∗
xdlchain src [node] dst.
#[local] Lemma xdlchain_cons_unfold {src} node nodes dst :
xdlchain src (node :: nodes) dst ⊣⊢
node.[xdlchain_prev] ↦ src ∗
match nodes with
| [] ⇒
node.[xdlchain_next] ↦ dst
| node' :: _ ⇒
node.[xdlchain_next] ↦ #node' ∗
xdlchain #node nodes dst
end.
Lemma xdlchain_cons {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊣⊢
node.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchain_cons_1 {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊢
node.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchain_cons_2 src node nodes dst :
node.[xdlchain_prev] ↦ src -∗
node.[xdlchain_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_1 {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_2 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.[xdlchain_prev] ↦ from_option #@{location} src (last nodes') ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_snoc_1 {src} nodes nodes' node dst :
nodes = nodes' ++ [node] →
xdlchain src nodes dst ⊢
xdlchain src nodes' #node ∗
node.[xdlchain_prev] ↦ from_option #@{location} src (last nodes') ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_snoc_2 src nodes node dst :
xdlchain src nodes #node -∗
node.[xdlchain_prev] ↦ from_option #@{location} src (last nodes) -∗
node.[xdlchain_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.[xdlchain_prev] ↦ from_option #@{location} src (last nodes') ∗
node.[xdlchain_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.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S i) nodes) ∗
xdlchain #node (drop (S i) nodes) dst.
Lemma xdlchain_lookup_1 {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊢
xdlchain src (take i nodes) #node ∗
node.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S i) nodes) ∗
xdlchain #node (drop (S i) nodes) dst.
Lemma xdlchain_lookup_2 {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 (S i) nodes) →
xdlchain src (take i nodes) #node -∗
node.[xdlchain_prev] ↦ prev -∗
node.[xdlchain_next] ↦ next -∗
xdlchain #node (drop (S 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.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S i) nodes) ∗
( node.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) -∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S 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).{xdlchain_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).{xdlchain_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).{xdlchain_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).{xdlchain_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).{xdlchain_next} @ E
{{{
RET from_option #@{location} dst (head $ drop (S 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).{xdlchain_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 <-{xdlchain_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 <-{xdlchain_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 <-{xdlchain_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 <-{xdlchain_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 <-{xdlchain_next} v @ E
{{{
RET ();
xdlchain src (take (S i) nodes) v ∗
xdlchain #node (drop (S i) nodes) dst
}}}.
Lemma xdlchain٠set_next𑁒spec_last {src nodes} node dst v E :
last nodes = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{xdlchain_next} v @ E
{{{
RET ();
xdlchain src nodes v
}}}.
End zoo_G.
From zoo_std Require
xdlchain__opaque.
#[global] Opaque xdlchain.
prelude.
From zoo.common Require Import
list.
From zoo.language Require Import
notations.
From zoo.diaframe Require Import
diaframe.
From zoo_std Require Export
base
xdlchain__types.
From zoo Require Import
options.
Implicit Types node : location.
Implicit Types nodes : list location.
Implicit Types 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.[xdlchain_prev] ↦ src ∗
match nodes with
| [] ⇒
node.[xdlchain_next] ↦ dst
| node' :: _ ⇒
node.[xdlchain_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.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_singleton_1 src node dst :
xdlchain src [node] dst ⊢
node.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_singleton_2 src node dst :
node.[xdlchain_prev] ↦ src -∗
node.[xdlchain_next] ↦ dst -∗
xdlchain src [node] dst.
#[local] Lemma xdlchain_cons_unfold {src} node nodes dst :
xdlchain src (node :: nodes) dst ⊣⊢
node.[xdlchain_prev] ↦ src ∗
match nodes with
| [] ⇒
node.[xdlchain_next] ↦ dst
| node' :: _ ⇒
node.[xdlchain_next] ↦ #node' ∗
xdlchain #node nodes dst
end.
Lemma xdlchain_cons {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊣⊢
node.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchain_cons_1 {src} nodes node nodes' dst :
nodes = node :: nodes' →
xdlchain src nodes dst ⊢
node.[xdlchain_prev] ↦ src ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head nodes') ∗
xdlchain #node nodes' dst.
Lemma xdlchain_cons_2 src node nodes dst :
node.[xdlchain_prev] ↦ src -∗
node.[xdlchain_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_1 {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_2 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.[xdlchain_prev] ↦ from_option #@{location} src (last nodes') ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_snoc_1 {src} nodes nodes' node dst :
nodes = nodes' ++ [node] →
xdlchain src nodes dst ⊢
xdlchain src nodes' #node ∗
node.[xdlchain_prev] ↦ from_option #@{location} src (last nodes') ∗
node.[xdlchain_next] ↦ dst.
Lemma xdlchain_snoc_2 src nodes node dst :
xdlchain src nodes #node -∗
node.[xdlchain_prev] ↦ from_option #@{location} src (last nodes) -∗
node.[xdlchain_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.[xdlchain_prev] ↦ from_option #@{location} src (last nodes') ∗
node.[xdlchain_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.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S i) nodes) ∗
xdlchain #node (drop (S i) nodes) dst.
Lemma xdlchain_lookup_1 {src nodes} i node dst :
nodes !! i = Some node →
xdlchain src nodes dst ⊢
xdlchain src (take i nodes) #node ∗
node.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S i) nodes) ∗
xdlchain #node (drop (S i) nodes) dst.
Lemma xdlchain_lookup_2 {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 (S i) nodes) →
xdlchain src (take i nodes) #node -∗
node.[xdlchain_prev] ↦ prev -∗
node.[xdlchain_next] ↦ next -∗
xdlchain #node (drop (S 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.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) ∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S i) nodes) ∗
( node.[xdlchain_prev] ↦ from_option #@{location} src (last $ take i nodes) -∗
node.[xdlchain_next] ↦ from_option #@{location} dst (head $ drop (S 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).{xdlchain_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).{xdlchain_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).{xdlchain_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).{xdlchain_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).{xdlchain_next} @ E
{{{
RET from_option #@{location} dst (head $ drop (S 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).{xdlchain_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 <-{xdlchain_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 <-{xdlchain_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 <-{xdlchain_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 <-{xdlchain_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 <-{xdlchain_next} v @ E
{{{
RET ();
xdlchain src (take (S i) nodes) v ∗
xdlchain #node (drop (S i) nodes) dst
}}}.
Lemma xdlchain٠set_next𑁒spec_last {src nodes} node dst v E :
last nodes = Some node →
{{{
xdlchain src nodes dst
}}}
#node <-{xdlchain_next} v @ E
{{{
RET ();
xdlchain src nodes v
}}}.
End zoo_G.
From zoo_std Require
xdlchain__opaque.
#[global] Opaque xdlchain.