Ltac myinv :=
  match goal with
  | [ |- In _ nil -> _ ] => let X := fresh "X" in intro X; elim X
  | [ |- In _ (ret _ _) -> _ ] =>
        let X := fresh "X" in
        intro X; elim X; clear X;
        [let EQ := fresh "EQ" in intro EQ; unfold ret in EQ; inv EQ; myinv | myinv]
  | [ |- In _ (_ :: nil) -> _ ] =>
        let X := fresh "X" in
        intro X; elim X; clear X; [let EQ := fresh "EQ" in intro EQ; inv EQ; myinv | myinv]
  | [ |- In _ (match ?x with Some _ => _ | None => _ end) -> _ ] => destruct x eqn:?; myinv
  | [ |- In _ (match ?x with false => _ | true => _ end) -> _ ] => destruct x eqn:?; myinv
  | [ |- In _ (match ?x with left _ => _ | right _ => _ end) -> _ ] => destruct x; myinv
  | _ => idtac
  end.

(* Specifications: *)
Theorem step_expr_sound: forall a k m, reducts_ok k a m (step_expr k a m) with step_exprlist_sound: forall al m, list_reducts_ok al m (step_exprlist al m).
Lemma step_exprlist_val_list: forall m al, is_val_list al <> None -> step_exprlist al m = nil.
Lemma lred_topred: forall l1 m1 l2 m2, lred ge e l1 m1 l2 m2 -> exists rule, step_expr LV l1 m1 = topred (Lred rule l2 m2).
Lemma rred_topred: forall w' r1 m1 t r2 m2, rred ge r1 m1 t r2 m2 -> possible_trace w t w' -> exists rule, step_expr RV r1 m1 = topred (Rred rule r2 m2 t).
Lemma callred_topred: forall a fd args ty m, callred ge a m fd args ty -> exists rule, step_expr RV a m = topred (Callred rule fd args ty m).