Concurrency Theory: Lecture 11, 6 March 2018 -------------------------------------------- Recall: Trace alphabet (Act,I), trace languages, regular trace languages Distributed alphabets (Act_1,...,Act_n) as implementations of trace alphabets Direct product automata - Characterized in terms of shuffle closure - Not closed under boolean operations Synchronized product automata - F is an arbitrary subset of Q (not simply F_1 x F_2 x ... x F_k) - Closed under boolean operations - Equivalent to finite unions of direct product automata - No effective characterization of this class Synchronized products do not accept all regular trace languages. - Counterexample: Distributed alphabet = ({a,c},{b,c}) - Language = [(ab+ba)c + (aabb + ... + bbaa)c]* Synchronized products coordinate components once, at the end of the input. Need coordination at every synchronization. ---------- Asynchronous automata (Zielonka, 1987) - Let loc(a) = {i1,i2,..,ik} - An a-state is (q1,...,qk) where each qj belongs to Q_ij - Q_a denote the set of a-states - Transition relation -->_a is a subset of Q_a x Q_a jointly agree on the next move - Global initial state, global final states - Components only contribute local states, no local transition relations - Can view this is a labelled 1-safe net - 1 place for each local state - 1 labelled transition for each entry in -->_a Theorem [Zielonka] Every regular trace language is accepted by a deterministic asynchronous automaton. Note: this works for any distributed alphabet that implements th independence relation of the trace alphabet. Proving the theorem involves solving a problem regarding information flow in a trace: ---------------------------------------------------------------------- Let t = (E,<=.lab) be a trace, represented as a labelled partial order, lab : E --> Act ---------- For a in Act, max_a(t) is the maximum a-event (wrt <=) in E - All a events are ordered, because (a,a) in D, not I - Can add an initial event labelled 0 that synchronizes all processes (so loc(0) = {1,2,...,n}), so max_a(t) is always well defined A-view of t is what is "visible" with respect to max_a(t) - delta_a(t) = { e | e' <= max_a(t)} ---------- Can adapt these definitions in terms of agents/processes rather than letters For i in {1,2,...,n}, an i-event is any event labelled by Act_i - Note that any two i-events are ordered wrt <= - The initial event 0 is an i-event for all i max_i(t) = maximum i-event in t delta_i(t) = i-view of t = {e | e <= max_i(t)} Latest information of i about j is the maximum j event in the i-view latest_{i->j}(t) = max_j(delta_i(t)) ---------- Problem: Suppose each process i incrementally maintains local information about latest{i->k}(t) for every process k. When i and j meet, they need to compare which of latest_{i->k}(t) and latest_{j->k}(t) is latest, for every process k Constraints: Finite-state, maintain only bounded amount of information. ---------- Maintaining latest information: - Each process i maintains a table latest_i with n entries, corresponding to latest_{i->1}, ..., latest_{i->n} - Call these events i's primary events - At most n primary events per process - Each entry in the table records an event, identified by a suitable label - If two entries have the same label, they are the same event - How to set up labels so that they can be compared? Local timestamps - Each process i maintains a local count c_i of how many actions it has performed. - Each action a is labelled by (a,v) where v is a vector of local "timestamps" where v[i] is c_i if i in loc(a) and is a dummy value, say _, otherwise Informal algorithm: Each process i maintains a counter c_i Initially: latest_{i->j} = (0,(1,1,...,1)) for all j c_i := 1 When an action a occurs - Each i in loc(a) increments c_i - The current action is assigned the label l = (a,v) where v[j] = c_j for all j in loc(a) and v[j] = _ otherwise - For each i,j in loc(a), latest_{i->j} is updated to (a,v) - For each k not in loc(a): - For each i in loc(a), let latest_{i->k} be (a_i,v_i) - Compare and choose (a_j,v_j) for which v_j[k] is maximum - Every process updates latest_{i->k} to (a_j,v_j) Notice that all processes j that participate in a leave with identical values in latest_j. ---------- Difficulty: - Comparing local timestamps relies on actual values of timestamps. Counter values are unbounded, so number of bits to maintain counters and timestamps is also unbounded. - Finite state => bounded memory => bounded set of labels, that must be reused. Need to fix order between labels dynamically, according to context. (For unbounded numbers, order between labels is fixed statically, based on value of number.) ---------- Comparing labels without relying on values: Suppose i and j synchronize on an action after t. Events in delta_i(t) union delta_j(t) divide into three sets: 1. E_common = delta_i(t) intersect delta_j(t) : both see these events 2. E_i = delta_i(t) \ delta_j(t) : only i sees these events 3. E_j = delta_j(t) \ delta_i(t) : only j sees these events Note that each pair of events e in E_i and f in E_j is independent. We want to compare e_ik = latest_{i->k}(t) and e_jk = latest{j->k}(t). Three cases are possible A. e_ik in E_i, e_jk in E_common : e_ik is later than e_jk B. e_jk in E_j, e_ik in E_common : e_jk is later than e_ik C. e_ik and_jk both in E_common : e_jk = e_ik Cannot have e_ik in E_i and e_jk in E_j because all k events are linearly ordered, but E_i is independent of E_j. If we can compute whether e_ik and e_jk are inside or outside E_common, we are done. Lemma: Every maximal element in E_common is a primary event for both i and j Therefore, the set of events that belong to both latest_i and latest_j include all the maximal events in E_common - Any event in latest_i below such a maximal event lies in E_common - Any event in latest_i above such a maximal event lies in E_i ======================================================================