Section dedup.
Variable A : Type.
Hypothesis A_eq_dec : forall x y : A, {x = y} + {x <> y}.
Fixpoint dedup (xs : list A) : list A :=
match xs with
| [] => []
| x :: xs => let tail := dedup xs in
if in_dec A_eq_dec x xs then
tail
else
x :: tail
end.
Proof using.
intros. simpl in *.
break_match.
+ auto.
+ exfalso. intuition.
Qed.
Proof using.
induction xs; intros; simpl in *.
- intuition.
- break_if; intuition; subst; simpl; auto.
Qed.
Proof using.
intros.
induction xs; simpl; repeat (break_match; simpl);
auto using f_equal2; try discriminate.
+ exfalso. apply n. apply in_app_iff. apply in_app_or in i. intuition.
+ exfalso. apply n. apply in_app_or in i. intuition.
* simpl in *. intuition. congruence.
Qed.
Proof using.
intros. induction xs; simpl; auto.
repeat break_match.
- apply IHxs.
intros. apply H; intuition.
- exfalso. specialize (H a a).
apply H; intuition.
do_in_app. intuition.
- exfalso. apply n. intuition.
- simpl. f_equal.
apply IHxs.
intros. apply H; intuition.
Qed.
Proof using.
induction xs; intros; simpl in *.
- intuition.
- break_if; simpl in *; intuition.
Qed.
Proof using.
induction xs; simpl.
- constructor.
- break_if; auto.
constructor; auto.
intro.
apply n.
eapply in_dedup_was_in; eauto.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl. repeat (break_match; simpl); auto using f_equal.
+ exfalso. apply n0. apply remove_preserve; auto.
+ exfalso. apply n. eapply in_remove; eauto.
Qed.
Proof using.
intros xs p ys xs' ys' H.
f_apply H (remove A_eq_dec p).
rewrite remove_dedup_comm, remove_partition in *.
find_rewrite.
rewrite remove_partition.
apply remove_not_in.
apply NoDup_remove_2.
rewrite <- H.
apply NoDup_dedup.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl. invc_NoDup. concludes.
break_if; congruence.
Qed.

Lemma dedup_not_in_cons :
forall x xs,
(~ In x xs) ->
x :: dedup xs = dedup (x :: xs).