1#![allow(clippy::items_after_test_module)]
5
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7use std::collections::{HashMap, HashSet, VecDeque};
8
9use super::types::{
10 ByzantineFaultTolerance, CAPClass, CAPProperty, CAPTheorem, ConsistencyLevel, FLPImpossibility,
11 GCounter, LamportClock, LamportTimestamp, PNCounter, PaxosAcceptor, PaxosProtocol, RaftNode,
12 RaftProtocol, RaftRole, ThreePCParticipant, TwoPCOutcome, TwoPCParticipant, TwoPCState,
13 TwoPSet, VectorClock,
14};
15
16pub fn app(f: Expr, a: Expr) -> Expr {
17 Expr::App(Box::new(f), Box::new(a))
18}
19pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
20 app(app(f, a), b)
21}
22pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
23 app(app2(f, a, b), c)
24}
25pub fn cst(s: &str) -> Expr {
26 Expr::Const(Name::str(s), vec![])
27}
28pub fn prop() -> Expr {
29 Expr::Sort(Level::zero())
30}
31pub fn type0() -> Expr {
32 Expr::Sort(Level::succ(Level::zero()))
33}
34pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
35 Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
36}
37pub fn arrow(a: Expr, b: Expr) -> Expr {
38 pi(BinderInfo::Default, "_", a, b)
39}
40pub fn bvar(n: u32) -> Expr {
41 Expr::BVar(n)
42}
43pub fn nat_ty() -> Expr {
44 cst("Nat")
45}
46pub fn bool_ty() -> Expr {
47 cst("Bool")
48}
49pub fn real_ty() -> Expr {
50 cst("Real")
51}
52pub fn list_ty(elem: Expr) -> Expr {
53 app(cst("List"), elem)
54}
55pub fn distributed_system_ty() -> Expr {
57 arrow(nat_ty(), prop())
58}
59pub fn cap_consistency_ty() -> Expr {
61 arrow(prop(), prop())
62}
63pub fn cap_availability_ty() -> Expr {
65 arrow(prop(), prop())
66}
67pub fn cap_partition_tolerance_ty() -> Expr {
69 arrow(prop(), prop())
70}
71pub fn cap_theorem_ty() -> Expr {
74 arrow(prop(), prop())
75}
76pub fn consensus_protocol_ty() -> Expr {
78 arrow(nat_ty(), prop())
79}
80pub fn paxos_protocol_ty() -> Expr {
82 arrow(nat_ty(), arrow(nat_ty(), prop()))
83}
84pub fn raft_protocol_ty() -> Expr {
86 arrow(nat_ty(), arrow(nat_ty(), prop()))
87}
88pub fn pbft_protocol_ty() -> Expr {
90 arrow(nat_ty(), arrow(nat_ty(), prop()))
91}
92pub fn byzantine_fault_tolerance_ty() -> Expr {
95 arrow(prop(), arrow(nat_ty(), prop()))
96}
97pub fn atomic_broadcast_ty() -> Expr {
99 arrow(prop(), prop())
100}
101pub fn vector_clock_ty() -> Expr {
103 arrow(nat_ty(), prop())
104}
105pub fn lamport_timestamp_ty() -> Expr {
107 arrow(prop(), nat_ty())
108}
109pub fn causally_precedes_ty() -> Expr {
111 arrow(prop(), arrow(prop(), prop()))
112}
113pub fn crdt_ty() -> Expr {
115 arrow(prop(), prop())
116}
117pub fn state_based_crdt_ty() -> Expr {
119 arrow(prop(), prop())
120}
121pub fn op_based_crdt_ty() -> Expr {
123 arrow(prop(), prop())
124}
125pub fn eventual_consistency_ty() -> Expr {
127 arrow(prop(), prop())
128}
129pub fn strong_eventual_consistency_ty() -> Expr {
131 arrow(prop(), prop())
132}
133pub fn linearizability_ty() -> Expr {
135 arrow(prop(), prop())
136}
137pub fn serializability_ty() -> Expr {
139 arrow(prop(), prop())
140}
141pub fn strict_serializability_ty() -> Expr {
143 arrow(prop(), prop())
144}
145pub fn two_phase_commit_ty() -> Expr {
147 arrow(nat_ty(), prop())
148}
149pub fn three_phase_commit_ty() -> Expr {
151 arrow(nat_ty(), prop())
152}
153pub fn safety_property_ty() -> Expr {
155 arrow(prop(), prop())
156}
157pub fn liveness_property_ty() -> Expr {
159 arrow(prop(), prop())
160}
161pub fn flp_impossibility_ty() -> Expr {
164 prop()
165}
166pub fn flp_theorem_ty() -> Expr {
169 arrow(prop(), prop())
170}
171pub fn byzantine_generals_ty() -> Expr {
174 arrow(nat_ty(), arrow(nat_ty(), prop()))
175}
176pub fn paxos_correctness_ty() -> Expr {
178 arrow(prop(), prop())
179}
180pub fn raft_leader_election_ty() -> Expr {
182 arrow(prop(), prop())
183}
184pub fn vector_clock_consistency_ty() -> Expr {
187 arrow(prop(), prop())
188}
189pub fn build_distributed_systems_env(env: &mut Environment) {
191 let axioms: &[(&str, Expr)] = &[
192 ("DistributedSystem", distributed_system_ty()),
193 ("CAPConsistency", cap_consistency_ty()),
194 ("CAPAvailability", cap_availability_ty()),
195 ("CAPPartitionTolerance", cap_partition_tolerance_ty()),
196 ("CAPTheorem", cap_theorem_ty()),
197 ("ConsensusProtocol", consensus_protocol_ty()),
198 ("PaxosProtocol", paxos_protocol_ty()),
199 ("RaftProtocol", raft_protocol_ty()),
200 ("PBFTProtocol", pbft_protocol_ty()),
201 ("ByzantineFaultTolerance", byzantine_fault_tolerance_ty()),
202 ("AtomicBroadcast", atomic_broadcast_ty()),
203 ("VectorClock", vector_clock_ty()),
204 ("LamportTimestamp", lamport_timestamp_ty()),
205 ("CausallyPrecedes", causally_precedes_ty()),
206 ("CRDT", crdt_ty()),
207 ("StateBasedCRDT", state_based_crdt_ty()),
208 ("OpBasedCRDT", op_based_crdt_ty()),
209 ("EventualConsistency", eventual_consistency_ty()),
210 (
211 "StrongEventualConsistency",
212 strong_eventual_consistency_ty(),
213 ),
214 ("Linearizability", linearizability_ty()),
215 ("Serializability", serializability_ty()),
216 ("StrictSerializability", strict_serializability_ty()),
217 ("TwoPhaseCommit", two_phase_commit_ty()),
218 ("ThreePhaseCommit", three_phase_commit_ty()),
219 ("SafetyProperty", safety_property_ty()),
220 ("LivenessProperty", liveness_property_ty()),
221 ("FLPImpossibility", flp_impossibility_ty()),
222 ("FLPTheorem", flp_theorem_ty()),
223 ("ByzantineGeneralsProblem", byzantine_generals_ty()),
224 ("PaxosCorrectness", paxos_correctness_ty()),
225 ("RaftLeaderElection", raft_leader_election_ty()),
226 ("VectorClockConsistency", vector_clock_consistency_ty()),
227 ("ProcessId", nat_ty()),
228 ("LogicalTime", nat_ty()),
229 ("Term", nat_ty()),
230 ("LogIndex", nat_ty()),
231 ("NodeState", arrow(nat_ty(), prop())),
232 ("MessageHistory", list_ty(prop())),
233 ("TransactionLog", list_ty(prop())),
234 ("PartitionEvent", prop()),
235 ];
236 for (name, ty) in axioms {
237 env.add(Declaration::Axiom {
238 name: Name::str(*name),
239 univ_params: vec![],
240 ty: ty.clone(),
241 })
242 .ok();
243 }
244}
245pub fn paxos_round(
250 acceptors: &mut Vec<PaxosAcceptor>,
251 proposal_number: u64,
252 proposed_value: u64,
253) -> Option<u64> {
254 let n = acceptors.len();
255 let quorum = n / 2 + 1;
256 let mut promises = Vec::new();
257 for acc in acceptors.iter_mut() {
258 if let Some(p) = acc.prepare(proposal_number) {
259 promises.push(p);
260 }
261 }
262 if promises.len() < quorum {
263 return None;
264 }
265 let value_to_propose = promises
266 .iter()
267 .filter(|(n, v)| *n > 0 && v.is_some())
268 .max_by_key(|(n, _)| *n)
269 .and_then(|(_, v)| *v)
270 .unwrap_or(proposed_value);
271 let mut accepts = 0;
272 for acc in acceptors.iter_mut() {
273 if acc.accept(proposal_number, value_to_propose) {
274 accepts += 1;
275 }
276 }
277 if accepts >= quorum {
278 Some(value_to_propose)
279 } else {
280 None
281 }
282}
283pub fn two_phase_commit(participants: &mut Vec<TwoPCParticipant>) -> TwoPCOutcome {
287 let all_yes = participants.iter_mut().all(|p| p.prepare());
288 let outcome = if all_yes {
289 TwoPCOutcome::Committed
290 } else {
291 TwoPCOutcome::Aborted
292 };
293 for p in participants.iter_mut() {
294 p.decide(outcome == TwoPCOutcome::Committed);
295 }
296 outcome
297}
298pub fn three_phase_commit(participants: &mut Vec<ThreePCParticipant>) -> bool {
300 let all_yes = participants.iter_mut().all(|p| p.can_commit());
301 if !all_yes {
302 for p in participants.iter_mut() {
303 p.abort();
304 }
305 return false;
306 }
307 for p in participants.iter_mut() {
308 p.pre_commit();
309 }
310 for p in participants.iter_mut() {
311 p.do_commit();
312 }
313 true
314}
315pub fn can_tolerate_byzantine(n: usize, f: usize) -> bool {
319 n > 3 * f
320}
321pub fn max_byzantine_faults(n: usize) -> usize {
323 if n < 4 {
324 0
325 } else {
326 (n - 1) / 3
327 }
328}
329pub fn flp_impossibility(asynchronous: bool, n_faulty: usize) -> bool {
334 asynchronous && n_faulty >= 1
335}
336pub fn cap_feasible(properties: &HashSet<CAPProperty>) -> bool {
341 !(properties.contains(&CAPProperty::Consistency)
342 && properties.contains(&CAPProperty::Availability)
343 && properties.contains(&CAPProperty::PartitionTolerance))
344}
345pub fn cap_classify(properties: &HashSet<CAPProperty>) -> Option<CAPClass> {
347 let c = properties.contains(&CAPProperty::Consistency);
348 let a = properties.contains(&CAPProperty::Availability);
349 let p = properties.contains(&CAPProperty::PartitionTolerance);
350 match (c, a, p) {
351 (true, false, true) => Some(CAPClass::CP),
352 (false, true, true) => Some(CAPClass::AP),
353 (true, true, false) => Some(CAPClass::CA),
354 _ => None,
355 }
356}
357#[cfg(test)]
358mod tests {
359 use super::*;
360 #[test]
361 fn test_lamport_clock() {
362 let mut c1 = LamportClock::new();
363 let mut c2 = LamportClock::new();
364 let t1 = c1.tick();
365 assert_eq!(t1, 1);
366 let t2 = c1.tick();
367 assert_eq!(t2, 2);
368 let t3 = c2.receive(t2);
369 assert_eq!(t3, 3, "After receiving t=2, c2 should be at max(0,2)+1 = 3");
370 let t4 = c2.tick();
371 assert_eq!(t4, 4);
372 }
373 #[test]
374 fn test_vector_clock_causality() {
375 let mut vc1 = VectorClock::new(0, 2);
376 let mut vc2 = VectorClock::new(1, 2);
377 vc1.tick();
378 vc2.receive(&vc1);
379 vc2.tick();
380 assert!(
381 vc1.causally_precedes(&vc2),
382 "vc1 should causally precede vc2"
383 );
384 assert!(
385 !vc2.causally_precedes(&vc1),
386 "vc2 should NOT causally precede vc1"
387 );
388 let mut vc3 = VectorClock::new(1, 2);
389 vc3.tick();
390 let vc1_copy = VectorClock {
391 clocks: vec![1, 0],
392 process_id: 0,
393 };
394 assert!(
395 vc1_copy.concurrent(&vc3),
396 "vc1=[1,0] and vc3=[0,1] should be concurrent"
397 );
398 }
399 #[test]
400 fn test_g_counter_crdt() {
401 let mut r0 = GCounter::new(0, 3);
402 let mut r1 = GCounter::new(1, 3);
403 let mut r2 = GCounter::new(2, 3);
404 r0.increment_by(5);
405 r1.increment_by(3);
406 r2.increment_by(2);
407 r0.merge(&r1);
408 r0.merge(&r2);
409 assert_eq!(r0.value(), 10, "G-Counter total should be 5+3+2=10");
410 r0.merge(&r1);
411 assert_eq!(r0.value(), 10, "G-Counter merge should be idempotent");
412 }
413 #[test]
414 fn test_pn_counter_crdt() {
415 let mut r0 = PNCounter::new(0, 2);
416 let mut r1 = PNCounter::new(1, 2);
417 r0.increment();
418 r0.increment();
419 r1.increment();
420 r1.decrement();
421 r0.merge(&r1);
422 assert_eq!(r0.value(), 2, "PN-Counter: 2 + 0 = 2");
423 }
424 #[test]
425 fn test_two_pset_crdt() {
426 let mut s1: TwoPSet<u32> = TwoPSet::new();
427 let mut s2: TwoPSet<u32> = TwoPSet::new();
428 s1.add(1u32);
429 s1.add(2u32);
430 s2.add(2u32);
431 s2.add(3u32);
432 s1.remove(2u32);
433 s1.merge(&s2);
434 assert!(s1.contains(&1u32), "1 should be present");
435 assert!(!s1.contains(&2u32), "2 was removed, should not be present");
436 assert!(s1.contains(&3u32), "3 should be present from s2");
437 s1.add(2u32);
438 assert!(!s1.contains(&2u32), "Cannot re-add tombstoned element");
439 }
440 #[test]
441 fn test_paxos_round() {
442 let mut acceptors: Vec<PaxosAcceptor> = (0..5).map(|_| PaxosAcceptor::new()).collect();
443 let result = paxos_round(&mut acceptors, 1, 42);
444 assert_eq!(
445 result,
446 Some(42),
447 "Paxos should decide value 42 with fresh acceptors"
448 );
449 let result2 = paxos_round(&mut acceptors, 2, 99);
450 assert!(result2.is_some(), "Second Paxos round should also decide");
451 assert_eq!(
452 result2,
453 Some(42),
454 "Paxos should preserve previously accepted value 42"
455 );
456 }
457 #[test]
458 fn test_raft_election() {
459 let n = 5;
460 let mut nodes: Vec<RaftNode> = (0..n).map(RaftNode::new).collect();
461 nodes[0].start_election();
462 assert_eq!(nodes[0].role, RaftRole::Candidate);
463 assert_eq!(nodes[0].current_term, 1);
464 let term = nodes[0].current_term;
465 let log_len = nodes[0].log.len();
466 for voter_id in 1..n {
467 let granted = nodes[voter_id].request_vote(0, term, log_len);
468 if granted {
469 let became_leader = nodes[0].receive_vote(voter_id, n);
470 if became_leader {
471 break;
472 }
473 }
474 }
475 assert_eq!(
476 nodes[0].role,
477 RaftRole::Leader,
478 "Node 0 should win election with majority"
479 );
480 }
481 #[test]
482 fn test_two_phase_commit() {
483 let mut ps: Vec<TwoPCParticipant> =
484 (0..4).map(|i| TwoPCParticipant::new(i, true)).collect();
485 let outcome = two_phase_commit(&mut ps);
486 assert_eq!(outcome, TwoPCOutcome::Committed, "All-yes should commit");
487 assert!(ps.iter().all(|p| p.state == TwoPCState::Committed));
488 let mut ps2: Vec<TwoPCParticipant> = vec![
489 TwoPCParticipant::new(0, true),
490 TwoPCParticipant::new(1, false),
491 TwoPCParticipant::new(2, true),
492 ];
493 let outcome2 = two_phase_commit(&mut ps2);
494 assert_eq!(outcome2, TwoPCOutcome::Aborted, "One-no should abort");
495 assert!(ps2.iter().all(|p| p.state == TwoPCState::Aborted));
496 }
497 #[test]
498 fn test_cap_theorem() {
499 let cp: HashSet<CAPProperty> = [CAPProperty::Consistency, CAPProperty::PartitionTolerance]
500 .iter()
501 .cloned()
502 .collect();
503 assert!(cap_feasible(&cp), "CP should be feasible");
504 assert_eq!(cap_classify(&cp), Some(CAPClass::CP));
505 let all: HashSet<CAPProperty> = [
506 CAPProperty::Consistency,
507 CAPProperty::Availability,
508 CAPProperty::PartitionTolerance,
509 ]
510 .iter()
511 .cloned()
512 .collect();
513 assert!(!cap_feasible(&all), "All-three CAP should be infeasible");
514 assert_eq!(cap_classify(&all), None);
515 }
516 #[test]
517 fn test_byzantine_faults() {
518 assert!(
519 can_tolerate_byzantine(4, 1),
520 "4 nodes can tolerate 1 Byzantine fault"
521 );
522 assert!(
523 !can_tolerate_byzantine(3, 1),
524 "3 nodes cannot tolerate 1 Byzantine fault"
525 );
526 assert_eq!(
527 max_byzantine_faults(10),
528 3,
529 "10 nodes: max Byzantine faults = 3"
530 );
531 assert_eq!(
532 max_byzantine_faults(3),
533 0,
534 "3 nodes: cannot tolerate any Byzantine fault"
535 );
536 assert!(flp_impossibility(true, 1), "Async + 1 faulty: FLP applies");
537 assert!(
538 !flp_impossibility(false, 1),
539 "Sync system: FLP does not apply"
540 );
541 }
542 #[test]
543 fn test_consistency_levels() {
544 assert!(ConsistencyLevel::Linearizable.implies(ConsistencyLevel::Eventual));
545 assert!(ConsistencyLevel::Linearizable.implies(ConsistencyLevel::Causal));
546 assert!(!ConsistencyLevel::Eventual.implies(ConsistencyLevel::Causal));
547 assert_eq!(ConsistencyLevel::Linearizable.name(), "Linearizable");
548 assert_eq!(ConsistencyLevel::Eventual.name(), "Eventual");
549 }
550 #[test]
551 fn test_build_env() {
552 let mut env = Environment::new();
553 build_distributed_systems_env(&mut env);
554 assert!(env.get(&Name::str("PaxosProtocol")).is_some());
555 assert!(env.get(&Name::str("VectorClock")).is_some());
556 assert!(env.get(&Name::str("CAPTheorem")).is_some());
557 assert!(env.get(&Name::str("TwoPhaseCommit")).is_some());
558 assert!(env.get(&Name::str("FLPImpossibility")).is_some());
559 }
560}
561pub fn build_env(env: &mut Environment) {
563 build_distributed_systems_env(env);
564}
565pub fn dst_ext_flp_impossibility_strong_ty() -> Expr {
568 arrow(nat_ty(), prop())
569}
570pub fn dst_ext_async_consensus_lower_bound_ty() -> Expr {
573 arrow(nat_ty(), arrow(nat_ty(), prop()))
574}
575pub fn dst_ext_crash_failure_model_ty() -> Expr {
578 arrow(nat_ty(), arrow(nat_ty(), prop()))
579}
580pub fn dst_ext_omission_failure_model_ty() -> Expr {
583 arrow(nat_ty(), arrow(nat_ty(), prop()))
584}
585pub fn dst_ext_timed_async_model_ty() -> Expr {
588 arrow(real_ty(), arrow(real_ty(), prop()))
589}
590pub fn dst_ext_paxos_safety_ty() -> Expr {
593 prop()
594}
595pub fn dst_ext_paxos_liveness_ty() -> Expr {
598 arrow(nat_ty(), prop())
599}
600pub fn dst_ext_multi_paxos_ty() -> Expr {
603 arrow(nat_ty(), arrow(nat_ty(), prop()))
604}
605pub fn dst_ext_paxos_phase1_ty() -> Expr {
608 arrow(nat_ty(), prop())
609}
610pub fn dst_ext_paxos_phase2_ty() -> Expr {
613 arrow(nat_ty(), arrow(real_ty(), prop()))
614}
615pub fn dst_ext_raft_leader_uniqueness_ty() -> Expr {
618 prop()
619}
620pub fn dst_ext_raft_log_matching_ty() -> Expr {
623 prop()
624}
625pub fn dst_ext_raft_leader_completeness_ty() -> Expr {
628 prop()
629}
630pub fn dst_ext_raft_state_machine_safety_ty() -> Expr {
633 prop()
634}
635pub fn dst_ext_raft_membership_change_ty() -> Expr {
638 arrow(nat_ty(), arrow(nat_ty(), prop()))
639}
640pub fn dst_ext_pbft_safety_ty() -> Expr {
643 arrow(nat_ty(), prop())
644}
645pub fn dst_ext_pbft_liveness_ty() -> Expr {
648 arrow(nat_ty(), prop())
649}
650pub fn dst_ext_threshold_signature_ty() -> Expr {
653 arrow(nat_ty(), arrow(nat_ty(), prop()))
654}
655pub fn dst_ext_byzantine_agreement_ty() -> Expr {
658 arrow(nat_ty(), arrow(nat_ty(), prop()))
659}
660pub fn dst_ext_authenticated_byzantine_ty() -> Expr {
663 arrow(nat_ty(), arrow(nat_ty(), prop()))
664}
665pub fn dst_ext_consistent_hashing_ty() -> Expr {
668 arrow(nat_ty(), arrow(nat_ty(), prop()))
669}
670pub fn dst_ext_consistent_hashing_balance_ty() -> Expr {
673 arrow(nat_ty(), arrow(real_ty(), prop()))
674}
675pub fn dst_ext_dht_chord_ty() -> Expr {
678 arrow(nat_ty(), prop())
679}
680pub fn dst_ext_dht_kademlia_ty() -> Expr {
683 arrow(nat_ty(), prop())
684}
685pub fn dst_ext_dht_lookup_complexity_ty() -> Expr {
688 arrow(nat_ty(), prop())
689}
690pub fn dst_ext_eventual_consistency_convergence_ty() -> Expr {
693 arrow(real_ty(), prop())
694}
695pub fn dst_ext_monotonic_read_consistency_ty() -> Expr {
698 prop()
699}
700pub fn dst_ext_monotonic_write_consistency_ty() -> Expr {
703 prop()
704}
705pub fn dst_ext_read_your_writes_ty() -> Expr {
708 prop()
709}
710pub fn dst_ext_writes_follow_reads_ty() -> Expr {
713 prop()
714}
715pub fn dst_ext_crdt_sec_ty() -> Expr {
718 prop()
719}
720pub fn dst_ext_crdt_join_semilattice_ty() -> Expr {
723 prop()
724}
725pub fn dst_ext_crdt_inflation_ty() -> Expr {
728 prop()
729}
730pub fn dst_ext_or_set_crdt_ty() -> Expr {
733 prop()
734}
735pub fn dst_ext_mv_register_crdt_ty() -> Expr {
738 prop()
739}
740pub fn dst_ext_ntp_sync_bound_ty() -> Expr {
743 arrow(real_ty(), arrow(real_ty(), prop()))
744}
745pub fn dst_ext_clock_drift_rate_ty() -> Expr {
748 arrow(real_ty(), prop())
749}
750pub fn dst_ext_christian_algorithm_ty() -> Expr {
753 arrow(real_ty(), prop())
754}
755pub fn dst_ext_berkeley_algorithm_ty() -> Expr {
758 arrow(nat_ty(), arrow(real_ty(), prop()))
759}
760pub fn dst_ext_happens_before_ty() -> Expr {
763 arrow(prop(), arrow(prop(), prop()))
764}
765pub fn dst_ext_lamport_clock_consistency_ty() -> Expr {
768 prop()
769}
770pub fn dst_ext_vector_clock_characterization_ty() -> Expr {
773 prop()
774}
775pub fn dst_ext_causal_delivery_ty() -> Expr {
778 prop()
779}
780pub fn dst_ext_causal_consistency_ty() -> Expr {
783 prop()
784}
785pub fn dst_ext_snapshot_isolation_ty() -> Expr {
788 prop()
789}
790pub fn dst_ext_repeatable_read_ty() -> Expr {
793 prop()
794}
795pub fn dst_ext_phantom_read_ty() -> Expr {
798 prop()
799}
800pub fn dst_ext_write_skew_ty() -> Expr {
803 prop()
804}
805pub fn register_distributed_systems_extended(env: &mut Environment) -> Result<(), String> {
807 let axioms: &[(&str, Expr)] = &[
808 (
809 "FLPImpossibilityStrong",
810 dst_ext_flp_impossibility_strong_ty(),
811 ),
812 (
813 "AsyncConsensusLowerBound",
814 dst_ext_async_consensus_lower_bound_ty(),
815 ),
816 ("CrashFailureModel", dst_ext_crash_failure_model_ty()),
817 ("OmissionFailureModel", dst_ext_omission_failure_model_ty()),
818 ("TimedAsynchronousModel", dst_ext_timed_async_model_ty()),
819 ("PaxosSafety", dst_ext_paxos_safety_ty()),
820 ("PaxosLiveness", dst_ext_paxos_liveness_ty()),
821 ("MultiPaxos", dst_ext_multi_paxos_ty()),
822 ("PaxosPhaseOneMessage", dst_ext_paxos_phase1_ty()),
823 ("PaxosPhaseTwoMessage", dst_ext_paxos_phase2_ty()),
824 ("RaftLeaderUniqueness", dst_ext_raft_leader_uniqueness_ty()),
825 ("RaftLogMatching", dst_ext_raft_log_matching_ty()),
826 (
827 "RaftLeaderCompleteness",
828 dst_ext_raft_leader_completeness_ty(),
829 ),
830 (
831 "RaftStateMachineSafety",
832 dst_ext_raft_state_machine_safety_ty(),
833 ),
834 ("RaftMembershipChange", dst_ext_raft_membership_change_ty()),
835 ("PBFTSafety", dst_ext_pbft_safety_ty()),
836 ("PBFTLiveness", dst_ext_pbft_liveness_ty()),
837 ("ThresholdSignature", dst_ext_threshold_signature_ty()),
838 ("ByzantineAgreement", dst_ext_byzantine_agreement_ty()),
839 (
840 "AuthenticatedByzantine",
841 dst_ext_authenticated_byzantine_ty(),
842 ),
843 ("ConsistentHashing", dst_ext_consistent_hashing_ty()),
844 (
845 "ConsistentHashingBalance",
846 dst_ext_consistent_hashing_balance_ty(),
847 ),
848 ("DHTChord", dst_ext_dht_chord_ty()),
849 ("DHTKademlia", dst_ext_dht_kademlia_ty()),
850 ("DHTLookupComplexity", dst_ext_dht_lookup_complexity_ty()),
851 (
852 "EventualConsistencyConvergence",
853 dst_ext_eventual_consistency_convergence_ty(),
854 ),
855 (
856 "MonotonicReadConsistency",
857 dst_ext_monotonic_read_consistency_ty(),
858 ),
859 (
860 "MonotonicWriteConsistency",
861 dst_ext_monotonic_write_consistency_ty(),
862 ),
863 ("ReadYourWrites", dst_ext_read_your_writes_ty()),
864 ("WritesFollowReads", dst_ext_writes_follow_reads_ty()),
865 ("CRDTStrongEventualConsistency", dst_ext_crdt_sec_ty()),
866 ("CRDTJoinSemilattice", dst_ext_crdt_join_semilattice_ty()),
867 ("CRDTInflation", dst_ext_crdt_inflation_ty()),
868 ("OrSetCRDT", dst_ext_or_set_crdt_ty()),
869 ("MVRegisterCRDT", dst_ext_mv_register_crdt_ty()),
870 ("NTPSyncBound", dst_ext_ntp_sync_bound_ty()),
871 ("ClockDriftRate", dst_ext_clock_drift_rate_ty()),
872 ("ChristianAlgorithm", dst_ext_christian_algorithm_ty()),
873 ("BerkeleyAlgorithm", dst_ext_berkeley_algorithm_ty()),
874 ("HappensBefore", dst_ext_happens_before_ty()),
875 (
876 "LamportClockConsistency",
877 dst_ext_lamport_clock_consistency_ty(),
878 ),
879 (
880 "VectorClockCharacterization",
881 dst_ext_vector_clock_characterization_ty(),
882 ),
883 ("CausalDelivery", dst_ext_causal_delivery_ty()),
884 ("CausalConsistency", dst_ext_causal_consistency_ty()),
885 ("SnapshotIsolation", dst_ext_snapshot_isolation_ty()),
886 ("RepeatableRead", dst_ext_repeatable_read_ty()),
887 ("PhantomRead", dst_ext_phantom_read_ty()),
888 ("WriteSkew", dst_ext_write_skew_ty()),
889 ];
890 for (name, ty) in axioms {
891 env.add(Declaration::Axiom {
892 name: Name::str(*name),
893 univ_params: vec![],
894 ty: ty.clone(),
895 })
896 .map_err(|e| format!("Failed to register {}: {:?}", name, e))?;
897 }
898 Ok(())
899}
900pub fn dst_ext_mix_hash(a: u64, b: u64) -> u64 {
902 let mut h = a.wrapping_mul(6364136223846793005).wrapping_add(b);
903 h ^= h >> 33;
904 h = h.wrapping_mul(0xff51afd7ed558ccd);
905 h ^= h >> 33;
906 h
907}