Section remove_all.
Variable A : Type.
Hypothesis A_eq_dec : forall x y : A, {x = y} + {x <> y}.
Fixpoint remove_all (to_delete l : list A) : list A :=
match to_delete with
| [] => l
| d :: ds => remove_all ds (remove A_eq_dec d l)
end.
Proof using.
induction ds; intros; simpl in *; intuition.
eauto using in_remove.
Qed.
Proof using.
induction ds; intros; simpl in *; intuition auto using remove_preserve.
Qed.
Proof using.
induction ds; intros; simpl in *; intuition.
- subst. find_apply_lem_hyp in_remove_all_was_in.
eapply remove_In; eauto.
- eauto.
Qed.
Proof using.
intros. induction ys; simpl in *; intuition.
Qed.
Proof using.
induction ys; intros; simpl in *; intuition.
break_if; subst; simpl in *; intuition.
specialize (IHys a0 (remove A_eq_dec a l)). intuition.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
- rewrite remove_all_nil in *. simpl in *. intuition.
- pose proof remove_all_cons ys a l. intuition.
+ repeat find_rewrite. right. intuition eauto.
subst; intuition.
+ repeat find_rewrite. simpl in *. intuition eauto.
Qed.
Proof using.
induction l; intros; simpl in *; intuition;
pose proof remove_all_cons xs a l; subst; intuition;
repeat find_rewrite; simpl in *; intuition.
Qed.
Proof using.
intros.
induction l'.
- rewrite remove_all_nil; auto.
- invc_NoDup.
concludes.
pose proof remove_all_cons l a l'.
break_or_hyp; break_and; find_rewrite; auto.
constructor; auto.
intro.
find_apply_lem_hyp in_remove_all_was_in; auto.
Qed.
Proof using.
induction l'; intros; simpl in *.
- find_rewrite_lem remove_all_nil.
destruct l0; simpl in *; match goal with H: [] = _ |- _ => contradict H end; auto using nil_cons.
- invc_NoDup.
break_if; subst.
* rewrite remove_not_in; auto.
pose proof remove_all_cons l a l'.
break_or_hyp; break_and.
+ find_rewrite.
match goal with H0: NoDup _, H1: _ = remove_all _ _ |- _ => specialize (IHl' _ _ _ H0 (eq_sym H1)) end.
rewrite remove_not_in in IHl'; auto.
+ destruct l0; simpl in *; find_rewrite; find_injection; auto.
assert (In a (remove_all l l')).
match goal with H: _ = remove_all _ _ |- _ => rewrite <- H end.
apply in_or_app.
right; left; auto.
find_apply_lem_hyp in_remove_all_was_in.
intuition.
* pose proof remove_all_cons l a l'.
break_or_hyp; break_and; find_rewrite.
+ pose proof remove_all_cons l a (remove A_eq_dec a0 l').
break_or_hyp; break_and; intuition.
aggressive_rewrite_goal; auto.
+ destruct l0; simpl in *; find_injection; intuition.
match goal with H0: NoDup _, H1: _ = remove_all _ _ |- _ => specialize (IHl' _ _ _ H0 (eq_sym H1)) end.
rewrite <- IHl'.
pose proof remove_all_cons l a (remove A_eq_dec a0 l').
break_or_hyp; break_and; intuition.
Qed.
Proof using.
induction zs; intros.
- now repeat rewrite remove_all_nil.
- pose proof (remove_all_cons (xs ++ ys) a zs).
pose proof (remove_all_cons ys a zs).
pose proof (remove_all_cons xs a (remove_all ys zs)).
repeat (break_or_hyp; break_and); repeat find_rewrite;
try find_eapply_lem_hyp in_app_or;
try assert (In a (xs ++ ys)) by (eapply in_or_app; eauto);
tauto.
Qed.

Lemma remove_all_app_r :
forall xs ys zs,
remove_all xs (ys ++ zs) = remove_all xs ys ++ remove_all xs zs.