Inductive wf_move: reg -> reg -> Prop :=
  | wf_move_same: forall s d,
      In (s, d) initial_move -> wf_move s d
  | wf_move_temp_left: forall s d,
      wf_move s d -> wf_move (temp s) d
  | wf_move_temp_right: forall s d,
      wf_move s d -> wf_move s (temp s).Inductive wf_move: reg -> reg -> Prop :=
  | wf_move_same: forall s d,
      In (s, d) initial_move -> wf_move s d
  | wf_move_temp_left: forall s d,
      wf_move s d -> wf_move (temp s) d
  | wf_move_temp_right: forall s d,
      wf_move s d -> wf_move s (temp s).Inductive wf_move: reg -> reg -> Prop :=
  | wf_move_same: forall s d,
      In (s, d) initial_move -> wf_move s d
  | wf_move_temp_left: forall s d,
      wf_move s d -> wf_move (temp s) d
  | wf_move_temp_right: forall s d,
      wf_move s d -> wf_move s (temp s).Inductive wf_move: reg -> reg -> Prop :=
  | wf_move_same: forall s d,
      In (s, d) initial_move -> wf_move s d
  | wf_move_temp_left: forall s d,
      wf_move s d -> wf_move (temp s) d
  | wf_move_temp_right: forall s d,
      wf_move s d -> wf_move s (temp s).Definition wf_moves (m: moves) : Prop :=
  forall s d, In (s, d) m -> wf_move s d.

(* Specifications: *)
Lemma wf_moves_cons: forall s d m, wf_moves ((s, d) :: m) <-> wf_move s d /\ wf_moves m.
Lemma wf_moves_append: forall m1 m2, wf_moves (m1 ++ m2) <-> wf_moves m1 /\ wf_moves m2.
Lemma wf_moves_cons: forall s d m, wf_moves ((s, d) :: m) <-> wf_move s d /\ wf_moves m.
Lemma wf_moves_append: forall m1 m2, wf_moves (m1 ++ m2) <-> wf_moves m1 /\ wf_moves m2.