(* Victor B. F. Gomes, University of Cambridge MartinKleppmann,UniversityofCambridge DominicP.Mulligan,UniversityofCambridge AlastairR.Beresford,UniversityofCambridge
*)
section‹Observed-Remove Set›
text‹The ORSet is a well-known CRDT for implementing replicated sets, supporting two operations:
the \emph{insertion} and \emph{deletion} of an arbitrary element in the shared set.›
definition op_elem :: "('id, 'a) operation ==> 'a"where "op_elem oper ≡ case oper of Add i e ==> e | Rem is e ==> e"
definition interpret_op :: "('id, 'a) operation ==> ('id, 'a) state ⇀ ('id, 'a) state" (‹⟨_⟩› [0] 1000) where "interpret_op oper state ≡ let before = state (op_elem oper); after = case oper of Add i e ==> before ∪ {i} | Rem is e ==> before - is in Some (state ((op_elem oper) := after))"
definition valid_behaviours :: "('id, 'a) state ==> 'id × ('id, 'a) operation ==> bool"where "valid_behaviours state msg ≡ case msg of (i, Add j e) ==> i = j | (i, Rem is e) ==> is = state e"
lemma (in orset) add_rem_commute: assumes"i ∉ is" shows"⟨Add i e1⟩⊳⟨Rem is e2⟩ = ⟨Rem is e2⟩⊳⟨Add i e1⟩" using assms by(auto simp add: interpret_op_def kleisli_def op_elem_def, fastforce)
lemma (in orset) apply_operations_never_fails: assumes"xs prefix of i" shows"apply_operations xs ≠ None" using assms proof(induction xs rule: rev_induct, clarsimp) case (snoc x xs) thus ?case proof (cases x) case (Broadcast e) thus ?thesis using snoc by force next case (Deliver e) thus ?thesis using snoc by (clarsimp, metis interpret_op_def interp_msg_def bind.bind_lunit prefix_of_appendD) qed qed
lemma (in orset) add_id_valid: assumes"xs prefix of j" and"Deliver (i1, Add i2 e) ∈ set xs" shows"i1 = i2" proof - have"∃s. valid_behaviours s (i1, Add i2 e)" using assms deliver_in_prefix_is_valid by blast thus ?thesis by(simp add: valid_behaviours_def) qed
definition (in orset) added_ids :: "('id × ('id, 'b) operation) event list ==> 'b ==> 'id list"where "added_ids es p ≡ List.map_filter (λx. case x of Deliver (i, Add j e) ==> if e = p then Some j else None | _ ==> None) es"
lemma (in orset) [simp]: shows"added_ids [] e = []" by (auto simp: added_ids_def map_filter_def)
lemma (in orset) [simp]: shows"added_ids (xs @ ys) e = added_ids xs e @ added_ids ys e" by (auto simp: added_ids_def map_filter_append)
lemma (in orset) added_ids_Broadcast_collapse [simp]: shows"added_ids ([Broadcast e]) e' = []" by (auto simp: added_ids_def map_filter_append map_filter_def)
lemma (in orset) added_ids_Deliver_Rem_collapse [simp]: shows"added_ids ([Deliver (i, Rem is e)]) e' = []" by (auto simp: added_ids_def map_filter_append map_filter_def)
lemma (in orset) added_ids_Deliver_Add_diff_collapse [simp]: shows"e ≠ e' ==> added_ids ([Deliver (i, Add j e)]) e' = []" by (auto simp: added_ids_def map_filter_append map_filter_def)
lemma (in orset) added_ids_Deliver_Add_same_collapse [simp]: shows"added_ids ([Deliver (i, Add j e)]) e = [j]" by (auto simp: added_ids_def map_filter_append map_filter_def)
lemma (in orset) added_id_not_in_set: assumes"i1 ∉ set (added_ids [Deliver (i, Add i2 e)] e)" shows"i1 ≠ i2" using assms by simp
lemma (in orset) apply_operations_added_ids: assumes"es prefix of j" and"apply_operations es = Some f" shows"f x ⊆ set (added_ids es x)" using assms proof (induct es arbitrary: f rule: rev_induct, force) case (snoc x xs) thus ?case proof (cases x, force) case (Deliver e) moreoverobtain a b where"e = (a, b)"by force ultimatelyshow ?thesis using snoc by(case_tac b; clarsimp simp: interp_msg_def split: bind_splits,
force split: if_split_asm simp add: op_elem_def interpret_op_def) qed qed
lemma (in orset) Deliver_added_ids: assumes"xs prefix of j" and"i ∈ set (added_ids xs e)" shows"Deliver (i, Add i e) ∈ set xs" using assms proof (induct xs rule: rev_induct, clarsimp) case (snoc x xs) thus ?case proof (cases x, force) case (Deliver e') moreoverobtain a b where"e' = (a, b)"by force ultimatelyshow ?thesis using snoc apply (case_tac b; clarsimp) apply (metis added_ids_Deliver_Add_diff_collapse added_ids_Deliver_Add_same_collapse
empty_iff list.set(1) set_ConsD add_id_valid in_set_conv_decomp prefix_of_appendD) apply force done qed qed
lemma (in orset) Broadcast_Deliver_prefix_closed: assumes"xs @ [Broadcast (r, Rem ix e)] prefix of j" and"i ∈ ix" shows"Deliver (i, Add i e) ∈ set xs" proof - obtain y where"apply_operations xs = Some y" using assms broadcast_only_valid_msgs by blast moreoverhence"ix = y e" by (metis (mono_tags, lifting) assms(1) broadcast_only_valid_msgs operation.case(2) option.simps(1)
valid_behaviours_def case_prodD) ultimatelyshow ?thesis using assms Deliver_added_ids apply_operations_added_ids by blast qed
lemma (in orset) Broadcast_Deliver_prefix_closed2: assumes"xs prefix of j" and"Broadcast (r, Rem ix e) ∈ set xs" and"i ∈ ix" shows"Deliver (i, Add i e) ∈ set xs" using assms Broadcast_Deliver_prefix_closed by (induction xs rule: rev_induct; force)
lemma (in orset) concurrent_add_remove_independent_technical: assumes"i ∈ is" and"xs prefix of j" and"(i, Add i e) ∈ set (node_deliver_messages xs)"and"(ir, Rem is e) ∈ set (node_deliver_messages xs)" shows"hb (i, Add i e) (ir, Rem is e)" proof - obtainpre k where"pre@[Broadcast (ir, Rem is e)] prefix of k" using assms delivery_has_a_cause events_before_exist prefix_msg_in_history by blast moreoverhence"Deliver (i, Add i e) ∈ set pre" using Broadcast_Deliver_prefix_closed assms(1) by auto ultimatelyshow ?thesis using hb.intros(2) events_in_local_order by blast qed
lemma (in orset) Deliver_Add_same_id_same_message: assumes"Deliver (i, Add i e1) ∈ set (history j)"and"Deliver (i, Add i e2) ∈ set (history j)" shows"e1 = e2" proof - obtain pre1 pre2 k1 k2 where *: "pre1@[Broadcast (i, Add i e1)] prefix of k1""pre2@[Broadcast (i, Add i e2)] prefix of k2" using assms delivery_has_a_cause events_before_exist by meson moreoverhence"Broadcast (i, Add i e1) ∈ set (history k1)""Broadcast (i, Add i e2) ∈ set (history k2)" using node_histories.prefix_to_carriers node_histories_axioms by force+ ultimatelyshow ?thesis using msg_id_unique by fastforce qed
lemma (in orset) ids_imply_messages_same: assumes"i ∈ is" and"xs prefix of j" and"(i, Add i e1) ∈ set (node_deliver_messages xs)"and"(ir, Rem is e2) ∈ set (node_deliver_messages xs)" shows"e1 = e2" proof - obtainpre k where"pre@[Broadcast (ir, Rem is e2)] prefix of k" using assms delivery_has_a_cause events_before_exist prefix_msg_in_history by blast moreoverhence"Deliver (i, Add i e2) ∈ set pre" using Broadcast_Deliver_prefix_closed assms(1) by blast moreoverhave"Deliver (i, Add i e1) ∈ set (history j)" using assms(2) assms(3) prefix_msg_in_history by blast ultimatelyshow ?thesis by (metis fst_conv msg_id_unique network.delivery_has_a_cause network_axioms operation.inject(1)
prefix_elem_to_carriers prefix_of_appendD prod.inject) qed
corollary (in orset) concurrent_add_remove_independent: assumes"¬ hb (i, Add i e1) (ir, Rem is e2)"and"¬ hb (ir, Rem is e2) (i, Add i e1)" and"xs prefix of j" and"(i, Add i e1) ∈ set (node_deliver_messages xs)"and"(ir, Rem is e2) ∈ set (node_deliver_messages xs)" shows"i ∉ is" using assms ids_imply_messages_same concurrent_add_remove_independent_technical by fastforce
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.