(** * Properties of the branch map computed using union-find. *)
(** A variant of [record_goto] that also incrementally computes a measure [f: node -> nat] counting the number of [Lnop] instructions starting at a given [pc] that were eliminated. *)
Definition measure_edge (u: U.t) (pc s: node) (f: node -> nat) : node -> nat :=
fun x => if peq (U.repr u s) pc then f x
else if peq (U.repr u x) pc then (f x + f s + 1)%nat
else f x.
Definition record_goto' (uf: U.t * (node -> nat)) (pc: node) (b: bblock) : U.t * (node -> nat) :=
match b with
| Lbranch s :: b' => let (u, f) := uf in (U.union u pc s, measure_edge u pc s f)
| _ => uf
end.
Definition branch_map_correct (c: code) (uf: U.t * (node -> nat)): Prop :=
forall pc,
match c!pc with
| Some(Lbranch s :: b) =>
U.repr (fst uf) pc = pc \/ (U.repr (fst uf) pc = U.repr (fst uf) s /\ snd uf s < snd uf pc)%nat
| _ =>
U.repr (fst uf) pc = pc
end.

Lemma record_gotos'_correct:
forall c,
branch_map_correct c (PTree.fold record_goto' c (U.empty, fun (x: node) => O)).