End DATAFLOW_SOLVER.
(** Kildall's algorithm manipulates worklists, which are sets of CFG nodes equipped with a ``pick next node to examine'' operation. The algorithm converges faster if the nodes are chosen in an order consistent with a reverse postorder traversal of the CFG. For now, we parameterize the dataflow solver over a module that implements sets of CFG nodes. *)
Module Type NODE_SET.
Parameter t: Type.
Parameter empty: t.
Parameter add: positive -> t -> t.
Parameter pick: t -> option (positive * t).
Parameter all_nodes: forall {A: Type}, PTree.t A -> t.
Parameter In: positive -> t -> Prop.

(* Specifications: *)
Axiom empty_spec:
forall n, ~In n empty.
Axiom add_spec:
forall n n' s, In n' (add n s) <-> n = n' \/ In n' s.
Axiom pick_none:
forall s n, pick s = None -> ~In n s.
Axiom pick_some:
forall s n s', pick s = Some(n, s') ->
forall n', In n' s <-> n = n' \/ In n' s'.
Axiom all_nodes_spec:
forall A (code: PTree.t A) n instr,
code!n = Some instr -> In n (all_nodes code).