Make edges into proper objects

Edges are now always pairs (lists) of two nodes. This lets us talk about edges specifically, and also provides a natural syntax with the `list` reporter. The critical path algorithm example has been updated accordingly.