(** ** Relational characterization of the code transformation *)
(** The [is_return_spec] characterizes the instruction sequences recognized by the [is_return] boolean function.  *)
Inductive is_return_spec (f:function): node -> reg -> Prop :=
| is_return_none: forall pc r,
f.(fn_code)!pc = Some(Ireturn None) ->
is_return_spec f pc r
| is_return_some: forall pc r,
f.(fn_code)!pc = Some(Ireturn (Some r)) ->
is_return_spec f pc r
| is_return_nop: forall pc r s,
f.(fn_code)!pc = Some(Inop s) ->
is_return_spec f s r ->
(return_measure f.(fn_code) s < return_measure f.(fn_code) pc)%nat ->
is_return_spec f pc r
| is_return_move: forall pc r r' s,
f.(fn_code)!pc = Some(Iop Omove (r::nil) r' s) ->
is_return_spec f s r' ->
(return_measure f.(fn_code) s < return_measure f.(fn_code) pc)%nat ->
is_return_spec f pc r.

Lemma is_return_charact:
forall f n pc rret,
is_return n f pc rret = true -> (n <= niter)%nat ->
is_return_spec f pc rret.