End Kildall.
End Dataflow_Solver.
(** * Solving backward dataflow problems using Kildall's algorithm *)
(** A backward dataflow problem on a given flow graph is a forward dataflow program on the reversed flow graph, where predecessors replace successors.  We exploit this observation to cheaply derive a backward solver from the forward solver. *)
(** ** Construction of the reversed flow graph (the predecessor relation) *)
Definition successors_list (successors: PTree.t (list positive)) (pc: positive) : list positive :=
match successors!pc with None => nil | Some l => l end.
Notation "a !!! b" := (successors_list a b) (at level 1).
Section Predecessor.
Context {A: Type}.
Variable code: PTree.t A.
Variable successors: A -> list positive.
Fixpoint add_successors (pred: PTree.t (list positive))
(from: positive) (tolist: list positive)
{struct tolist} : PTree.t (list positive) :=
match tolist with
| nil => pred
| to :: rem => add_successors (PTree.set to (from :: pred!!!to) pred) from rem
end.

(* Specifications: *)
Lemma add_successors_correct:
forall tolist from pred n s,
In n pred!!!s \/ (n = from /\ In s tolist) ->
In n (add_successors pred from tolist)!!!s.