End Solver.
End BBlock_solver.
(** ** Node sets *)
(** We now define implementations of the [NODE_SET] interface appropriate for forward and backward dataflow analysis. As mentioned earlier, we aim for a traversal of the CFG nodes in reverse postorder (for forward analysis) or postorder (for backward analysis).  We take advantage of the following fact, valid for all CFG generated by translation from Cminor: the enumeration [n-1], [n-2], ..., 3, 2, 1 where [n] is the top CFG node is a reverse postorder traversal. Therefore, for forward analysis, we will use an implementation of [NODE_SET] where the [pick] operation selects the greatest node in the working list.  For backward analysis, we will similarly pick the smallest node in the working list. *)
Module NodeSetForward <: NODE_SET.
Definition t := PHeap.t.
Definition empty := PHeap.empty.
Definition add (n: positive) (s: t) : t := PHeap.insert n s.
Definition pick (s: t) :=
match PHeap.findMax s with
| Some n => Some(n, PHeap.deleteMax s)
| None => None
end.
Definition all_nodes {A: Type} (code: PTree.t A) :=
PTree.fold (fun s pc instr => PHeap.insert pc s) code PHeap.empty.
Definition In := PHeap.In.

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