Section list_util.
Variables A B C : Type.
Hypothesis A_eq_dec : forall x y : A, {x = y} + {x <> y}.
Proof using.
intros l x H.
symmetry in H.
induction l;
now inversion H.
Qed.
Proof using.
induction xs; intros.
- intuition auto.
- simpl in *.
concludes.
break_or_hyp; break_if; subst; try congruence; intuition (auto with datatypes).
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl in *. break_if; simpl in *; intuition auto.
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 (auto with datatypes).
rewrite IHxs by intuition (auto with datatypes). auto.
Qed.
Proof using.
induction xs; intros.
- constructor.
- simpl. invc_NoDup. constructor.
+ intro. do_in_map.
assert (x = a) by intuition (auto with datatypes).
congruence.
+ intuition (auto with datatypes).
Qed.
Proof using.
induction l; intros.
- auto.
- simpl. invc_NoDup. constructor.
+ intro. do_in_app. intuition eauto with datatypes.
+ intuition eauto with datatypes.
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 (auto with datatypes).
- subst. simpl in *. find_inversion.
invc H. exfalso. rewrite map_app in *. simpl in *.
repeat find_rewrite. intuition (auto with datatypes).
- 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 auto.
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 auto.
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 (auto with datatypes).
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 datatypes.
+ simpl. rewrite H by auto with datatypes.
break_if; eauto using f_equal2 with datatypes.
Qed.
Proof using.
induction l; intros.
- intuition auto.
- right. simpl in *.
apply app_eq_nil in H.
intros; break_and; break_or_hyp; concludes; break_or_hyp; auto.
contradiction.
Qed.
Proof using.
intros l l' Hnd Hp.
induction Hp; auto; invc_NoDup; constructor;
eauto using Permutation_in, Permutation_sym;
simpl in *; intuition (auto with struct_util).
Qed.
Proof using.
intuition eauto using NoDup_Permutation_NoDup, Permutation_sym, Permutation_cons_append.
Qed.
Proof using.
induction xs; intros; simpl in *.
- intuition auto.
- invc_NoDup. intuition auto; 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 auto.
break_if; subst; simpl; intuition auto.
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 datatypes.
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 datatypes.
do_in_app. simpl in *. intuition auto with datatypes. subst. congruence.
concludes.
forward IHxs.
rewrite app_length in *. simpl in *. lia.
concludes.
do_in_app. simpl in *. intuition auto with datatypes.
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 Nat.sub_0_r.
subst.
rewrite remove_length_not_in; auto.
+ simpl. concludes. lia.
Qed.
Proof using.
induction xs; intros.
- auto.
- simpl in *.
specialize (IHxs eq_dec).
break_if; subst; simpl; lia.
Qed.
Proof using.
induction xs; intros; simpl in *; [contradiction|]; break_or_hyp.
- subst.
break_if; try congruence.
pose proof remove_length_le x xs eq_dec.
lia.
- specialize (IHxs ltac:(eauto) ltac:(eauto)).
break_if; subst; simpl; lia.
Qed.
Proof using A_eq_dec.
induction xs; intros.
- simpl. lia.
- specialize (IHxs (remove A_eq_dec a ys)).
invc_NoDup.
concludes.
forward IHxs.
intros.
apply remove_preserve;
[congruence|intuition (auto with datatypes)].
concludes.
pose proof remove_length_lt a ys A_eq_dec.
assert (In a ys) by auto with datatypes.
concludes.
simpl. lia.
Qed.
Proof using.
intros.
destruct xs.
- solve_by_inversion.
- destruct xs; solve_by_inversion.
Qed.
Proof using.
intros. subst. auto with datatypes.
Qed.
Hint Resolve app_cons_in : struct_util.
Proof using.
intros. subst.
do_in_app; intuition auto with datatypes.
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 datatypes.
- exfalso. eauto using In_filter_In with datatypes.
- destruct l1'; simpl in *; break_and; find_inversion.
+ exfalso. eauto with datatypes.
+ 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 (auto with datatypes).
Qed.
Proof using.
intros.
rewrite <- app_ass in *.
find_apply_lem_hyp NoDup_remove_2.
rewrite app_ass in *.
auto 10 with datatypes.
Qed.
Proof using.
intros.
rewrite <- app_ass in *.
find_apply_lem_hyp NoDup_remove_2.
rewrite app_ass in *.
auto 10 with datatypes.
Qed.
Proof using.
intros.
repeat (do_in_app; intuition auto 10 with datatypes).
Qed.
Proof using.
intros.
repeat (do_in_app; simpl in *; intuition (auto with datatypes; try congruence)).
Qed.
Proof using.
intros.
do_in_app; simpl in *; intuition auto with datatypes. congruence.
Qed.
Proof using.
intros.
do_in_app; simpl in *; intuition auto with datatypes.
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 *; [lia|].
specialize (H a). intuition.
* destruct sub2; simpl in *; [lia|].
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; lia.
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.
Proof using.
intros l l' a H_pm.
assert (In a (a :: l)); auto with datatypes.
assert (In a l'); eauto using Permutation_in.
find_apply_lem_hyp In_split; auto.
Qed.
Proof using.
induction l; intros; simpl in *.
- apply NoDup_nil.
- invc_NoDup.
find_apply_hyp_hyp.
apply NoDup_cons; auto.
intro.
match goal with H: ~ In _ _ |- _ => contradict H end.
apply in_or_app.
left; auto.
Qed.
Proof using.
induction l; intros; simpl in *; auto.
invc_NoDup.
find_apply_hyp_hyp; auto.
Qed.
Proof using.
induction l; intros; simpl in *; auto.
invc_NoDup.
break_or_hyp; eauto with datatypes.
Qed.
Proof using.
intros.
induction l; simpl in *; auto.
invc_NoDup.
concludes.
intro.
break_or_hyp; auto with datatypes.
Qed.
Proof using.
intros.
induction l; simpl in *; auto.
break_if; auto.
find_rewrite.
auto.
Qed.
Proof using.
induction l; intros; simpl in *.
- find_apply_lem_hyp Permutation_nil.
find_rewrite.
auto.
- assert (In a l').
apply Permutation_in with (l := a :: l); auto with datatypes.
find_apply_lem_hyp in_split.
break_exists.
find_rewrite.
find_apply_lem_hyp Permutation_cons_app_inv.
find_apply_hyp_hyp.
find_rewrite.
rewrite map_app.
simpl.
apply Permutation_cons_app.
rewrite <- map_app.
auto.
Qed.
Proof using.
intros.
induction l; simpl in *; auto.
intro.
break_or_hyp.
- match goal with H: ~ _ |- _ => contradict H end.
left.
destruct a.
match goal with H: forall _ : A * B, _ |- _ => specialize (H (a, b)) end.
simpl in *.
intuition eauto; repeat find_rewrite; auto.
- match goal with H: In _ _ |- _ => contradict H end.
apply IHl; eauto.
Qed.

Lemma NoDup_map_snd_fst :
forall nms : list (A * B),
NoDup nms ->
(forall nm nm', In nm nms -> In nm' nms -> snd nm = snd nm') ->
NoDup (map fst nms).