Section dup_drop_reorder.
Variable A : Type.
Hypothesis A_eq_dec : forall x y : A, {x = y} + {x <> y}.
Inductive dup_drop_step : list A -> list A -> Prop :=
| DDS_dup : forall l p,
In p l ->
dup_drop_step l (p :: l)
| DDS_drop : forall xs p ys,
dup_drop_step (xs ++ p :: ys) (xs ++ ys).
Definition dup_drop_step_star := clos_refl_trans_n1 _ dup_drop_step.
Proof using.
intros.
apply clos_rt_rtn1_iff.
eapply rt_trans; apply clos_rt_rtn1_iff; eauto.
Qed.
Proof using.
intros.
econstructor; eauto.
Qed.
Proof using.
intros.
apply clos_rt_rtn1_iff.
apply clos_rt_rt1n_iff.
econstructor; [eauto|].
apply clos_rt_rt1n_iff.
apply clos_rt_rtn1_iff.
auto.
Qed.
Proof using.
intros.
eapply dup_drop_step_star_step_1n; eauto.
constructor.
Qed.
Proof using.
intros.
eapply dup_drop_step_star_step_1n; [eapply DDS_dup with (p := y); simpl; auto|].
eapply dup_drop_step_star_step_1n.
eapply DDS_drop with (xs := [y; x]) (p := y) (ys := l).
constructor.
Qed.
Proof using.
induction 1.
- constructor.
- invc H.
+ eapply dup_drop_step_star_trans; [eauto|].
eapply dup_drop_step_star_step_1n; [eapply DDS_dup with (p := p); simpl; auto|].
auto using dup_drop_swap.
+ eapply dup_drop_step_star_trans; [eauto|].
eapply dup_drop_step_star_step_1n.
eapply DDS_drop with (xs := x :: xs) (p := p) (ys := ys).
constructor.
Qed.
Proof using.
induction 1.
- constructor.
- auto using dup_drop_cons.
- auto using dup_drop_swap.
- eauto using dup_drop_step_star_trans.
Qed.
Proof using.
induction l; simpl; intuition.
break_if; congruence.
Qed.
Proof using.
induction 1; intros.
- auto.
- invc H.
+ simpl in *. intuition.
subst. auto.
+ apply IHclos_refl_trans_n1.
find_apply_lem_hyp in_app_or.
intuition.
Qed.
Proof using.
induction 1; intros.
- apply dup_drop_step_star_step_1. constructor. auto.
- concludes.
eapply dup_drop_step_star_trans; eauto.
apply dup_drop_cons.
apply dup_drop_step_star_step_1.
auto.
Qed.
Proof using.
induction l'; simpl; intuition.
- subst. break_if; try congruence.
destruct (in_dec A_eq_dec a0 l').
+ find_apply_hyp_hyp.
eapply dup_drop_step_star_trans; eauto.
eapply dup_drop_step_star_step_1.
apply DDS_dup; auto.
+ rewrite remove_not_in_nop in * by auto.
apply dup_drop_cons. auto.
- break_if.
+ subst.
find_apply_hyp_hyp.
eapply dup_drop_step_star_trans; eauto.
eapply dup_drop_step_star_step_1.
apply DDS_dup; auto.
+ pose proof dup_drop_in l _ a ltac:(eauto).
try concludes. (* Only needed in Coq 8.5 *)
eapply dup_drop_step_star_step_n1 in H0; [| eapply DDS_drop with (xs := [])].
simpl in *.
apply IHl' in H0; auto.
apply dup_drop_dup_early; auto.
simpl. intuition.
Qed.
Proof using.
induction l; simpl; intuition; break_if; subst; simpl in *; intuition.
Qed.

Lemma dup_drop_reorder :
forall l l' : list A,
(forall x, In x l' -> In x l) ->
dup_drop_step_star l l'.