|
| 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 main.tactics. |
| 12 | + |
| 13 | +Require main.crdt.operation_crdt. |
| 14 | + |
| 15 | +Import Coq.Lists.List.ListNotations. |
| 16 | + |
| 17 | +(* We can emulate a state-based CRDT with an operation-based CRDT. *) |
| 18 | + |
| 19 | +Definition operation_crdt_data_from_state_crdt |
| 20 | + [A Q] |
| 21 | + (crdt : state_crdt.Crdt A Q) |
| 22 | +: operation_crdt.CrdtData A Q |
| 23 | +:= |
| 24 | + {| |
| 25 | + operation_crdt.State := crdt.(state_crdt.State); |
| 26 | + operation_crdt.Operation := crdt.(state_crdt.State); |
| 27 | + operation_crdt.initial := crdt.(state_crdt.initial); |
| 28 | + operation_crdt.update x s := crdt.(state_crdt.update) x s; |
| 29 | + operation_crdt.interpret o s := crdt.(state_crdt.merge) o s; |
| 30 | + operation_crdt.query s := crdt.(state_crdt.query) s; |
| 31 | + operation_crdt.Precondition _ _ := True; |
| 32 | + |}. |
| 33 | + |
| 34 | +Program Definition operation_crdt_from_state_crdt |
| 35 | + [A Q] |
| 36 | + (crdt : state_crdt.Crdt A Q) |
| 37 | +: operation_crdt.Crdt (operation_crdt_data_from_state_crdt crdt) |
| 38 | +:= {| operation_crdt.commutativity := _ |}. |
| 39 | +Next Obligation. |
| 40 | + clean. |
| 41 | + pose proof (crdt.(state_crdt.semilattice _ _)). |
| 42 | + rewrite state_crdt.associativity |
| 43 | + with (initial := crdt.(state_crdt.initial)); search. |
| 44 | + rewrite state_crdt.commutativity |
| 45 | + with (initial := crdt.(state_crdt.initial)) (x := o1); search. |
| 46 | +Qed. |
| 47 | + |
| 48 | +(* |
| 49 | + We can emulate an operation-based CRDT with a state-based CRDT if the |
| 50 | + delivery precondition and equality of operations are decidable. |
| 51 | +*) |
| 52 | + |
| 53 | +#[local] Obligation Tactic := auto. (* `search` diverges here, sadly. *) |
| 54 | + |
| 55 | +Program Definition state_crdt_from_operation_crdt |
| 56 | + [A Q] |
| 57 | + [crdt_data : operation_crdt.CrdtData A Q] |
| 58 | + (crdt : operation_crdt.Crdt crdt_data) |
| 59 | + (precondition : |
| 60 | + forall s o, |
| 61 | + {crdt_data.(operation_crdt.Precondition) s o} + |
| 62 | + {~ crdt_data.(operation_crdt.Precondition) s o} |
| 63 | + ) |
| 64 | + (equal : |
| 65 | + forall o1 o2 : crdt_data.(operation_crdt.Operation), |
| 66 | + {o1 = o2} + {o1 <> o2} |
| 67 | + ) |
| 68 | +: state_crdt.Crdt A Q := |
| 69 | + {| |
| 70 | + state_crdt.State := |
| 71 | + list crdt_data.(operation_crdt.Operation) * |
| 72 | + list crdt_data.(operation_crdt.Operation) * |
| 73 | + crdt_data.(operation_crdt.State); |
| 74 | + state_crdt.initial := ([], [], crdt_data.(operation_crdt.initial)); |
| 75 | + state_crdt.merge := _; |
| 76 | + state_crdt.update _ _ := _; |
| 77 | + state_crdt.query '(_, _, s) := crdt_data.(operation_crdt.query) s; |
| 78 | + |}. |
| 79 | +Next Obligation. |
| 80 | +Admitted. |
| 81 | +Next Obligation. |
| 82 | +Admitted. |
0 commit comments