Proof using.
intros ir.
induction ir, good_trace using good_trace_ind; intros; try solve [simpl in *; intuition].
- rewrite acknowledge_all_ops_func_target_nil; auto.
- start.
eapply IR_equiv_trans.
+ apply op_equiv_AAOF_IR_equiv.
apply op_equivalent_all_Is_I_middle.
intros.
match goal with
| [ H : context [before] |- _ ] => apply H
end.
apply In_app_before; auto using op_eq_dec.
find_rewrite_lem get_op_input_keys_app. rewrite get_op_input_keys_defn in *.
intro. eapply NoDup_remove_2; eauto using in_or_app, get_op_input_keys_complete.
+ repeat rewrite app_ass.
rewrite acknowledge_all_ops_func_defn.
break_if.
* constructor.
{ eapply IR_equiv_trans.
- apply op_equiv_AAOF_IR_equiv.
rewrite <- app_ass.
eauto using op_equivalent_all_Is_O_middle, no_Ik_in_first2.
- simpl. constructor.
rewrite acknowledge_all_ops_func_target_ext with (t' := ir).
+ rewrite app_ass.
apply IHP; auto.
* eauto using O_IRO_preserved.
* eauto using IRO_O_preserved.
* eauto using IRU_I_preserved.
* eauto using IRU_not_O_preserved.
* eauto using in_before_before_preserved.
* eauto using in_before_preserved.
* eauto using IRI_I_preserved.
* eauto using subseq_NoDup, subseq_get_op_input_keys, subseq_2_3.
* eauto using subseq_NoDup, subseq_get_op_output_keys, subseq_2_3.
+ simpl. intuition congruence.
+ intuition.
}
* { break_if.
- simpl in *. intuition (try congruence).
exfalso. eauto using get_IR_output_keys_complete_U.
- exfalso. apply n. red. intuition.
}
- (* IRU case. *)
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 (I k') l) by firstorder;
assert (forall x, before x (I k') l -> exists k, x = I k) by eauto using before_head_op
end;
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.
find_copy_apply_lem_hyp in_split.
break_exists. subst.
eapply IR_equiv_trans.
+ apply op_equiv_AAOF_IR_equiv.
apply op_equivalent_all_Is_I_middle.
intros.
match goal with
| [ H : context [before] |- _ ] => apply H
end.
apply In_app_before; auto using op_eq_dec.
find_rewrite_lem get_op_input_keys_app. rewrite get_op_input_keys_defn in *.
intro. eapply NoDup_remove_2; eauto using in_or_app, get_op_input_keys_complete.
+ rewrite acknowledge_all_ops_func_defn.
break_if.
* exfalso.
intuition eauto using in_middle_insert, in_cons, in_eq, acknowledged_op_defn.
* rewrite if_decider_true by intuition.
{ constructor. constructor.
rewrite acknowledge_all_ops_func_target_ext_strong with (t' := ir).
- apply IHP; auto.
+ eauto using O_IRO_preserved_IU.
+ eauto using IRO_O_preserved_IU.
+ eauto using IRU_I_preserved_IU.
+ eauto using IRU_not_O_preserved_IU.
+ eauto using in_before_before_preserved_IU.
+ eauto using in_before_preserved_IU.
+ eauto using IRI_I_preserved_IU.
+ eauto using subseq_NoDup, subseq_get_op_input_keys, subseq_middle.
+ eauto using subseq_NoDup, subseq_get_op_output_keys, subseq_middle.
- simpl. intuition (try congruence ). find_inversion.
rewrite get_op_input_keys_app in *. rewrite get_op_input_keys_defn in *.
exfalso.
repeat match goal with
| [ H : In ?x (_ ++ ?x :: _) |- _ ] => clear H
| [ H : In ?x (_ ++ _ :: _ ++ ?x :: _) |- _ ] => clear H
end.
do_in_app.
eapply NoDup_remove_2; intuition eauto using in_or_app, get_op_input_keys_complete.
- intros. simpl. intuition.
}
Qed.

(* Specifications: *)
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.