(*** *** The actual tactic *)

(** Often, the target hypotheses declared using the [Transport] class
  have existential quantifiers, and need to be broken up to get to the
  actual relational hypotheses we're interested in. The [split_hyp]
  tactic does that. We also use that opportunity to split up
  [prod_rel] and [rel_incr] when appropriate. For [prod_rel] this is
  especially useful when [rel_curry] is involved. Likewise we
  generally want to split up [rel_incr] as soon as possible, so that
  the existentially quantified world therein can be used to
  instantiate evars that have been spawned from that point on.

  As a generally useful complement, the [split_hyps] tactic applies
  the same process to all hypotheses. *)

Ltac split_hyp H :=
  lazymatch type of H with
    | ex _ =>
      destruct H as [? H];
      split_hyp H
    | _ /\ _ =>
      let H1 := fresh in
      let H2 := fresh in
      destruct H as [H1 H2];
      split_hyp H1;
      split_hyp H2
    | prod_rel ?Rx ?Ry (?x1, ?y1) (?x2, ?y2) =>
      change (Rx x1 x2 /\ Ry y1 y2) in H;
      split_hyp H
    | rel_incr ?acc ?R ?w ?x ?y =>
      let w' := fresh w "'" in
      let Hw' := fresh "H" w' in
      destruct H as (w' & Hw' & H);
      split_hyp H
    | klr_diam ?l ?R ?w ?x ?y =>
      let w' := fresh w "'" in
      let Hw' := fresh "H" w' in
      destruct H as (w' & Hw' & H);
      split_hyp H
    | prod_klr ?Rx ?Ry ?w (?x1, ?y1) (?x2, ?y2) =>
      change (Rx w x1 x2 /\ Ry w y1 y2) in H;
      split_hyp H
    | _ =>
      idtac
  end.Ltac split_hyps :=
  repeat
    lazymatch goal with
      | H: ex _ |- _ =>
        destruct H
      | H: _ /\ _ |- _ =>
        destruct H
      | H: prod_rel ?Rx ?Ry (?x1, ?y1) (?x2, ?y2) |- _ =>
        change (Rx x1 x2 /\ Ry y1 y2) in H
      | H: klr_diam ?R ?w ?x ?y |- _ =>
        let w' := fresh w "'" in
        let Hw' := fresh "H" w' in
        destruct H as (w' & Hw' & H)
      | H: prod_klr ?Rx ?Ry ?w (?x1, ?y1) (?x2, ?y2) |- _ =>
        change (Rx w x1 x2 /\ Ry w y1 y2) in H
    end.

Lemma transport_in_goal `{Transport} `{!RAuto (R a b)} `{!Unconvertible a b}: forall (Q: Prop), (PB -> Q) -> (PA -> Q).