Section Update2Rel.
Variables A B : Type.
Variable R : relation A.
Hypothesis A_eq_dec : forall x y : A, {x = y} + {x <> y}.
Hypothesis R_dec : forall x y : A, {R x y} + {~ R x y}.
Proof using.
intros.
induction ns; simpl in *; [ intuition | idtac ].
break_if; simpl in *.
- break_or_hyp; auto.
concludes.
break_and.
auto.
- concludes.
break_and.
auto.
Qed.
Proof using.
intros.
induction ns; simpl in *; [ intuition | idtac ].
break_if.
- break_or_hyp.
* left; auto.
* concludes.
right; auto.
- break_or_hyp.
* intuition.
* concludes.
assumption.
Qed.
Proof using.
induction ns; intros; auto.
assert (H_neq: a <> n).
intro.
subst.
auto with datatypes.
assert (H_not_in: ~ In n ns).
intro.
intuition auto with datatypes.
simpl.
break_if; auto.
simpl.
intro.
break_or_hyp; auto.
intuition eauto.
Qed.
Proof using.
intros.
induction ns; auto.
invc_NoDup.
concludes.
simpl in *.
break_if; auto.
apply NoDup_cons; auto.
apply not_in_not_in_filter_rel.
assumption.
Qed.
Proof using.
induction ns0; intros; simpl in *.
- break_if; auto.
find_apply_lem_hyp irreflexive_R.
intuition.
- break_if; auto.
find_higher_order_rewrite.
trivial.
Qed.
Proof using.
intros f g h n n' l.
generalize f g; clear f g.
induction l; auto.
intros.
simpl in *.
break_let.
destruct a.
find_injection.
set (f' := update2 _ _ _ _ _).
set (g' := update2 _ _ _ _ _).
rewrite (IHl f' g'); auto.
unfold f', g', update2.
break_if; auto.
break_and.
subst.
find_rewrite.
trivial.
Qed.
Proof using.
induction l; intros; auto.
destruct a.
apply IHl.
unfold update2.
break_if; auto.
break_and.
subst.
apply in_or_app.
left.
assumption.
Qed.
Proof using.
induction l; intros; auto.
destruct a.
simpl.
apply IHl.
unfold update2.
break_if; auto.
break_and; subst.
destruct (f n' n); auto.
find_apply_lem_hyp hd_error_some_nil.
intuition.
Qed.
Proof using.
intros.
revert f.
induction ns; intros; auto.
destruct a.
simpl in *.
rewrite IHns.
unfold update2.
break_if; auto.
break_and; subst.
intuition.
Qed.
Proof using.
intros.
revert f.
induction l; intros; auto.
simpl in *.
break_let.
destruct a.
find_injection.
rewrite IHl; unfold update2.
- break_if.
* break_and; subst.
simpl in *.
contradict H.
left.
trivial.
* intros.
trivial.
- intro.
contradict H.
right.
assumption.
Qed.
Proof using.
induction l1; intros; auto.
simpl.
break_let.
destruct a.
find_injection.
rewrite IHl1.
trivial.
Qed.
Proof using.
intros.
assert (H_eq: update2 A_eq_dec f h n ms h h' =  f h h').
unfold update2.
break_if; auto.
break_and; subst.
intuition.
rewrite (collate_f_eq _ _ _ _ _ _ H_eq).
trivial.
Qed.
Proof using.
intros.
rewrite collate_app.
revert f.
induction l1; intros; simpl in *; auto.
break_let.
rewrite IHl1.
- destruct a.
find_injection.
simpl in *.
assert (H_neq: a0 <> h').
intro.
contradict H.
left.
trivial.
rewrite collate_neq_update2; trivial.
- intro.
contradict H.
right.
trivial.
Qed.
Proof using.
intros.
rewrite collate_app.
revert f.
induction l2; intros; simpl in *; auto.
break_let.
subst_max.
simpl in *.
assert (H_neq: a0 <> h'); auto.
rewrite collate_neq_update2; auto.
Qed.

Lemma collate_not_in_mid :
forall h h' l1 l2 (f : A -> A -> list B) m,
~ In h (map fst (l1 ++ l2)) ->
collate A_eq_dec h' (update2 A_eq_dec f h' h (f h' h ++ [m])) (l1 ++ l2) = collate A_eq_dec h' f (l1 ++ (h, m) :: l2).