Ltac use_rdestruct_rstep m n :=
  let H := fresh in
  intro H;
  pattern m, n;
  eapply (rdestruct_rstep m n);
  [ .. | eexact H].Hint Extern 40 (RStep _ (_ (match ?m with _=>_ end) (match ?n with _=>_ end))) =>
  use_rdestruct_rstep m n : typeclass_instances.Ltac rdestruct_remember :=
  lazymatch goal with
    | _ : rdestruct_remember |- _ =>
      idtac
    | _ =>
      let H := fresh "Hrdestruct" in
      pose proof rdestruct_remember_intro as H
  end.(** ** Choosing to discard or keep equations *)

(** The [RStep] above will leave us with a bunch of [rdestruct_result]
  subgoals. The next [RStep] will unpack them, and either discard or
  keep equations.

  By default, we discard equations. This is to prevent them from
  cluttering the context, possibly interfering with further steps, and
  introducing unwanted dependencies. However, the user can use the
  [rdestruct_remember] and [rdestruct_forget] tactics below to control
  this behavior. *)

CoInductive rdestruct_remember := rdestruct_remember_intro.Ltac rdestruct_forget :=
  lazymatch goal with
    | H : rdestruct_remember |- _ =>
      clear H
    | _ =>
      idtac
  end.

(* Specifications: *)
Lemma rdestruct_forget_rintro {A B} m n (Q: rel A B) x y: RIntro (Q x y) (rdestruct_result m n Q) x y.
Lemma rdestruct_remember_rintro {A B} m n (Q: rel A B) x y: RIntro (m = x -> n = y -> Q x y) (rdestruct_result m n Q) x y.