Section list_util.
Variables A B C : Type.
Hypothesis A_eq_dec : forall x y : A, {x = y} + {x <> y}.
Proof using.
intuition.
symmetry in H.
induction l;
now inversion H.
Qed.
Proof using.
induction xs; intros.
- intuition.
- simpl in *.
concludes.
intuition; break_if; subst; try congruence; intuition.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl in *. break_if; simpl in *; intuition.
Qed.
Proof using.
induction xs; intros; simpl; break_if; congruence.
Qed.
Proof using.
intros. induction xs; simpl in *; try break_if; intuition congruence.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl. rewrite IHxs. break_if; auto.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl. rewrite H by intuition. rewrite IHxs by intuition. auto.
Qed.
Proof using.
induction xs; intros.
- constructor.
- simpl. invc_NoDup. constructor.
+ intro. do_in_map.
assert (x = a) by intuition.
congruence.
+ intuition.
Qed.
Proof using.
induction l; intros.
- auto.
- simpl. invc_NoDup. constructor.
+ intro. do_in_app. intuition eauto with *.
+ intuition eauto with *.
Qed.
Proof using.
induction xs; simpl; intros; destruct xs'.
- auto.
- subst. simpl in *. find_inversion.
invc H. exfalso. rewrite map_app in *. simpl in *.
repeat find_rewrite. intuition.
- subst. simpl in *. find_inversion.
invc H. exfalso. rewrite map_app in *. simpl in *.
repeat find_rewrite. intuition.
- subst. simpl in *. find_injection. intros. subst.
f_equal. eapply IHxs; eauto. solve_by_inversion.
Qed.
Proof using.
induction l; intros.
- auto.
- invc_NoDup. simpl. break_if; auto.
constructor; auto.
intro. apply filter_In in H. intuition.
Qed.
Proof using.
intros. induction l; simpl in *.
- constructor.
- invc_NoDup. concludes.
break_if; simpl in *; auto.
constructor; auto.
intro. do_in_map.
find_apply_lem_hyp filter_In. intuition.
match goal with | H : _ -> False |- False => apply H end.
apply in_map_iff. eauto.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl. now rewrite H, IHxs by intuition.
Qed.
Proof using.
induction xs; simpl; auto using f_equal2.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl.
break_if.
+ subst. repeat find_rewrite. eauto with *.
+ simpl. rewrite H by auto with *.
break_if; eauto using f_equal2 with *.
Qed.
Proof using.
induction l; intros.
- intuition.
- right. simpl in *.
apply app_eq_nil in H.
intuition; subst; simpl in *; intuition.
Qed.
Proof using.
intros l l' Hnd Hp.
induction Hp; auto; invc_NoDup; constructor;
eauto using Permutation_in, Permutation_sym;
simpl in *; intuition.
Qed.
Proof using.
intuition eauto using NoDup_Permutation_NoDup, Permutation_sym, Permutation_cons_append.
Qed.
Proof using.
induction xs; intros; simpl in *.
- intuition.
- invc_NoDup. intuition; subst; auto; exfalso.
+ repeat find_rewrite. auto using in_map.
+ repeat find_reverse_rewrite. auto using in_map.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl in *. intuition.
break_if; subst; simpl; intuition.
Qed.
Proof using.
induction xs; intros; simpl in *; intuition; invc_NoDup;
break_if; subst; intuition (simpl; try congruence).
now rewrite remove_length_not_in.
Qed.
Proof using.
induction xs; intros.
- destruct ys; simpl in *; congruence.
- invc_NoDup. concludes.
assert (In a ys) by eauto with *.
find_apply_lem_hyp in_split.
break_exists_name l1.
break_exists_name l2.
subst.
specialize (IHxs (l1 ++ l2)).
conclude_using ltac:(eauto using NoDup_remove_1).
forward IHxs.
intros x' Hx'.
assert (In x' (l1 ++ a :: l2)) by eauto with *.
do_in_app. simpl in *. intuition. subst. congruence.
concludes.
forward IHxs.
rewrite app_length in *. simpl in *. omega.
concludes.
do_in_app. simpl in *. intuition.
Qed.
Proof using.
induction xs; intros.
- auto with struct_util.
- invc_NoDup. simpl. break_if; eauto 6 using in_remove with struct_util.
Qed.
Proof using.
induction xs; intros.
- auto.
- invc_NoDup. simpl. break_if.
+ rewrite <- minus_n_O.
subst.
rewrite remove_length_not_in; auto.
+ simpl. concludes. omega.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl in *.
specialize (IHxs eq_dec).
break_if; subst; simpl; omega.
Qed.
Proof using.
induction xs; intros; simpl in *; intuition.
- subst.
break_if; try congruence.
pose proof remove_length_le x xs eq_dec.
omega.
- specialize (IHxs ltac:(eauto) ltac:(eauto)).
break_if; subst; simpl; omega.
Qed.
Proof using A_eq_dec.
induction xs; intros.
- simpl. omega.
- specialize (IHxs (remove A_eq_dec a ys)).
invc_NoDup.
concludes.
forward IHxs.
intros.
apply remove_preserve; [congruence|intuition].
concludes.
pose proof remove_length_lt a ys A_eq_dec.
conclude_using intuition.
simpl. omega.
Qed.
Proof using.
intros.
destruct xs.
- solve_by_inversion.
- destruct xs; solve_by_inversion.
Qed.
Proof using.
intros. subst. auto with *.
Qed.
Hint Resolve app_cons_in : struct_util.
Proof using.
intros. subst. in_crush.
Qed.
Hint Resolve app_cons_in_rest : struct_util.
Proof using.
intros.
subst_max.
do_in_app.
break_or_hyp.
- auto with datatypes.
- find_apply_lem_hyp in_inv.
break_or_hyp; auto using in_or_app || congruence.
Qed.
Hint Resolve in_rest_app_cons : struct_util.
Proof using.
induction l; intros; simpl in *; auto.
repeat (break_if; subst; simpl in *; try congruence).
Qed.
Proof using.
intros. subst.
eapply filter_In; eauto.
Qed.
Proof using.
induction l1; intros; simpl in *; break_if; simpl in *; invc_NoDup.
- destruct l1'; simpl in *.
+ solve_by_inversion.
+ find_inversion. exfalso. eauto using In_filter_In with *.
- exfalso. eauto using In_filter_In with *.
- destruct l1'; simpl in *; break_and; find_inversion.
+ exfalso. eauto with *.
+ find_apply_hyp_hyp. intuition auto using f_equal2.
- eauto.
Qed.

Lemma map_inverses :
forall (la : list A) (lb : list B)  (f : A -> B) g,
(forall a, g (f a) = a) ->
(forall b, f (g b) = b) ->
lb = map f la ->
la = map g lb.