Ltac start :=
    match goal with
      | [ H : good_trace (_ :: _) |- _ ] => simpl in H
    end;
    break_and; subst;
    match goal with
      | [ H : context [In (?c _) (_ :: ?c ?k' :: _) -> In _ ?l] |- _ ] =>
        assert (In (O k') l) by firstorder;
          assert (before (I k') (O k') l) by auto;
          repeat rewrite get_IR_input_keys_defn in *;
          repeat rewrite get_IR_output_keys_defn in *;
          repeat match goal with
                   | [ H : NoDup (_ :: _) |- _ ] => invc H
                 end;
          assert (In (I k') l) by eauto using before_In;
          assert (forall x, before x (I k') l -> exists k, x = I k) by eauto using before_head_op;
          find_copy_apply_lem_hyp before_split; auto; try congruence; break_exists; subst
    end;
    repeat match goal with
             | [ H : In ?x (_ ++ ?x :: _) |- _ ] => clear H
             | [ H : In ?x (_ ++ _ :: _ ++ ?x :: _) |- _ ] => clear H
           end.

Theorem equivalent_intro : forall l ir, good_trace ir -> (forall k, In (O k) l -> In (IRO k) ir) -> (forall k, In (IRO k) ir -> In (O k) l) -> (forall k, In (IRU k) ir -> In (I k) l) -> (forall k k', In (I k') l -> before (O k) (I k') l -> before (IRO k) (IRI k') ir) -> (forall k, In (O k) l -> before (I k) (O k) l) -> (forall k, In (IRU k) ir -> ~ In (O k) l) -> NoDup (get_op_input_keys l) -> NoDup (get_IR_input_keys ir) -> NoDup (get_op_output_keys l) -> NoDup (get_IR_output_keys ir) -> equivalent l ir.