Rain and a sprinkler wet the grass, and wet grass is slippery: 5,000 samples of rain, sprinkler, wet, slippery. One step per test.

  1. G <- the complete undirected graph
  2. for d = 0, 1, 2, … while some node has > d neighbors
  3. adj <- the neighbors in G, fixed for this depth
  4. for each adjacent pair (x, y)
  5. for each S of size d from adj(x) \ {y} or adj(y) \ {x}
  6. p <- test(x, y | S)
  7. if p > α: mark x – y, add S to sepset(x, y), keep the largest p as p(x, y)
  8. remove the marked edges from G
  9. for each unshielded triple x – y – z, highest p(x, z) first
  10. if y ∉ sepset(x, z) and neither y -> x nor y -> z
  11. orient x -> y <- z
  12. apply Meek's rules R1–R3 until nothing changes

Solid ring: the pair tested. Dashed ring: its conditioning set, or the middle of a triple. Faint edge: marked, removed when the depth ends.

Row i, column j is the mark at i on the edge i – j: a bar for a tail, a triangle for an arrowhead; amber undirected, graphite directed.