/** * AsyncSpanningTree * -- compute the parent relation * adapted from N. Lynch, p. 496 */ type Pid; var parent: [Pid] Pid; var reported: [Pid] bool; procedure Main () { var root: Pid; assume (forall p: Pid :: reported[p] == false); call {:async} search (root, root); return; } procedure search (this: Pid, sender: Pid) { var neighbor: Pid; if (! reported[this]) { // BUG: this should be done synchronously // so that when the message comes back we // don't continue to propagate. call parent (this, sender); while (*) { havoc neighbor; assume neighbor != this; assume neighbor != sender; call {:async} search (neighbor, this); } } return; } procedure parent (this: Pid, p: Pid) { parent[this] := p; reported[this] := true; return; }