(** ** Correctness invariant *)
(** The following invariant is preserved at each iteration of Kildall's algorithm: for all visited program point [n], either [n] is in the worklist, or the inequations associated with [n] ([aval[s] >= transf n aval[n]] for all successors [s] of [n]) hold.  In other terms, the worklist contains all nodes that were visited but do not yet satisfy their inequations.  The second part of the invariant shows that nodes that already have an abstract value associated with them have been visited. *)
Record good_state (st: state) : Prop := {
gs_stable: forall n,
st.(visited) n ->
NS.In n st.(worklist) \/
(forall i s,
code!n = Some i -> In s (successors i) ->
optge st.(aval)!s (Some (transf n (abstr_value n st))));
gs_defined: forall n v,
st.(aval)!n = Some v -> st.(visited) n
}.
(** We show that the [step] function preserves this invariant. *)

Lemma step_state_good_2:
forall st pc rem,
good_state st ->
NS.pick (worklist st) = Some (pc, rem) ->
code!pc = None ->
good_state (mkstate st.(aval) rem st.(visited)).