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.
Proof using.
destruct la; intros; simpl in *.
- subst. reflexivity.
- destruct lb; try congruence.
simpl in *. find_inversion.
find_higher_order_rewrite.
f_equal.
rewrite map_map.
erewrite map_ext; [symmetry; apply map_id|].
simpl in *. auto.
Qed.
Proof using.
intuition congruence.
Qed.
Proof using.
simpl.
intuition congruence.
Qed.
Proof using.
intros.
rewrite <- app_ass in *.
find_apply_lem_hyp NoDup_remove.
rewrite app_ass in *.
intuition.
Qed.
Proof using.
intros.
rewrite <- app_ass in *.
find_apply_lem_hyp NoDup_remove_2.
rewrite app_ass in *.
auto 10 with *.
Qed.
Proof using.
intros.
rewrite <- app_ass in *.
find_apply_lem_hyp NoDup_remove_2.
rewrite app_ass in *.
auto 10 with *.
Qed.
Proof using.
intros.
repeat (do_in_app; intuition auto 10 with *).
Qed.
Proof using.
intros.
repeat (do_in_app; simpl in *; intuition (auto with *; try congruence)).
Qed.
Proof using.
intros.
do_in_app; simpl in *; intuition. congruence.
Qed.
Proof using.
intros.
do_in_app; simpl in *; intuition.
Qed.
Proof using.
induction l; intros; simpl.
- auto.
- apply NoDup_append.
invc_NoDup.
constructor; auto.
intuition.
find_apply_lem_hyp in_rev.
auto.
Qed.
Proof using.
induction xs; intros; simpl in *.
- constructor.
- invc_NoDup.
constructor; auto.
intro.
do_in_map.
find_apply_hyp_hyp.
find_reverse_rewrite.
auto using in_map.
Qed.
Proof using A_eq_dec.
induction l.
intros.
+ simpl in *. find_apply_lem_hyp plus_gt_0. intuition.
* destruct sub1; simpl in *; [omega|].
specialize (H a). intuition.
* destruct sub2; simpl in *; [omega|].
specialize (H0 a). intuition.
+ intros. simpl in *.
destruct (in_dec A_eq_dec a sub1);
destruct (in_dec A_eq_dec a sub2); eauto;
specialize (IHl (remove A_eq_dec a sub1) (remove A_eq_dec a sub2));
cut (exists a0, In a0 (remove A_eq_dec a sub1) /\ In a0 (remove A_eq_dec a sub2));
try solve [intros; break_exists;
intuition eauto using in_remove];
apply IHl; try solve [
intros; find_copy_apply_lem_hyp in_remove;
find_apply_hyp_hyp; intuition; subst; exfalso; eapply remove_In; eauto];
eauto using remove_NoDup; try solve_by_inversion;
repeat match goal with
| H : ~ In a ?sub |- _ =>
assert (length (remove A_eq_dec a sub) = length sub)
by eauto using remove_length_not_in; clear H
| H : In a ?sub |- _ =>
assert (length (remove A_eq_dec a sub) >= length sub - 1)
by eauto using remove_length_ge; clear H
end; omega.
Qed.
Proof using.
induction l; intros; simpl; intuition.
auto using f_equal.
Qed.
Proof using.
auto.
Qed.
Proof using.
induction l; simpl; intros xs ys H.
- symmetry in H. apply app_eq_nil in H. break_and. subst.
exists [], []. auto.
- destruct xs; simpl in *.
+ exists [], (a :: l). intuition.
+ invc H. find_apply_hyp_hyp.
break_exists_name l1.
break_exists_name l2.
break_and.
exists (a :: l1), l2. subst.
intuition.
Qed.
Proof using.
intros p l x p' f H_m.
pose proof map_eq_inv f _ _ _ H_m.
break_exists_name l1.
break_exists_name l2.
break_and.
find_rewrite.
destruct l2; simpl in *.
- match goal with H : [] = _ :: _ |- _ => contradict H end.
auto with datatypes.
- repeat find_rewrite.
find_inversion.
exists l1, a, l2. auto.
Qed.
Proof using.
induction l; simpl; intros l' Heq; destruct l'; simpl in *; try congruence.
find_inversion. auto using f_equal2.
Qed.
Proof using.
intros.
rewrite <- map_id.
apply map_ext.
destruct a; auto.
Qed.
Proof using.
induction n; simpl; intuition; break_match; simpl in *; intuition.
Qed.
Proof using.
induction n; intros; simpl; destruct xs; auto with struct_util.
invc_NoDup.
eauto 6 using in_firstn with struct_util.
Qed.
Proof using.
induction l; intros; simpl in *.
- invc_NoDup; auto.
- invc_NoDup.
intro.
break_or_hyp.
* match goal with H: ~ In _ _ |- _ => contradict H end.
apply in_or_app.
right; left. auto.
* match goal with H: In _ _ |- _ => contradict H end.
eauto.
Qed.

Lemma Permutation_split :
forall (ns ns' : list A) (n : A),
Permutation (n :: ns) ns' ->
exists ns0, exists ns1, ns' = ns0 ++ n :: ns1.