Skip to content

Commit 6f8a647

Browse files
committed
Demonstrate that the two styles of CRDTs are equivalent
1 parent d08a37d commit 6f8a647

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

proofs/crdt/equivalence.v

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
(**************************************************************************)
2+
(**************************************************************************)
3+
(**** ****)
4+
(**** Equivalence of state-based and operation-based conflict-free ****)
5+
(**** replicated data types ****)
6+
(**** ****)
7+
(**************************************************************************)
8+
(**************************************************************************)
9+
10+
Require Import Coq.Lists.List.
11+
Require Import Coq.Sorting.Permutation.
12+
Require Import main.tactics.
13+
14+
Require main.crdt.operation_crdt.
15+
16+
Import Coq.Lists.List.ListNotations.
17+
18+
(* We can emulate a state-based CRDT with an operation-based CRDT. *)
19+
20+
Definition operation_crdt_data_from_state_crdt
21+
[A Q]
22+
(crdt : state_crdt.Crdt A Q)
23+
: operation_crdt.CrdtData A Q
24+
:=
25+
{|
26+
operation_crdt.State := crdt.(state_crdt.State);
27+
operation_crdt.Operation := crdt.(state_crdt.State);
28+
operation_crdt.initial := crdt.(state_crdt.initial);
29+
operation_crdt.update x s := crdt.(state_crdt.update) x s;
30+
operation_crdt.interpret o s := crdt.(state_crdt.merge) o s;
31+
operation_crdt.query s := crdt.(state_crdt.query) s;
32+
operation_crdt.Precondition _ _ := True;
33+
|}.
34+
35+
Program Definition operation_crdt_from_state_crdt
36+
[A Q]
37+
(crdt : state_crdt.Crdt A Q)
38+
: operation_crdt.Crdt (operation_crdt_data_from_state_crdt crdt)
39+
:= {| operation_crdt.commutativity := _ |}.
40+
Next Obligation.
41+
clean.
42+
pose proof (crdt.(state_crdt.semilattice _ _)).
43+
rewrite state_crdt.associativity
44+
with (initial := crdt.(state_crdt.initial)); search.
45+
rewrite state_crdt.commutativity
46+
with (initial := crdt.(state_crdt.initial)) (x := o1); search.
47+
Qed.
48+
49+
(*
50+
We can emulate an operation-based CRDT with a state-based CRDT if the
51+
delivery precondition and equality on operations are decidable and there is a
52+
way to order any given set of operations. The order can be completely
53+
arbitrary.
54+
*)
55+
56+
#[local] Obligation Tactic := auto. (* `search` diverges here, sadly. *)
57+
58+
Program Definition state_crdt_from_operation_crdt
59+
[A Q]
60+
[crdt_data : operation_crdt.CrdtData A Q]
61+
(crdt : operation_crdt.Crdt crdt_data)
62+
(precondition :
63+
forall s o,
64+
{crdt_data.(operation_crdt.Precondition) s o} +
65+
{~ crdt_data.(operation_crdt.Precondition) s o})
66+
(equal :
67+
forall (o1 o2 : crdt_data.(operation_crdt.Operation)),
68+
{o1 = o2} + {o1 <> o2})
69+
(permute :
70+
list crdt_data.(operation_crdt.Operation) ->
71+
list crdt_data.(operation_crdt.Operation))
72+
(H1 : forall os, Permutation os (permute os))
73+
(H : forall os1 os2, Permutation os1 os2 -> permute os1 = permute os2)
74+
: state_crdt.Crdt A Q :=
75+
{|
76+
state_crdt.State :=
77+
list crdt_data.(operation_crdt.Operation) *
78+
list crdt_data.(operation_crdt.Operation);
79+
state_crdt.initial := ([], []);
80+
state_crdt.merge '(_, _) '(_, _) := _;
81+
state_crdt.update _ '(_, _) := _;
82+
state_crdt.query '(_, delivered) :=
83+
crdt_data.(operation_crdt.query)
84+
(operation_crdt.run crdt_data delivered);
85+
|}.
86+
Next Obligation.
87+
clean.
88+
split; search.
89+
Admitted.
90+
Next Obligation.
91+
Admitted.

0 commit comments

Comments
 (0)