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.

Lemma before_head_op :
forall l h ir,
(forall k1 k2,
In (I k2) l ->
before (O k1) (I k2) l ->
before (IRO k1) (IRI k2) (IRI h :: ir)) ->
forall x,
In (I h) l ->
before x (I h) l ->
exists k,
x = I k.