public void OrderingOfEventsExample() { // ^ ^ time ↑ // | | // evt p3 * | // | | // rcv p2 *---+ +---* q2 rcv // | \ / | // | \/ | // | /\ | // | / \ | // rcv p1 *---+ +---* q1 snd // | | Stamp seed = new Stamp(); (Stamp, Stamp)fork = seed.Fork(); Process p = new Process("p", fork.Item1); Process q = new Process("q", fork.Item2); Message msgp1 = p.Send("p1"); Stamp p1 = p.CurrentStamp; Console.WriteLine($"p1:{p1} after send"); Message msgq1 = q.Send("q1"); Stamp q1 = q.CurrentStamp; Console.WriteLine($"q1:{q1} after send"); Stamp p2 = p.Receive(msgq1); Console.WriteLine($"p2:{p2} after receive"); Stamp q2 = q.Receive(msgp1); Console.WriteLine($"q1:{q1} after receive"); Stamp p3 = p.Increment(); Console.WriteLine($"p3:{p3} after event"); p1.Leq(p2).Should().BeTrue(); p1.Leq(p3).Should().BeTrue(); p2.Leq(p3).Should().BeTrue(); q1.Leq(q2).Should().BeTrue(); p1.Leq(q2).Should().BeTrue(); // send occurs before receive q1.Leq(p2).Should().BeTrue(); // send occurs before receive p1.Concurrent(q1).Should().BeTrue(); p2.Concurrent(q2).Should().BeTrue(); p3.Concurrent(q2).Should().BeTrue(); // Stamp implements IComparable<Stamp> so a collection of stamps // can be partially ordered using Sort methods. Note this is a // partial order (not total order) as CompareTo returns 0 // for equal and concurrent stamps. var arr = new[] { q2, q1, p3, p2, p1 }; Array.Sort(arr); arr.Should().ContainInOrder(p1, p2, p3); arr.Should().ContainInOrder(q1, q2); arr.Should().ContainInOrder(p1, q2); arr.Should().ContainInOrder(q1, p2, p3); }