Section Examples.
Example IR_equiv_eg1 :
forall k k',
k <> k' ->
IR_equivalent [IRI k; IRI k'; IRO k; IRO k'] [IRI k; IRO k; IRI k'; IRO k'].
Proof using.
intros.
constructor.
econstructor; auto.
red.
intuition (auto; congruence).
Qed.
Example IR_equiv_eg2 :
forall k k',
k <> k' ->
IR_equivalent [IRI k; IRI k'; IRO k; IRO k'] [IRI k'; IRO k'; IRI k; IRO k].
Proof using.
intros.
eapply IR_equiv_trans with (l2 := [IRI k; IRI k'; IRO k'; IRO k]).
- repeat constructor; unfold good_move; intuition (try congruence).
- eapply IR_equiv_trans with (l2 := [IRI k'; IRI k; IRO k'; IRO k]).
+ apply IR_equiv_move; auto using IR_equivalent_refl.
red. intuition congruence.
+ constructor. apply IR_equiv_move; auto.
red. intuition congruence.
Qed.
Example IR_equiv_eg3 :
forall k k',
k <> k' ->
IR_equivalent [IRI k; IRI k'; IRO k'; IRO k] [IRI k'; IRO k'; IRI k; IRO k].
Proof using.
intros.
eapply IR_equiv_trans with (l2 := [IRI k'; IRI k; IRO k'; IRO k]).
- constructor.
+ apply IR_equivalent_refl.
+ red. intuition congruence.
- constructor. constructor.
+ apply IR_equivalent_refl.
+ red. intuition congruence.
Qed.
Example IR_equiv_eg4 :
forall k k',
k <> k' ->
IR_equivalent [IRI k; IRI k'; IRO k'; IRO k] [IRI k; IRO k; IRI k'; IRO k'].
Proof using.
intros.
constructor.
eapply IR_equiv_trans with (l2 := [IRI k'; IRO k; IRO k']).
- repeat constructor; unfold good_move; intuition congruence.
- eapply IR_equiv_move; auto.
red. intuition congruence.
Qed.
End Examples.
Fixpoint good_trace (l : list IR) : Prop :=
match l with
| [] => True
| IRI k :: IRO k' :: l' => k = k' /\ good_trace l'
| IRI k :: IRU k' :: l' => k = k' /\ good_trace l'
| _ => False
end.
Definition equivalent (l : list op) (ir : list IR) : Prop :=
good_trace ir /\
exists ir',
acknowledge_all_ops l ir' /\
IR_equivalent ir' ir.
Proof using.
induction l; intros; simpl in *; repeat break_match; subst; simpl in *;
intuition (eauto; congruence).
Qed.
Definition get_op_input_keys (l : list op) : list K :=
filterMap (fun x => match x with
| I k => Some k
| _ => None
end) l.
Proof using.
unfold get_op_input_keys.
intros.
simpl. repeat break_match; congruence.
Qed.
Definition get_IR_input_keys (l : list IR) : list K :=
filterMap (fun x => match x with
| IRI k => Some k
| _ => None
end) l.
Proof using.
unfold get_IR_input_keys.
intros.
simpl. repeat break_match; congruence.
Qed.
Definition get_op_output_keys (l : list op) : list K :=
filterMap (fun x => match x with
| O k => Some k
| _ => None
end) l.
Proof using.
unfold get_op_output_keys.
intros.
simpl.
repeat break_match; congruence.
Qed.
Definition get_IR_output_keys (l : list IR) : list K :=
filterMap (fun x => match x with
| IRO k => Some k
| IRU k => Some k
| _ => None
end) l.
Proof using.
unfold get_IR_output_keys.
intros. simpl. repeat break_match; congruence.
Qed.
(* this is cleaner than the auto-generated functional induction scheme *)
Fixpoint good_trace_ind'
(P : list IR -> Prop -> Prop)
(l : list IR) :
P [] True ->
(forall k, P [IRI k] False) ->
(forall k k' l, P (IRI k :: IRI k' :: l) False) ->
(forall k k' l, P l (good_trace l) -> P (IRI k :: IRO k' :: l) (k = k' /\ good_trace l)) ->
(forall k k' l, P l (good_trace l) -> P (IRI k :: IRU k' :: l) (k = k' /\ good_trace l)) ->
(forall k l, P (IRO k :: l) False) ->
(forall k l, P (IRU k :: l) False) ->
P l (good_trace l).
Proof using.
intros.
destruct l; simpl; repeat break_match; auto; subst.
- match goal with
| [ H : context [IRI _ :: IRO _ :: _ ] |- _ ] => apply H
end.
apply good_trace_ind'; auto.
- match goal with
| [ H : context [IRI _ :: IRU _ :: _ ] |- _ ] => apply H
end.
apply good_trace_ind'; auto.
Qed.
Proof using.
intros.
apply good_trace_ind'; auto.
Qed.
Proof using.
intros ir.
induction ir, good_trace using good_trace_ind; intros; simpl in *; intuition (auto; try congruence).
- subst. find_apply_hyp_hyp. intuition.
- subst. find_apply_hyp_hyp. intuition.
Qed.
Proof using.
induction l; intros; simpl in *.
- auto.
- repeat break_match; subst; unfold acknowledged_op in *;
(exfalso + idtac); solve [intuition eauto].
Qed.
Proof using.
intros. destruct x. eauto.
eapply_prop_hyp In In; eauto.
simpl in *. intuition congruence.
Qed.
Proof using.
red. intuition congruence.
Qed.
Proof using.
red. intuition congruence.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
apply IR_equiv_trans with (l2 := (a :: IRI k :: l)).
- auto.
- specialize (H a). concludes. break_exists. subst.
auto using IR_equivalent_refl, good_move_II.
Qed.
Definition good_op_move (x y : op) : Prop :=
(forall k k', ~ (x = O k /\ y = I k')) /\
(forall k, ~ (x = I k /\ y = O k)).
Inductive op_equivalent : list op -> list op -> Prop :=
| op_equiv_nil : op_equivalent [] []
| op_equiv_cons : forall x xs ys, op_equivalent xs ys -> op_equivalent (x :: xs) (x :: ys)
| op_equiv_move : forall x y xs ys, good_op_move x y ->
op_equivalent xs ys -> op_equivalent (x :: y :: xs) (y :: x :: ys)
| op_equiv_trans : forall l1 l2 l3, op_equivalent l1 l2 -> op_equivalent l2 l3 -> op_equivalent l1 l3.
Proof using.
induction 1; eauto.
Qed.
Proof using.
unfold acknowledged_op.
intros.
eauto using Permutation_in, op_equiv_Permutation.
Qed.
Proof using.
unfold acknowledged_op.
intros.
eauto using Permutation_sym, Permutation_in, op_equiv_Permutation.
Qed.
Proof using.
auto.
Qed.
Proof using.
red. intuition congruence.
Qed.
Proof using.
red. intuition congruence.
Qed.
Proof using.
red. intuition congruence.
Qed.
Hint Resolve IR_equivalent_refl : core.
Hint Resolve good_move_II : core.
Hint Resolve good_move_U_l : core.
Proof using.
unfold good_op_move.
intuition eauto.
Qed.
Proof using.
unfold good_op_move.
intuition eauto.
Qed.
Proof using.
unfold good_op_move, good_move.
intuition (try congruence). repeat find_inversion. eauto.
Qed.
Proof using.
unfold good_op_move. intros.
destruct x as [k|k], y as [k'|k']; exists k, k'; intuition.
- right. right. intuition. subst. eauto.
- exfalso. eauto.
Qed.
Proof using.
unfold acknowledged_op.
simpl. intuition congruence.
Qed.
Proof using.
unfold acknowledged_op.
simpl. intuition congruence.
Qed.
Hint Constructors op_equivalent : core.
Proof using.
intros.
simpl.
repeat break_match; auto;
exfalso; eauto using op_equiv_ack_op_lr, op_equiv_ack_op_rl.
Qed.
Proof using.
intros.
rewrite acknowledge_all_ops_func_defn.
break_if.
- rewrite acknowledge_all_ops_func_defn.
break_if; rewrite acknowledge_all_ops_func_defn with (l := _ :: _).
+ rewrite if_decider_true by
eauto 3 using acknowledged_op_I_cons_expand, op_equiv_ack_op_lr,
acknowledged_op_I_cons_reduce.
rewrite acknowledge_all_ops_func_defn.
rewrite if_decider_true by
eauto 3 using acknowledged_op_I_cons_expand, op_equiv_ack_op_lr,
acknowledged_op_I_cons_reduce.
auto.
+ rewrite if_decider_false with (dec := acknowledged_op_dec _) by
intuition eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite acknowledge_all_ops_func_defn.
rewrite if_decider_true with (dec := acknowledged_op_dec _) by
eauto 3 using acknowledged_op_I_cons_expand, op_equiv_ack_op_lr,
acknowledged_op_I_cons_reduce.
break_if.
* eauto 6 using good_move_IU_neq.
* auto.
- break_if; rewrite acknowledge_all_ops_func_defn.
+ break_if; rewrite acknowledge_all_ops_func_defn.
* rewrite if_decider_true by
eauto 3 using acknowledged_op_I_cons_expand, op_equiv_ack_op_lr,
acknowledged_op_I_cons_reduce.
rewrite acknowledge_all_ops_func_defn.
rewrite if_decider_false by
intuition eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite if_decider_true by auto.
eauto.
* rewrite if_decider_false with (dec := acknowledged_op_dec _) by
eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite acknowledge_all_ops_func_defn.
rewrite if_decider_false with (dec := acknowledged_op_dec _) by
eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite if_decider_true with (dec := in_dec _ (IRU k)) by auto.
{ break_if.
- eapply IR_equiv_trans; [apply IR_equiv_cons; apply IR_equiv_move; auto|].
eapply IR_equiv_trans; [apply IR_equiv_move; auto|]. constructor.
eapply IR_equiv_trans; [apply IR_equiv_cons; apply IR_equiv_move; auto|].
auto using good_move_IU_neq.
- auto.
}
+ break_if; rewrite acknowledge_all_ops_func_defn.
* rewrite if_decider_true with (dec := acknowledged_op_dec _) by
eauto 3 using acknowledged_op_I_cons_expand, op_equiv_ack_op_lr,
acknowledged_op_I_cons_reduce.
rewrite acknowledge_all_ops_func_defn.
rewrite if_decider_false with (dec := acknowledged_op_dec _) by
eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite if_decider_false by auto.
auto.
* rewrite if_decider_false with (dec := acknowledged_op_dec _) by
eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite acknowledge_all_ops_func_defn.
rewrite if_decider_false with (dec := acknowledged_op_dec _) by
eauto using acknowledged_op_I_cons_expand, op_equiv_ack_op_rl,
acknowledged_op_I_cons_reduce.
rewrite if_decider_false with (dec := in_dec _ (IRU k)) by auto.
break_if; auto.
Qed.
Proof using.
induction 1; intros.
- auto.
- simpl.
repeat break_match; subst; auto;
exfalso; eauto using op_equiv_ack_op_lr, op_equiv_ack_op_rl.
- find_copy_apply_lem_hyp good_op_move_cases. break_exists. intuition; subst.
+ destruct (K_eq_dec x0 x1).
* subst. auto using IR_equiv_AAOF_I.
* auto using IR_equiv_AAOF_II_neq.
+ simpl. eauto using good_move_OO.
+ simpl. repeat break_match; intuition; try congruence.
* eauto using good_move_IO_neq.
* exfalso. eauto using op_equiv_ack_op_lr.
* exfalso. eauto using op_equiv_ack_op_lr.
* exfalso; eauto using Permutation_in, op_equiv_Permutation, acknowledged_op_defn, Permutation_sym.
* eapply IR_equiv_trans; [apply IR_equiv_cons; apply IR_equiv_move; auto|].
eapply IR_equiv_trans; [apply IR_equiv_move; auto|]. apply good_move_IO_neq. congruence.
auto.
* exfalso.
match goal with
| [ H : In (O _) _ -> False |- _ ] => apply H
end.
eapply Permutation_in; [apply Permutation_sym; eapply op_equiv_Permutation; eauto|].
auto using acknowledged_op_defn.
- eauto.
Qed.
Proof using.
induction xs; auto.
Qed.
Proof using.
red. intuition congruence.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
apply op_equiv_trans with (l2 := (a :: I k :: l)).
- auto.
- specialize (H a). concludes. break_exists. subst.
auto using op_equivalent_refl, good_op_move_II.
Qed.
Proof using.
unfold good_op_move.
intuition congruence.
Qed.
Proof using.
unfold good_op_move.
intuition congruence.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
apply op_equiv_trans with (l2 := (a :: O k :: l)).
- eauto 10.
- destruct a.
+ eauto 6 using good_op_move_neq_IO, op_equivalent_refl.
+ eauto 6 using good_op_move_OO, op_equivalent_refl.
Qed.
Proof using.
induction 1; intros; simpl in *; intuition.
- auto using op_equivalent_refl.
- eauto.
Qed.
Proof using.
intros.
rewrite app_comm_cons.
replace (xs ++ I k :: ys) with ((xs ++ [I k]) ++ ys) by now rewrite app_ass.
auto using op_equiv_app_tail, op_equivalent_all_Is_I.
Qed.
Proof using.
intros.
apply filterMap_app.
Qed.
Proof using.
intros.
apply filterMap_app.
Qed.
Proof using.
unfold get_op_input_keys.
intros.
eapply filterMap_In; eauto.
auto.
Qed.
Proof using.
induction l; intros.
- auto.
- simpl in *. rewrite get_op_input_keys_defn in *. break_match; simpl in *.
+ subst. intuition congruence.
+ intuition.
Qed.
Proof using.
induction l; intros.
- auto.
- simpl in *. rewrite get_op_output_keys_defn in *. break_match; simpl in *.
+ subst. auto.
+ intuition congruence.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
rewrite get_op_input_keys_defn.
pose proof H a. concludes. break_exists. subst.
auto.
Qed.
Proof using.
intros.
unfold get_op_input_keys.
apply filterMap_NoDup_inj; auto.
intros.
repeat break_match; try discriminate.
subst. congruence.
Qed.
Proof using.
intros.
unfold get_op_output_keys.
apply filterMap_NoDup_inj; auto.
intros.
repeat break_match; try discriminate.
subst. congruence.
Qed.
Proof using.
unfold get_op_input_keys.
intros.
eapply filterMap_In; eauto.
auto.
Qed.
Proof using.
unfold get_IR_output_keys.
intros.
eapply filterMap_In; eauto. auto.
Qed.
Proof using.
unfold get_IR_output_keys.
intros.
eapply filterMap_In; eauto. auto.
Qed.
Proof using.
unfold get_IR_input_keys.
intros.
eapply filterMap_In; eauto. auto.
Qed.
Proof using.
intros.
rewrite app_comm_cons.
replace (xs ++ O k :: ys) with ((xs ++ [O k]) ++ ys) by now rewrite app_ass.
auto using op_equiv_app_tail, op_equivalent_all_Is_O.
Qed.
Proof using.
intros.
rewrite get_op_output_keys_app in *.
rewrite get_op_output_keys_defn in *.
do_in_app.
intuition; eapply NoDup_remove_2; eauto using get_op_output_keys_complete, in_or_app.
Qed.
Proof using.
intros.
rewrite get_op_output_keys_app in *.
rewrite get_op_output_keys_defn in *.
rewrite get_op_output_keys_app in *.
rewrite get_op_output_keys_defn in *.
repeat
(do_in_app; intuition
eauto using NoDup_app3_not_in_1, NoDup_app3_not_in_2,
NoDup_app3_not_in_3, get_op_output_keys_complete).
Qed.
Proof using.
intros.
rewrite get_op_input_keys_app in *.
rewrite get_op_input_keys_defn in *.
rewrite get_op_input_keys_app in *.
rewrite get_op_input_keys_defn in *.
match goal with
| [ H : NoDup _ |- _ ] =>
apply NoDup_remove_2 in H
end.
repeat (do_in_app; intuition); eauto 10 using get_op_input_keys_complete with *.
Qed.
Proof using.
intros.
eapply In_cons_neq.
- eapply In_cons_neq.
+ eauto.
+ discriminate.
- discriminate.
Qed.
Proof using.
intros.
eapply In_cons_neq.
- eapply In_cons_neq.
+ eauto using In_cons_2_3.
+ discriminate.
- intro. find_inversion. eauto using NoDup_get_op_output_keys_In_2_3.
Qed.
Proof using.
intros.
rewrite get_op_input_keys_app in *. rewrite get_op_input_keys_defn in *.
match goal with
| [ H : NoDup (_ ++ _ :: _) |- _ ] =>
apply NoDup_remove_2 in H
end.
rewrite get_op_input_keys_app in *.
intro. subst.
repeat do_in_app; intuition auto 10 using get_op_input_keys_complete, in_or_app.
Qed.
Proof using.
intros.
apply in_middle_reduce with (y := I k'); intuition (auto with *; congruence).
Qed.
Proof using.
intros.
eapply In_cons_2_3_neq; eauto using in_cons; try congruence.
intro. find_inversion. eauto using get_IR_output_keys_complete_O.
Qed.
Proof using.
intros.
apply in_middle_reduce with (y := I k'); intuition.
find_inversion.
auto using get_IR_output_keys_complete_U.
Qed.
Proof using.
intros.
eapply In_cons_2_3_neq; eauto using in_cons; try congruence.
intro. find_inversion. eauto using get_IR_output_keys_complete_U.
Qed.
Proof using.
intros.
rewrite get_op_input_keys_app in *.
rewrite get_op_input_keys_defn in *.
do_in_app.
intuition; eapply NoDup_remove_2; eauto using get_op_input_keys_complete, in_or_app.
Qed.
Proof using.
intros.
simpl in *.
find_eapply_lem_hyp before_middle_insert.
- find_eapply_lem_hyp in_middle_insert.
eapply_prop_hyp In (O k1); eauto.
intuition; try congruence.
- intro. find_inversion. eauto using NoDup_get_op_input_keys_In_I.
Qed.
Proof using.
intros.
simpl in *.
find_copy_eapply_lem_hyp before_2_3_insert.
- find_eapply_lem_hyp In_cons_2_3.
eapply_prop_hyp In (O k1); eauto.
intuition; try congruence.
find_inversion.
find_copy_eapply_lem_hyp before_In.
exfalso.
eauto using NoDup_get_op_output_keys_In_2_3.
- intro. find_inversion. eauto using NoDup_get_op_input_keys_In_2_3.
- discriminate.
Qed.
Proof using.
intros.
eapply before_middle_reduce.
- eauto using in_middle_insert.
- intro. find_inversion. intuition eauto using acknowledged_op_defn.
Qed.

Lemma in_before_preserved :
forall xs ys zs k',
NoDup (get_op_output_keys (xs ++ I k' :: ys ++ O k' :: zs)) ->
(forall k, In (O k) (xs ++ I k' :: ys ++ O k' :: zs) ->
before (I k) (O k) (xs ++ I k' :: ys ++ O k' :: zs)) ->
forall k, In (O k) (xs ++ ys ++ zs) ->
before (I k) (O k) (xs ++ ys ++ zs).