// L = number of levels in the tree. // By default, use a tree tall enough to contain all three types of processes. constant L := 3; variable x[(2^L-1)] < 3; process Root[i < 1] { read: x[1]; read: x[2]; write: x[0]; (future & silent) (x[0] != x[1] && x[0] != x[2]) ; } process P[j < (2^(L-1)-2)] { let i := j + 1; let parent_idx := (i-1)/2; let left_idx := 2*(i+1)-1; let right_idx := 2*(i+1); read: x[parent_idx]; read: x[left_idx]; read: x[right_idx]; write: x[i]; (future & silent) (x[parent_idx] != x[i] && x[i] != x[left_idx] && x[i] != x[right_idx]) ; puppet action: ( x[i]==x[parent_idx] --> x[i]:=x[i]+1; ) ; } process Leaf[j < (2^(L-1))] { let i := j + (2^(L-1)-1); let parent_idx := (i-1)/2; read: x[parent_idx]; write: x[i]; puppet action: ( x[i]==x[parent_idx] --> x[i]:=x[i]+1; ) ; }