Concurrency Theory: Lecture 13, 7 March 2017 -------------------------------------------- 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 ---------- Digression: Constructing t_w = (E_w, <=, lab) from a word w over (Act,I) - For each a in Act, if a occurs k_a times in w, create events (a,1), (a,2), ..., (a,k_a) - E_w is the set of such events - lab((a,i)) = a - Build up <= incrementally - Assume w = a_1 a_2 ... a_m and we have constructed the trace for a prefix a_1 a_2 ... a_i. - a_{i+1} is (b,j) for some letter b and some j in {1,...,k_b}. - append (b,j), connected to all current maximal events whose labels are dependent on b. ---------- 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.) ======================================================================