Section SumList.
Variable A : Set.
Definition sumList(ls : list A)(f : A -> Rat) := fold_left (fun a b => a + (f b)) ls 0.
(* Facts about sumList *)
Abort.
Abort.
induction ls; intuition; simpl in *.
eapply eqRat_refl.
eapply eqRat_trans.
eapply IHls.
eapply eqRat_trans.
eapply ratAdd_assoc.
eapply ratAdd_eqRat_compat.
eapply eqRat_refl.
eapply eqRat_symm.
eapply IHls.
Qed.
induction ls; intuition; simpl in *.
eapply IHls; eauto.
eapply ratAdd_eqRat_compat; eauto.
Qed.
induction 1; intuition; simpl in *.
eapply IHPermutation; eauto.
eapply ratAdd_eqRat_compat; eauto.
eapply fold_add_body_eq.
eapply eqRat_trans.
eapply ratAdd_assoc.
eapply eqRat_trans.
2:{
eapply eqRat_symm.
eapply ratAdd_assoc.
}
eapply ratAdd_eqRat_compat; eauto.
eapply eqRat_trans.
eapply ratAdd_comm.
eapply ratAdd_eqRat_compat; eauto.
intuition.
eapply eqRat_trans; eauto.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply eqRat_symm; eauto.
intuition.
eapply eqRat_symm.
eapply H2.
eapply Permutation_in.
eapply Permutation_sym.
eauto.
eauto.
simpl.
eapply IHPermutation2.
trivial.
intuition.
eapply H2.
eapply Permutation_in.
eapply Permutation_sym.
eauto.
eauto.
Qed.
induction ls; intuition; simpl in *.
eapply IHls; eauto.
rewrite H0.
eapply ratAdd_eqRat_compat; eauto.
eapply eqRat_refl.
intuition.
Qed.
induction ls; intuition; simpl in *.
intuition.
unfold sumList.
simpl.
eapply eqRat_refl.
intuition; subst.
unfold sumList in *; simpl in *.
eapply eqRat_trans.
eapply ratAdd_0.
eapply eqRat_trans.
eapply ratAdd_comm.
eapply eqRat_trans.
eapply eqRat_symm.
eapply fold_add_init.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
eapply H.
eapply eqRat_refl.
eapply IHls.
unfold sumList in *; simpl in *.
eapply ratAdd_0.
eapply eqRat_trans.
eapply eqRat_symm.
eapply fold_add_init.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
eapply H.
trivial.
unfold sumList.
simpl.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
eapply eqRat_trans.
eapply fold_add_init.
eapply ratAdd_0.
intuition.
unfold sumList in *.
eapply IHls.
intuition.
Qed.
induction ls; intuition; unfold sumList in *; simpl in *.
exfalso.
apply H.
eapply eqRat_refl.
destruct H.
intuition.
assert (f a + fold_left (fun r a => r + f a) ls 0 == 0 -> False).
intuition.
eapply H.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
eapply eqRat_trans.
eapply fold_add_init.
trivial.
eapply ratAdd_nz in H0.
destruct H0.
econstructor; intuition.
apply IHls in H0.
destruct H0; intuition.
exists x.
intuition.
assert (f a + fold_left (fun r a => r + f a) ls 0 == 0).
eapply eqRat_trans.
eapply eqRat_symm.
eapply fold_add_init.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
trivial.
apply ratAdd_0 in H1.
intuition.
destruct H.
intuition.
subst.
intuition.
apply IHls in H3; intuition.
econstructor; eauto.
Qed.
End SumList.
intuition.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
rewrite ratAdd_0_r.
apply eqRat_refl.
apply eqRat_refl.
apply fold_add_init.
Qed.
induction ls; intuition; simpl in *; intuition.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_r.
apply eqRat_refl.
apply eqRat_refl.
trivial.
Qed.
intuition.
eapply eqRat_trans.
eapply fold_add_body_eq.
apply eqRat_refl.
eapply H.
simpl.
eapply fold_add_eq_init.
Qed.
induction ls; intuition; simpl in *.
eapply eqRat_refl.
rewrite IHls.
eapply fold_add_body_eq.
repeat rewrite <- ratAdd_assoc.
apply ratAdd_eqRat_compat; intuition.
rewrite ratAdd_assoc.
rewrite ratAdd_assoc.
apply ratAdd_eqRat_compat; intuition.
eapply ratAdd_comm.
intuition.
Qed.
induction lsa; destruct lsb; intuition; simpl in *; intuition.
apply eqRat_symm.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_r.
apply eqRat_refl.
apply eqRat_refl.
apply fold_add_eq_init.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_r.
apply eqRat_refl.
apply eqRat_refl.
apply fold_add_eq_init.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_l.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_l.
apply eqRat_refl.
apply eqRat_refl.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_l.
apply eqRat_refl.
apply eqRat_refl.
simpl.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
eapply eqRat_refl.
eapply fold_add_init_0.
simpl.
eapply eqRat_trans.
eapply fold_add_init_0.
eapply eqRat_trans.
eapply ratAdd_eqRat_compat.
apply eqRat_refl.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
apply ratAdd_0_r.
apply eqRat_refl.
apply eqRat_symm.
eapply fold_add_eq.
eapply eqRat_trans.
eapply ratAdd_eqRat_compat.
apply eqRat_refl.
apply ratAdd_eqRat_compat.
apply eqRat_refl.
eapply IHlsa.
eapply eqRat_symm.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_l.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_l.
apply eqRat_refl.
apply eqRat_refl.
eapply fold_add_body_eq; intuition.
rewrite <- ratAdd_0_l.
apply eqRat_refl.
apply eqRat_refl.
simpl.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
eapply eqRat_refl.
eapply fold_add_init_0.
simpl.
eapply eqRat_trans.
eapply fold_add_init_0.
eapply eqRat_trans.
eapply ratAdd_eqRat_compat.
apply eqRat_refl.
eapply eqRat_trans.
eapply fold_add_body_eq; intuition.
apply ratAdd_0_r.
apply eqRat_refl.
apply eqRat_symm.
eapply fold_add_eq.
eapply eqRat_trans.
eapply ratAdd_eqRat_compat.
eapply fold_add_init_0.
eapply eqRat_refl.
eapply eqRat_symm.
eapply eqRat_trans.
eapply ratAdd_eqRat_compat.
eapply fold_add_init_0.
eapply eqRat_refl.
repeat rewrite <- ratAdd_assoc.
eapply ratAdd_eqRat_compat.
repeat rewrite (ratAdd_assoc (f a b)).
eapply ratAdd_eqRat_compat; intuition.
eapply ratAdd_comm.
eapply eqRat_refl.
Qed.
intuition.
eapply fold_add_comm; intuition.
Qed.
intuition.
eapply fold_add_body_eq; intuition.
Qed.
induction ls; intuition; simpl in *.
intuition.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply eqRat_symm.
eapply ratMult_distrib_r.
intuition.
eapply eqRat_refl.
eapply IHls.
Qed.
intuition.
unfold sumList.
rewrite <- fold_add_factor_constant_r.
eapply fold_add_body_eq.
eapply eqRat_symm.
eapply ratMult_0_l.
intuition.
Qed.
intuition.
eapply eqRat_trans.
eapply sumList_body_eq; intuition.
apply ratMult_comm.
eapply eqRat_trans.
eapply sumList_factor_constant_r.
apply ratMult_comm.
Qed.
induction ls; intuition; simpl in *.
eapply eqRat_trans.
eapply ratAdd_0_l.
eapply ratAdd_eqRat_compat.
eapply eqRat_symm.
apply ratMult_0_r.
intuition.
rewrite IHls.
eapply eqRat_trans.
eapply ratAdd_eqRat_compat.
apply eqRat_refl.
apply ratAdd_comm.
rewrite <- (ratAdd_assoc).
apply ratAdd_eqRat_compat; intuition.
eapply eqRat_symm.
eapply eqRat_trans.
eapply ratMult_eqRat_compat.
apply eqRat_refl.
apply ratS_num.
rewrite ratMult_distrib.
rewrite ratAdd_comm.
apply ratAdd_eqRat_compat; intuition.
apply ratMult_1_r.
Qed.
intuition.
eapply eqRat_trans.
apply fold_add_body_const.
rewrite <- ratAdd_0_r.
eapply eqRat_refl.
Qed.
induction ls; intuition; simpl in *;
intuition; subst.
assert (init + f a <= r).
eapply IHls.
apply H.
eapply ratAdd_any_le; eauto.
assert (init + f a0 <= r).
eapply IHls.
eauto.
eapply ratAdd_any_le.
eapply leRat_trans.
apply eqRat_impl_leRat.
apply ratAdd_comm.
eauto.
edestruct IHls; eauto.
Qed.
intuition.
eapply fold_add_iter_le; eauto.
Qed.
Fixpoint removeFirst(A : Set)(eqd : eq_dec A)(ls : list A) a :=
match ls with
| nil => nil
| a' :: ls' =>
if (eqd a a') then ls' else a' :: (removeFirst eqd ls' a)
end.
induction ls; intuition; simpl in *;
intuition; subst.
destruct (eqd a0 a0); try congruence.
eapply Permutation_refl.
destruct (eqd a0 a); subst.
eapply Permutation_refl.
eapply perm_trans; [idtac | eapply perm_swap].
eapply perm_skip.
eauto.
Qed.
induction ls; intuition; simpl in *.
destruct (eqd a2 a); subst.
intuition.
simpl in *.
intuition.
eapply IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
inversion H; clear H; subst.
destruct(eqd a0 a); subst.
intuition.
simpl in *.
intuition; subst.
eapply IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
inversion H; clear H; subst.
destruct (eqd a0 a); subst.
trivial.
econstructor.
eapply removeFirst_not_in.
intuition.
eapply IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
destruct (eqd a2 a); subst.
intuition.
congruence.
simpl.
intuition.
Qed.
induction ls; intuition; simpl in *.
destruct (eqd a2 a); subst.
intuition.
simpl in *.
intuition.
right.
eapply IHls; eauto.
Qed.
(* ls1 is the smaller set.  This function returns a permutation of ls2 where the first elements of ls2 match the order of the elements in ls1.  This function only works if ls1 is a subset of ls2. *)
Fixpoint matchOrder (A : Set)(eqd : eq_dec A)(ls1 ls2 : list A) :=
match ls1 with
| nil => ls2
| a :: ls1' =>
a :: (matchOrder eqd ls1' (removeFirst eqd ls2 a))
end.
induction ls1; destruct ls2; intuition; simpl in *; eauto; intuition; subst.
inversion H; clear H; subst.
inversion H0; clear H0; subst.
destruct (eqd a a1); subst.
intuition.
right.
eapply (IHls1 (a1 :: removeFirst _ ls2 a)); intuition.
econstructor.
eapply removeFirst_not_in; intuition.
eapply removeFirst_NoDup; intuition.
simpl.
destruct (H1 a0); auto.
right.
eapply removeFirst_in; eauto.
intuition. subst.
intuition.
inversion H; clear H; subst.
inversion H0; clear H0; subst.
destruct (H1 a); intuition; subst.
destruct (eqd a a); try congruence.
right.
eapply (IHls1 ls2); intuition.
destruct (H1 a0); intuition; subst.
intuition.
destruct (eqd a a0); try congruence.
destruct (eqd a a1); subst; auto.
right.
eapply (IHls1 (a0 :: removeFirst _ ls2 a)); intuition.
econstructor.
eapply removeFirst_not_in; trivial.
eapply removeFirst_NoDup; trivial.
simpl.
destruct (H1 a2); eauto.
destruct (eqd a0 a2); intuition.
right.
eapply removeFirst_in; trivial.
intuition.
subst.
intuition.
simpl.
destruct (eqd a0 a1); intuition.
right.
eapply removeFirst_in; trivial.
intuition.
inversion H; clear H; subst.
inversion H0; clear H0; subst.
destruct (eqd a0 a1); subst; intuition.
right.
assert (In a1 (if eqd a a0 then ls2 else a0 :: removeFirst eqd ls2 a)).
eapply IHls1.
trivial.
destruct (eqd a a0).
trivial.
econstructor.
eapply removeFirst_not_in; eauto.
eapply removeFirst_NoDup; intuition.
intuition.
destruct (eqd a a0).
destruct (H1 a2).
intuition.
subst.
intuition.
trivial.
simpl.
destruct (eqd a0 a2); intuition.
right.
destruct (H1 a2).
destruct (eqd a a2); intuition.
subst.
intuition.
eapply removeFirst_in.
trivial.
intuition. subst.
intuition.
trivial.
destruct (eqd a a0); intuition.
simpl in *.
intuition.
eapply removeFirst_in_iff.
eauto.
Qed.
induction ls1; intuition; simpl in *.
intuition; subst.
eapply (IHls1 (removeFirst eqd ls2 a)).
eapply H3.
intuition.
eapply removeFirst_not_in.
intuition.
eapply H0.
eauto.
eapply H.
eauto.
Qed.
induction ls1; intuition; simpl in *.
destruct (eqd a a0); subst;
intuition.
eapply IHls1.
intuition.
eapply H0.
assert (~ In a0 ls1).
intuition.
specialize (@matchOrder_not_in_h _ eqd ls1 (removeFirst eqd ls2 a) a0); intuition.
exfalso.
eapply H4; eauto.
intuition.
eapply removeFirst_not_in.
intuition.
eapply H0.
eapply H5.
eapply H3.
Qed.
induction ls1; intuition; simpl in *.
inversion H1; clear H1; subst.
econstructor.
eapply matchOrder_not_in.
intuition.
destruct (eqd a a0); subst; intuition.
eapply removeFirst_in.
eapply H.
intuition.
intuition.
eapply removeFirst_NoDup_not_in; eauto.
eapply IHls1; intuition.
destruct (eqd a a0); subst; intuition.
eapply removeFirst_in; eauto.
eapply removeFirst_NoDup; eauto.
Qed.
intuition.
eapply NoDup_Permutation; intuition.
eapply matchOrder_NoDup; eauto.
eapply (@matchOrder_In _ eqd ls1 ls2); eauto.
eapply (@matchOrder_In _ eqd ls1 ls2); eauto.
Qed.
induction ls1; intuition; simpl in *.
inversion H; clear H; subst.
f_equal.
eapply IHls1; eauto.
eapply removeFirst_NoDup; eauto.
intuition.
destruct (eqd a0 a); subst; intuition.
eapply removeFirst_in.
eapply H1.
intuition.
intuition.
Qed.
induction ls; intuition; simpl in *.
destruct n; simpl in *;
trivial.
inversion H0; clear H0; subst.
destruct n; simpl in *.
eapply eqRat_symm.
eapply eqRat_trans.
eapply fold_add_eq_init_f; intuition.
rewrite (ratAdd_0_r init1).
eapply ratAdd_eqRat_compat; intuition.
eapply IHls.
eapply ratAdd_eqRat_compat; intuition.
trivial.
intuition.
eapply H1.
intuition.
intuition.
subst.
intuition.
Qed.
induction 1; intuition.
inversion H0; clear H0; subst.
econstructor.
intuition.
eapply H3.
eapply Permutation_in.
eapply Permutation_sym.
eapply H.
eauto.
eauto.
inversion H; clear H; subst.
inversion H3; clear H3; subst.
simpl in *.
econstructor.
simpl.
intuition.
econstructor;
intuition.
Qed.
intuition.
erewrite <- matchOrder_firstn at 1.
eapply eqRat_symm.
eapply eqRat_trans.
eapply fold_add_rat_perm.
eapply matchOrder_permutation.
eapply H0.
eauto.
intuition.
eapply eqRat_refl.
intuition.
eapply eqRat_refl.
eapply eqRat_symm.
eapply fold_add_matchOrder; intuition.
eapply permutation_NoDup.
eapply matchOrder_permutation; eauto.
eauto.
eapply H3.
intuition.
eapply H5.
rewrite matchOrder_firstn; eauto.
eauto.
eauto.
eauto.
Grab Existential Variables.
trivial.
Qed.
intuition.
eapply fold_add_subset; intuition.
Qed.
Fixpoint flatten(A : Type)(ls : list (list A)) :=
match ls with
| nil => nil
| a :: ls' => a ++ (flatten ls')
end.
induction ls; simpl in *; intuition.
destruct H; intuition.
apply in_app_or in H.
intuition.
exists a; intuition.
apply IHls in H0.
destruct H0.
intuition.
exists x; intuition.
apply in_or_app.
destruct H; intuition.
subst.
intuition.
right.
eapply IHls.
econstructor.
eauto.
Qed.
induction ls; destruct ls'; intuition; simpl in *.
intuition.
destruct H; simpl in *; subst; intuition.
destruct H; simpl in *; subst; intuition.
rewrite app_length.
simpl.
omega.
rewrite app_length.
specialize (IHls (a0 :: ls') H).
simpl in *.
intuition.
Qed.
Fixpoint getUnique(A : Set)(ls : list A)(pf : eq_dec A) : list A :=
match ls with
| nil => nil
| a :: ls' =>
let ls'' := (getUnique ls' pf) in
if (in_dec pf a ls'')
then ls''
else a :: ls''
end.
induction ls; simpl in *; intuition.
destruct (in_dec _ a (getUnique ls _)).
right.
eapply IHls.
eapply H.
simpl in *.
intuition.
right.
eapply IHls.
eapply H0.
Qed.
induction ls; simpl in *; intuition.
subst.
destruct (in_dec _ a0 (getUnique ls _)); simpl; auto.
destruct (in_dec _ a (getUnique ls _)); simpl.
eapply IHls. trivial.
right.
eapply IHls.
trivial.
Qed.
induction ls; intuition; simpl in *.
econstructor.
destruct (in_dec _ a (getUnique ls _)); eauto.
econstructor; eauto.
Qed.
induction ls; intuition; simpl in *.
destruct (in_dec eqd a (getUnique ls eqd)).
destruct ls; simpl in *; intuition.
simpl.
omega.
Qed.
Definition maxList(ls : list nat) : nat :=
fold_left max ls O.
induction ls; intuition; simpl in *.
eapply le_trans.
eapply Max.max_lub_l.
eapply le_refl.
eapply IHls.
Qed.
induction ls; intuition.
inversion H.
simpl in *.
intuition; subst.
eapply le_trans.
eapply Max.max_lub_r.
eapply le_refl.
eapply fold_left_max_ge_init.
Qed.
intuition.
eapply maxList_correct_h.
trivial.
Qed.
(* relational folds and other llist operations *)
Inductive pred_count(A : Type)(p : A -> Prop) : list A -> nat -> Prop :=
| pc_nil :
pred_count p nil 0
| pc_yes :
forall ls n a,
pred_count p ls n ->
p a ->
pred_count p (a :: ls) (S n)
| pc_no : forall ls n a,
pred_count p ls n ->
~p a ->
pred_count p (a :: ls) n.
induction ls; intuition; simpl in *.
inversion H; subst.
trivial.
inversion H; clear H; subst.
eapply le_n_S.
eapply IHls.
trivial.
econstructor.
eapply IHls.
trivial.
Qed.
(* listRepeat is used to show some interesting properties of rel_map and pred_count. *)
Fixpoint listRepeat(A : Type)(a : A) n :=
match n with
| 0 => nil
| S n' => a :: (listRepeat a n')
end.
induction n; intuition; simpl in *.
f_equal.
eauto.
Qed.
induction n; intuition; simpl in *.
inversion H. trivial.
inversion H; clear H; subst.
f_equal.
eapply IHn; eauto.
congruence.
Qed.
induction n; intuition; simpl in *.
inversion H0. trivial.
inversion H0; clear H0; subst.
intuition.
eapply IHn; eauto.
Qed.
induction ls; intuition.
inversion H. inversion H0. trivial.
inversion H; clear H; subst.
inversion H0; clear H0; subst.
f_equal.
eapply IHls; eauto.
intuition.
inversion H0; clear H0; subst.
intuition.
eapply IHls; eauto.
Qed.
induction 1; intuition; simpl in *.
f_equal.
eauto.
specialize (H1 a).
intuition.
Qed.
induction 1; intuition; simpl in *.
exists O. exists O.
intuition;
destruct n; simpl; econstructor.
destruct n0; simpl.
destruct (IHpred_count O).
destruct H1.
intuition. subst.
exists x.
exists (S x0).
intuition.
econstructor; trivial.
destruct (IHpred_count n0).
destruct H1.
destruct H1.
intuition. subst.
exists (S x).
exists x0.
intuition.
econstructor; trivial.
destruct n0; simpl.
destruct (IHpred_count O).
destruct H1.
intuition. subst.
exists x.
exists x0.
intuition.
econstructor; trivial.
destruct (IHpred_count n0).
destruct H1.
destruct H1.
intuition. subst.
exists x.
exists x0.
intuition.
econstructor; trivial.
Qed.
induction ls; intuition; simpl in *; subst.
econstructor.
econstructor; eauto.
Qed.
induction ls; intuition; simpl in *.
econstructor.
econstructor; eauto.
Qed.
induction n; intuition; simpl in *.
intuition.
intuition.
Qed.
induction ls1; intuition; simpl in *.
inversion H; subst; clear H.
simpl.
trivial.
inversion H; clear H; subst.
simpl.
econstructor; eauto.
econstructor; eauto.
Qed.
induction 1; intuition.
inversion H0; clear H0; subst.
econstructor; eauto.
econstructor; eauto.
inversion H; clear H; subst.
inversion H2; clear H2; subst.
econstructor; eauto.
econstructor; eauto.
eapply pc_no; eauto.
econstructor; eauto.
inversion H2; clear H2; subst.
econstructor; eauto.
econstructor; eauto.
econstructor; eauto.
econstructor; eauto.
Qed.
induction 1; intuition; simpl in *.
exfalso.
eapply H1.
eauto.
trivial.
eapply IHpred_count.
intuition.
eapply H1; eauto.
Qed.
intuition.
assert (pred_count P (a :: (removeFirst eqd ls a)) c).
eapply pred_count_permutation.
eapply removeFirst_permutation.
trivial.
trivial.
inversion H4; clear H4; subst.
assert (n = 0)%nat.
eapply pred_count_eq_none_inv.
eauto.
intuition.
eapply H3.
eapply removeFirst_in_iff.
eauto.
assert (~In a (removeFirst eqd ls a)).
eapply removeFirst_NoDup_not_in.
trivial.
intuition; subst; intuition.
trivial.
omega.
intuition.
Qed.
induction ls; intuition.
exists O.
econstructor.
destruct H0.
destruct (H a).
exists (S x).
econstructor; eauto.
exists x.
econstructor; eauto.
Qed.
Inductive rel_map(A B : Type)(r : A -> B -> Prop) : list A -> list B -> Prop :=
| rm_nil :
rel_map r nil nil
| rm_step :
forall lsa lsb a b,
rel_map r lsa lsb ->
r a b ->
rel_map r (a :: lsa) (b :: lsb).
induction ls_c; intuition.
inversion H; subst.
simpl.
econstructor.
inversion H; clear H; subst.
simpl.
econstructor; eauto.
Qed.
induction 1; intuition; simpl in *.
f_equal.
eauto.
Qed.
induction 1; intuition; simpl in *.
intuition.
intuition; subst.
eauto.
Qed.
induction ls1; intuition; subst.
inversion H1; clear H1; subst.
inversion H2; clear H2; subst.
trivial.
inversion H1; clear H1; subst.
inversion H2; clear H2; subst.
f_equal.
eapply H0; eauto.
eapply IHls1; eauto.
Qed.
induction 1; intuition; subst.
econstructor.
econstructor.
eapply IHrel_map; eauto.
intuition.
eapply H2.
simpl.
intuition.
simpl.
intuition.
trivial.
Qed.
induction ls; intuition.
inversion H0; subst; clear H0.
inversion H1. trivial.
inversion H0; clear H0; subst.
inversion H1; clear H1; subst.
exfalso.
eapply H; eauto. simpl. intuition.
eapply IHls; eauto.
intuition.
eapply H; eauto. simpl. intuition.
Qed.
induction lsa1; intuition; simpl in *.
econstructor.
inversion H; clear H; subst.
econstructor.
eapply IHlsa1; eauto.
trivial.
inversion H; clear H; subst.
eapply IHlsa1; eauto.
Qed.
induction lsa; intuition; simpl in *.
inversion H; subst; clear H.
econstructor.
inversion H; clear H; subst.
econstructor.
eapply IHlsa; eauto.
trivial.
Qed.
induction lsa; intuition; simpl in *.
econstructor.
econstructor; eauto.
Qed.
induction lsa1; intuition; simpl in *.
inversion H; clear H; subst.
simpl.
trivial.
inversion H; clear H; subst.
rewrite <- app_comm_cons.
econstructor; eauto.
Qed.
induction lsa; intuition; simpl in *.
inversion H.
econstructor.
inversion H; clear H; subst.
econstructor; eauto.
Qed.
induction 1; intuition; simpl in *.
intuition.
intuition;
subst.
econstructor; eauto.
destruct (IHrel_map b0).
trivial.
intuition.
econstructor; eauto.
Qed.
induction ls; intuition; simpl in *.
intuition; subst.
eapply H; eauto.
eapply IHls; eauto.
Qed.
induction 1; intuition; simpl in *.
econstructor.
inversion H1; clear H1; subst.
econstructor.
eapply ne_all_not_in.
intuition.
subst.
destruct (rel_map_inverse H a').
trivial.
intuition.
eapply H2.
left; eauto.
right; eauto.
intuition; subst; intuition.
eauto.
eauto.
trivial.
eapply IHrel_map; intuition.
subst.
eapply H2.
right.
eapply H3.
right.
eapply H4.
trivial.
eauto.
eauto.
trivial.
Qed.
induction 1; intuition; simpl in *.
intuition; subst.
left; eauto.
right; eauto.
Qed.
induction lsa; intuition.
exists nil.
econstructor.
destruct H0.
destruct (H a).
exists (x0 :: x).
econstructor; eauto.
Qed.
induction 1; intuition; simpl in *.
inversion H; clear H; subst.
trivial.
inversion H1; clear H1; subst.
f_equal.
eauto.
eauto.
Qed.
induction 1; intuition; simpl in *.
inversion H1; clear H1; subst.
inversion H2; clear H2; subst.
econstructor.
inversion H2; clear H2; subst.
inversion H3; clear H3; subst.
assert (b = b0).
eapply H0; eauto.
subst.
eapply perm_skip.
eauto.
inversion H1; clear H1; subst.
inversion H5; clear H5; subst.
inversion H2; clear H2; subst.
inversion H5; clear H5; subst.
assert (b0 = b1); eauto; subst.
assert (b = b2); eauto; subst.
eapply perm_trans.
eapply perm_swap.
eapply perm_skip.
eapply perm_skip.
eauto.
assert (lsb0 = lsb1).
eapply rel_map_func; eauto.
subst.
eapply Permutation_refl.
edestruct rel_map_left_total; eauto.
eapply perm_trans.
eapply IHPermutation1; eauto.
eapply IHPermutation2; eauto.
Qed.
induction lsa; intuition.
inversion H; clear H; subst.
econstructor.
inversion H; clear H; subst.
econstructor.
eapply IHlsa; eauto.
intuition.
eapply H0.
simpl.
intuition.
trivial.
Qed.
induction 1; intuition; simpl in *.
intuition.
intuition; subst.
econstructor; eauto.
edestruct IHrel_map; eauto.
intuition.
econstructor; eauto.
Qed.
(* a relational version of sumList *)
Inductive sumList_rel(A : Type)(rel : A -> Rat -> Prop) : list A -> Rat -> Prop :=
| slr_nil :
forall r,
r == rat0 ->
sumList_rel rel nil r
| slr_cons :
forall (ls : list A)(a : A) r1 r2 r3,
sumList_rel rel ls r1 ->
rel a r2 ->
r3 == r2 + r1 ->
sumList_rel rel (a :: ls) r3.
induction ls; intuition; simpl in *.
inversion H0. inversion H1. subst.
rewrite H2.
rewrite H3.
eapply leRat_trans.
eapply eqRat_impl_leRat.
eapply (ratIdentityIndiscernables 0).
intuition.
eapply rat0_le_all.
inversion H0; clear H0; subst.
inversion H1; clear H1; subst.
rewrite ratS_num.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
eapply eqRat_symm.
eapply ratMult_distrib.
}
rewrite H7.
rewrite H9.
rewrite rat_distance_of_sum.
eapply ratAdd_leRat_compat.
rewrite <- ratMult_1_r.
eapply ratMult_leRat_compat.
eapply H; eauto.
intuition.
eapply IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
inversion H.
intuition.
inversion H; clear H; subst.
rewrite H6.
rewrite (H0 a r2); eauto.
rewrite <- ratAdd_0_l.
eapply IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
intuition.
inversion H1; clear H1; subst.
inversion H; clear H; subst.
intuition; subst.
rewrite H10.
rewrite (H3 r2); eauto.
rewrite (sumList_rel_all_0_inv H5).
rewrite <- ratAdd_0_r.
intuition.
intuition.
eapply H2.
right.
eauto.
intuition; subst.
eauto.
trivial.
eapply eqRat_trans.
rewrite H10.
eapply ratAdd_eqRat_compat.
eapply H2.
left.
eauto.
intuition; subst; intuition.
trivial.
eauto.
rewrite <- ratAdd_0_l.
intuition.
Qed.
induction 1; intuition; subst.
econstructor.
rewrite <- H1.
trivial.
econstructor.
eapply IHsumList_rel.
intuition.
eapply eqRat_refl.
trivial.
eauto.
rewrite <- H3.
trivial.
Qed.
induction ls; intuition; simpl in *.
inversion H1; clear H1; subst.
inversion H2; clear H2; subst.
inversion H; clear H; subst.
rewrite H3.
rewrite H1.
rewrite H2.
rewrite <- ratAdd_0_l.
intuition.
inversion H1; clear H1; subst.
inversion H2; clear H2; subst.
inversion H; clear H; subst.
assert (r7 == r3 + r5).
eauto.
assert (r6 == r0 + r4).
eauto.
rewrite H12.
rewrite H8.
rewrite H10.
rewrite H.
rewrite H1.
repeat rewrite <- ratAdd_assoc.
eapply ratAdd_eqRat_compat; intuition.
rewrite ratAdd_assoc.
rewrite (ratAdd_comm r5).
rewrite <- ratAdd_assoc.
intuition.
Qed.
induction ls; intuition; simpl in *.
exists 0.
econstructor.
intuition.
edestruct H.
left.
eauto.
edestruct IHls.
intuition.
econstructor.
econstructor.
eauto.
eauto.
eapply eqRat_refl.
Qed.
induction ls; intuition.
inversion H; subst; clear H.
apply ratMult_0 in H0.
destruct H0.
econstructor; trivial.
exfalso.
eapply rat_num_nz; [idtac | eapply H].
eapply posnat_pos.
inversion H; clear H; subst.
symmetry in H5.
apply ratMult_inverse in H5.
rewrite ratMult_distrib_r in H5.
symmetry in H5.
econstructor; eauto.
eapply IHls.
eapply sumList_rel_body_eq.
eapply H2.
intuition.
rewrite ratMult_assoc.
rewrite <- ratMult_1_r at 1.
eapply ratMult_eqRat_compat; intuition.
rewrite <- ratMult_num_den.
symmetry.
eapply num_dem_same_rat1.
unfold posnatMult, natToPosnat, posnatToNat.
destruct p1.
destruct p2.
apply mult_comm.
trivial.
Qed.
induction 1; intuition; simpl in *.
inversion H0; clear H0; subst.
econstructor; eauto.
inversion H; clear H; subst.
inversion H2; clear H2; subst.
econstructor; eauto.
econstructor; eauto.
eapply eqRat_refl.
rewrite H5.
rewrite H7.
repeat rewrite <- ratAdd_assoc.
eapply ratAdd_eqRat_compat; intuition.
eapply ratAdd_comm.
Qed.
induction ls; intuition; simpl in *.
econstructor.
intuition.
econstructor.
eapply IHls.
intuition.
eauto.
rewrite <- ratAdd_0_l.
intuition.
Qed.
induction 1; intuition; simpl in *.
eapply sumList_rel_body_eq.
eapply sumList_rel_all_0.
intuition.
eapply H5.
eauto.
simpl.
intuition.
intuition.
intuition.
trivial.
inversion H2; clear H2; subst.
symmetry in H1.
eapply sumList_rel_body_eq; intuition; eauto.
clear H1.
clear r3.
destruct (in_dec H4 a ls2).
eapply sumList_rel_permutation.
eapply Permutation_sym.
eapply removeFirst_permutation.
eauto.
econstructor.
eapply IHsumList_rel; intuition.
eapply removeFirst_NoDup.
trivial.
eapply H5.
right.
eapply H1.
trivial.
trivial.
eapply H6.
intuition.
intuition.
eapply H2.
eapply removeFirst_in.
trivial.
intuition.
subst.
intuition.
destruct (H4 a a0); subst.
eapply H6.
intuition.
intuition.
eapply removeFirst_NoDup_not_in.
eapply H3.
eauto.
eapply H7.
eapply removeFirst_in_iff.
eauto.
simpl. intuition.
eauto.
intuition.
assert (rel a 0).
eapply H6.
intuition.
intuition.
assert (r2 == 0).
eapply H5.
eauto.
trivial.
trivial.
eapply sumList_rel_body_eq.
3:{
rewrite H2.
rewrite <- ratAdd_0_l.
eapply eqRat_refl.
}
2:{
intuition.
eauto.
}
2:{
eauto.
}
eapply IHsumList_rel; intuition.
eapply H5.
right.
eauto.
trivial.
trivial.
eapply H7.
trivial.
intuition.
subst.
intuition.
Grab Existential Variables.
trivial.
Qed.
induction ls; intuition.
unfold sumList.
simpl.
econstructor.
intuition.
unfold sumList in *. simpl in *.
econstructor.
eapply IHls.
eauto.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
eapply eqRat_refl.
intuition.
Qed.
intuition.
unfold sumList. simpl.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
eapply eqRat_refl.
intuition.
Qed.
induction ls; intuition; unfold sumList in *; simpl in *.
rewrite <- ratAdd_0_l.
intuition.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
rewrite (IHls f1 f2).
eapply eqRat_trans.
2:{
symmetry.
eapply ratAdd_eqRat_compat.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
eapply fold_add_init.
intuition.
eapply eqRat_refl.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
eapply fold_add_init.
intuition.
eapply eqRat_refl.
}
repeat rewrite <- ratAdd_assoc.
eapply ratAdd_eqRat_compat.
repeat rewrite ratAdd_assoc.
eapply ratAdd_eqRat_compat; intuition.
rewrite ratAdd_comm.
eapply ratAdd_eqRat_compat; intuition.
eapply fold_add_body_eq; intuition.
intuition.
Qed.
induction lsa; destruct lsb; intuition.
unfold sumList in *; simpl in *; intuition.
assert (sumList (b :: lsb) (fun b : B => sumList nil (fun a : A => f a b)) == 0).
eapply sumList_0.
intuition.
unfold sumList. simpl.
intuition.
rewrite H.
unfold sumList in *; simpl in *; intuition.
assert (sumList (a :: lsa) (fun a0 : A => sumList nil (fun b : B => f a0 b)) == 0).
eapply sumList_0.
intuition.
unfold sumList in *; simpl in *; intuition.
rewrite H.
unfold sumList in *; simpl in *; intuition.
rewrite sumList_body_eq.
2:{
intuition.
eapply sumList_cons.
}
rewrite sumList_sum.
rewrite (sumList_cons lsa a (fun a0 : A => sumList lsb (f a0))).
rewrite IHlsa.
symmetry.
rewrite sumList_body_eq.
2:{
intuition.
eapply sumList_cons.
}
rewrite sumList_sum.
repeat rewrite sumList_cons.
repeat rewrite <- ratAdd_assoc.
eapply ratAdd_eqRat_compat; intuition.
repeat rewrite ratAdd_assoc.
eapply ratAdd_eqRat_compat; intuition.
eapply ratAdd_comm.
Qed.
intuition.
erewrite <- matchOrder_firstn at 1.
eapply eqRat_symm.
eapply eqRat_trans.
eapply fold_add_rat_perm.
eapply matchOrder_permutation.
eapply H0.
eauto.
intuition.
eapply eqRat_refl.
intuition.
eapply eqRat_refl.
eapply eqRat_symm.
eapply fold_add_matchOrder; intuition.
eapply permutation_NoDup.
eapply matchOrder_permutation; eauto.
eauto.
eapply H3.
eapply matchOrder_In.
eapply H0.
trivial.
intuition.
eauto.
intuition.
eapply H5.
rewrite matchOrder_firstn; trivial.
trivial.
trivial.
trivial.
Grab Existential Variables.
trivial.
Qed.
intuition.
eapply fold_add_subset'; eauto.
intuition.
Qed.
induction ls; intuition.
inversion H0.
simpl in *.
inversion H; clear H; subst.
intuition; subst.
assert (sumList ls f == 0).
eapply sumList_0.
intuition.
eapply H1.
intuition.
intuition; subst; intuition.
unfold sumList in *; simpl.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
rewrite H.
rewrite <- ratAdd_0_r.
intuition.
intuition.
assert (sumList ls f == f a).
eapply IHls; intuition.
unfold sumList in *.
simpl.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
rewrite H0.
rewrite H1.
rewrite <- ratAdd_0_l.
intuition.
intuition.
intuition; subst; intuition.
intuition.
Qed.
induction 1; intuition; simpl in *.
eapply IHPermutation.
eapply ratAdd_eqRat_compat; intuition.
rewrite fold_add_body_eq.
eapply eqRat_refl.
rewrite ratAdd_assoc.
rewrite (ratAdd_comm (f y)).
rewrite <- ratAdd_assoc.
intuition.
eapply ratAdd_eqRat_compat; intuition.
eapply ratAdd_eqRat_compat; intuition.
intuition.
eapply eqRat_trans.
eapply IHPermutation1.
eapply H1.
eapply IHPermutation2.
intuition.
Qed.
intuition.
eapply fold_add_permutation; intuition.
Qed.
induction 1; intuition; subst.
econstructor.
rewrite <- H1.
trivial.
econstructor.
eapply IHsumList_rel.
intuition.
eapply eqRat_refl.
trivial.
eapply H2.
simpl.
intuition.
eauto.
rewrite <- H3.
trivial.
Qed.
induction lsa; intuition.
exists nil.
econstructor.
edestruct (IHlsa _ _ H).
intuition.
destruct (H a).
eapply H0.
simpl. intuition.
exists (x0 :: x).
econstructor; eauto.
Qed.
induction ls; intuition; subst; simpl in *.
trivial.
f_equal.
eauto.
Qed.
Fixpoint getNats s n :=
match n with
| O => nil
| S n' => (s + n')%nat :: (getNats s n')
end.
induction ls; intuition.
inversion H; clear H; subst.
econstructor.
rewrite H3.
apply ratMult_0_r.
inversion H; clear H; subst.
econstructor.
eauto.
unfold ratMult_rel.
intuition.
eapply ratMult_eqRat_compat; eauto.
rewrite H8.
eapply ratMult_distrib.
Qed.
induction n; intuition; simpl in *.
inversion H0; clear H0; subst.
inversion H1; clear H1; subst.
rewrite H0.
eapply rat0_le_all.
inversion H0; clear H0; subst.
inversion H1; clear H1; subst.
rewrite H9.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply H7.
}
eapply ratAdd_leRat_compat.
eauto.
eauto.
Qed.
induction n; intuition; simpl in *.
omega.
inversion H0; clear H0; subst.
inversion H1; clear H1; subst.
destruct n; simpl in *.
inversion H11; clear H11; subst.
inversion H12; clear H12; subst.
eapply ratSubtract_eqRat_compat.
rewrite H15.
rewrite H1.
rewrite <- ratAdd_0_r.
eauto.
rewrite H17.
rewrite H0.
rewrite <- ratAdd_0_r.
eauto.
rewrite H15.
rewrite H17.
inversion H11; clear H11; subst.
inversion H12; clear H12; subst.
assert (ratSubtract r1 r0 == ratSubtract x1 r5).
eapply IHn.
omega.
econstructor.
eapply H11.
eapply H18.
trivial.
econstructor.
eapply H10.
eapply H16.
trivial.
trivial.
trivial.
trivial.
trivial.
trivial.
trivial.
trivial.
trivial.
assert (r3 <= r2).
eauto.
assert (r0 <= r1).
rewrite H19.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply H21.
}
eapply ratAdd_leRat_compat.
eauto.
eapply series_le.
eauto.
eauto.
trivial.
rewrite ratSubtract_ratAdd_distr.
rewrite ratAdd_comm.
rewrite ratSubtract_ratAdd_assoc.
rewrite ratAdd_comm.
rewrite ratSubtract_ratAdd_assoc.
rewrite H0.
assert (r2 == r5).
eauto.
rewrite H20.
assert (x2 == r3).
eauto.
rewrite <- H22.
assert (x2 <= r5).
eauto.
assert (r5 <= x1).
eapply leRat_trans.
eapply H5.
eapply H18.
trivial.
eapply H6.
2:{
eauto.
}
2:{
eauto.
}
omega.
symmetry.
eapply ratSubtract_partition.
trivial.
trivial.
trivial.
trivial.
Qed.
intuition.
destruct H0.
assert (sumList_rel (fun i => ratMult_rel f (expRat_rel f i)) (getNats O n) (x * a)).
eapply ratMult_sumList_rel_distrib.
eapply H3.
unfold expRat_rel.
intuition.
rewrite H5; eauto.
rewrite H6; eauto.
intuition.
trivial.
trivial.
assert (ratSubtract a (x * a) == ratSubtract 1 (expRat x n)).
eapply ratSubtract_series_map; eauto.
intuition.
unfold expRat_rel, ratMult_rel in *.
simpl in *.
rewrite H6; eauto.
rewrite H7; eauto.
eapply eqRat_refl.
intuition.
eapply expRat_eqRat_compat; eauto.
unfold expRat_rel.
intuition.
simpl.
intuition.
unfold ratMult_rel, expRat_rel; intuition.
rewrite H7; eauto.
destruct n; try omega.
simpl.
eauto using ratMult_eqRat_compat, expRat_eqRat_compat.
unfold ratMult_rel, expRat_rel.
intuition.
rewrite H6; eauto.
rewrite H7; eauto.
eapply eqRat_refl.
intuition.
eapply expRat_eqRat_compat; eauto.
intuition.
eapply expRat_eqRat_compat; eauto.
unfold ratMult_rel, expRat_rel.
intuition.
rewrite H6; eauto.
rewrite H7; eauto.
eapply eqRat_refl.
intuition.
eapply expRat_eqRat_compat; eauto.
intuition.
eapply expRat_eqRat_compat; eauto.
intuition.
unfold expRat_rel, ratMult_rel in *.
rewrite H7.
2:{
eauto.
}
2:{
intuition.
}
rewrite ratMult_comm.
eapply ratMult_small_le.
case_eq (bleRat x 1); intuition.
exfalso.
eapply H2.
eauto.
eapply bleRat_total.
trivial.
unfold expRat_rel; intuition.
eapply leRat_trans.
eapply eqRat_impl_leRat.
eapply H8.
eauto.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply H7.
eauto.
}
eapply expRat_le.
case_eq (bleRat x 1); intuition.
exfalso.
eapply H2.
eauto.
eapply bleRat_total; trivial.
omega.
unfold ratMult_rel, expRat_rel.
intuition.
eapply leRat_trans.
eapply eqRat_impl_leRat.
eapply H8.
eauto.
intuition.
eapply expRat_eqRat_compat.
eauto.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply H7.
eauto.
intuition.
eapply expRat_eqRat_compat.
eauto.
}
eapply ratMult_leRat_compat.
intuition.
eapply expRat_le.
case_eq (bleRat x 1); intuition.
exfalso.
eapply H2.
eauto.
eapply bleRat_total; trivial.
omega.
unfold expRat_rel; intuition.
simpl.
intuition.
unfold ratMult_rel, ratSubtract_rel, expRat_rel, ratInverse_rel in *.
intuition.
rewrite H7; eauto.
destruct n; try omega.
simpl.
eapply ratMult_eqRat_compat; eauto.
eapply expRat_eqRat_compat; eauto.
unfold ratMult_rel, ratSubtract_rel, expRat_rel, ratInverse_rel in H4.
rewrite H4.
2:{
intuition.
rewrite H8.
rewrite <- H7.
eapply eqRat_refl.
eauto.
}
2:{
intuition.
eapply ratInverse_eqRat_compat.
2:{
rewrite H7.
eapply eqRat_refl.
eapply eqRat_refl.
eauto.
}
intuition.
eapply H2.
eauto.
apply ratSubtract_0_inv.
trivial.
}
rewrite <- (ratMult_1_l a) in H6 at 1.
eapply (@eqRat_ratMult_same_r (ratSubtract 1 x)).
intuition.
eapply H2; eauto.
eapply ratSubtract_0_inv; trivial.
rewrite ratMult_assoc.
rewrite ratInverse_prod_1.
rewrite ratMult_1_r.
rewrite ratMult_comm.
rewrite ratMult_ratSubtract_distrib_r.
trivial.
intuition.
eapply H2.
eauto.
eapply ratSubtract_0_inv; trivial.
Qed.
induction ls; intuition.
inversion H; clear H; subst.
rewrite H2.
eapply rat0_le_all.
inversion H; clear H; subst.
inversion H0; clear H0; subst.
rewrite H7.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply H9.
}
eapply ratAdd_leRat_compat.
eapply H1.
simpl.
left.
eauto.
trivial.
trivial.
eapply IHls.
eauto.
eauto.
intuition.
eapply H1.
simpl.
right.
eauto.
trivial.
trivial.
Qed.
induction ls; intuition;
unfold sumList in *; simpl in *.
intuition.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
eapply fold_add_init.
intuition.
eapply eqRat_refl.
}
destruct (P a); simpl.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
2:{
intuition.
eapply eqRat_refl.
}
rewrite fold_add_init.
eapply ratAdd_leRat_compat; intuition.
rewrite ratAdd_0_l.
eapply ratAdd_leRat_compat; intuition.
eapply rat0_le_all.
Qed.
induction ls; intuition; simpl in *.
unfold sumList.
simpl.
eapply ratAdd_0_l.
unfold sumList in *.
simpl in *.
erewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
2:{
intuition.
eapply eqRat_refl.
}
rewrite fold_add_init.
destruct (P a);
simpl.
erewrite (fold_add_body_eq (filter P ls)).
2:{
eapply ratAdd_comm.
}
2:{
intuition.
eapply eqRat_refl.
}
rewrite fold_add_init.
rewrite ratAdd_assoc.
eapply ratAdd_eqRat_compat;
intuition.
erewrite (fold_add_body_eq (filter (fun a => negb (P a)) ls)).
2:{
eapply ratAdd_comm.
}
2:{
intuition.
eapply eqRat_refl.
}
rewrite fold_add_init.
rewrite <- ratAdd_assoc.
rewrite (ratAdd_comm (fold_left (fun (a0 : Rat) (b : A) => a0 + f b) (filter P ls) 0 )).
rewrite ratAdd_assoc.
eapply ratAdd_eqRat_compat;
intuition.
Qed.
induction ls; intuition.
unfold sumList.
simpl.
econstructor.
intuition.
unfold sumList in *. simpl in *.
econstructor.
eapply IHls.
eapply eqRat_refl.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
eapply eqRat_refl.
intuition.
Qed.
induction n2; intuition; unfold sumList; simpl in *.
intuition.
rewrite fold_add_body_eq.
2:{
eapply ratAdd_comm.
}
rewrite fold_add_init.
unfold sumList in *.
rewrite IHn2; eauto.
eapply eqRat_trans.
2:{
symmetry.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
eapply fold_add_init.
}
eapply ratAdd_eqRat_compat.
eauto.
intuition.
intuition.
Qed.
induction n; intuition; unfold sumList in *; simpl in *.
eapply ratAdd_comm.
rewrite fold_add_body_eq.
2:{
rewrite ratAdd_assoc.
rewrite ratAdd_comm.
rewrite ratAdd_assoc.
rewrite (ratAdd_comm (f n ) 0).
eapply eqRat_refl.
}
rewrite fold_add_init.
rewrite IHn.
rewrite ratAdd_comm.
eapply eqRat_trans.
2:{
symmetry.
eapply ratAdd_eqRat_compat.
eapply eqRat_refl.
eapply eqRat_trans.
eapply fold_add_body_eq.
eapply ratAdd_comm.
intuition.
eapply eqRat_refl.
eapply fold_add_init.
}
rewrite (ratAdd_comm (f (S n))).
rewrite <- ratAdd_assoc.
intuition.
intuition.
Qed.
induction n; intuition; simpl in *.
Qed.
induction n; intuition; simpl in *.
destruct ls; simpl in *.
trivial.
omega.
destruct ls.
trivial.
f_equal.
eapply IHn.
simpl in *.
omega.
Qed.
induction n; intuition; simpl in *.
destruct ls1; simpl in *.
omega.
f_equal.
eapply IHn.
omega.
Qed.
induction 1; intuition.
inversion H0; clear H0; subst.
rewrite H.
rewrite H2.
intuition.
inversion H2; clear H2; subst.
rewrite H1.
rewrite H9.
eapply ratAdd_eqRat_compat;
eauto.
Qed.
induction ls; intuition.
unfold sumList; simpl in *.
eapply ratAdd_0_l.
repeat rewrite sumList_cons.
destruct (P a);
rewrite ratMult_0_r;
rewrite <- ratAdd_0_l;
rewrite ratMult_1_r;
rewrite IHls.
rewrite ratAdd_assoc.
intuition.
rewrite (ratAdd_comm (sumList ls (fun a0 : A => f a0 * (if P a0 then 1 else 0)))).
rewrite <- ratAdd_assoc.
rewrite <- ratAdd_comm.
intuition.
Qed.
induction ls; intuition.
unfold sumList; simpl in *.
intuition.
rewrite sumList_cons.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
rewrite sumList_cons.
eapply eqRat_refl.
}
simpl in *.
eapply ratAdd_leRat_compat.
eapply H.
intuition.
eapply IHls.
intuition.
Qed.
induction ls; intuition.
unfold sumList; simpl in *.
eapply eqRat_impl_leRat.
rewrite <- ratIdentityIndiscernables.
intuition.
repeat rewrite sumList_cons.
rewrite rat_distance_of_sum.
eapply ratAdd_leRat_compat.
eapply eqRat_impl_leRat.
eapply ratMult_ratDistance_factor_l.
eapply IHls.
Qed.
induction ls; intuition.
unfold sumList; simpl.
symmetry.
eapply ratMult_0_l.
rewrite sumList_cons.
simpl in *.
rewrite H; intuition.
rewrite IHls; intuition.
rewrite ratMult_comm.
rewrite ratMult_ratAdd_cd.
simpl.
eapply ratMult_comm.
Qed.
induction ls1; intuition; simpl in *.
case_eq (f a); intuition.
rewrite <- app_comm_cons.
f_equal.
eauto.
Qed.
induction ls; intuition; simpl in *.
case_eq (f a); intuition.
f_equal.
eauto.
rewrite H in H0.
discriminate.
intuition.
Qed.
induction ls1; intuition; simpl in *.
unfold sumList; simpl.
eapply rat0_le_all.
inversion H; clear H; subst.
rewrite sumList_cons.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply (@sumList_permutation _ _ _ (a :: removeFirst (EqDec_dec _) ls2 a)%list).
eapply removeFirst_permutation.
eapply H1.
intuition.
}
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
eapply sumList_cons.
}
eapply ratAdd_leRat_compat; intuition.
eapply IHls1; intuition.
eapply removeFirst_NoDup.
trivial.
destruct (EqDec_dec _ a a0).
subst.
intuition.
eapply removeFirst_in.
eapply H1; intuition.
intuition.
Qed.
Fixpoint allNatsLt (n : nat) :=
match n with
| 0 => nil
| S n' => allNatsLt n' ++ (n' :: nil)
end.
induction n; intuition; simpl in *.
rewrite app_length.
rewrite IHn.
rewrite plus_comm.
trivial.
Qed.
induction n; intuition; simpl in *.
intuition.
apply in_app_or in H.
simpl in *.
intuition.
Qed.
induction ls1; intuition.
inversion H; clear H; subst.
rewrite <- app_comm_cons.
econstructor.
intuition.
eapply in_app_or in H.
intuition.
eapply H1.
simpl.
left.
eauto.
trivial.
eapply IHls1; eauto.
intuition.
eapply H1.
simpl.
right.
eauto.
eauto.
intuition.
eapply H1.
simpl.
right.
eauto.
eauto.
Qed.
induction n; simpl in *; intuition.
econstructor.
eapply app_NoDup; intuition.
econstructor.
simpl; intuition.
econstructor.
simpl in *.
intuition; subst.
eapply allNatsLt_lt in H.
omega.
simpl in *.
intuition; subst.
eapply allNatsLt_lt in H0.
omega.
Qed.
induction n; intuition; simpl in *.
omega.
eapply in_or_app.
destruct (lt_dec i n).
left.
eauto.
right.
simpl.
intuition.
Qed.
induction k; intuition; simpl in *.
destruct (lt_dec n k).
rewrite app_nth1.
eauto.
rewrite allNatsLt_length.
trivial.
rewrite app_nth2.
rewrite allNatsLt_length.
assert (k = n).
omega.
rewrite H0.
rewrite minus_diag.
simpl.
trivial.
rewrite allNatsLt_length.
omega.
Qed.
intuition.
destruct (lt_dec n k).
eapply nth_allNatsLt_lt; intuition.
eapply nth_overflow.
rewrite allNatsLt_length.
omega.
Qed.
induction p; intuition.
simpl.
assert (n = 0%nat). omega.
subst. trivial.
simpl.
destruct (le_dec n p).
rewrite filter_app.
rewrite IHp; intuition.
simpl.
destruct (lt_dec p n ).
omega.
eapply app_nil_r.
assert (n = S p).
omega.
subst.
simpl.
rewrite filter_app.
f_equal.
eapply filter_true.
intuition.
destruct (lt_dec a (S p)); intuition.
apply allNatsLt_lt in H0.
omega.
simpl.
destruct (lt_dec p (S p)); intuition.
Qed.
induction ls; intuition; simpl in *.
intuition.
intuition; subst.
inversion H; clear H; subst.
trivial.
inversion H; clear H; subst.
eapply IHls; intuition.
Qed.
induction ls; intuition; simpl in *.
f_equal.
eapply H.
intuition.
eapply IHls.
intuition.
Qed.
intuition.
specialize (map_eq_all _ _ _ H); intros.
eapply map_eq_if_all.
intuition.
Qed.
Fixpoint getSomes(A : Type)(ls : list (option A)) :=
match ls with
| nil => nil
| o :: ls' =>
match o with
| None => getSomes ls'
| Some x => x :: (getSomes ls')
end
end.
induction i; intuition; simpl in *.
Qed.
induction n; intuition; simpl in *.
destruct ls; simpl in *.
eapply Permutation_refl.
subst.
eapply Permutation_refl.
destruct ls; simpl in *.
eapply (IHn nil).
eapply nth_nil.
destruct o.
eapply Permutation_sym.
eapply perm_trans.
eapply perm_swap.
eapply perm_skip.
eapply Permutation_sym.
eapply IHn.
trivial.
eapply IHn.
trivial.
Qed.
induction 1; intuition.
eapply perm_trans.
eapply listReplace_None_Permutation.
trivial.
rewrite <- H.
eapply Permutation_refl.
eapply perm_trans.
eapply listReplace_None_Permutation.
trivial.
rewrite <- H0.
eapply perm_skip.
eapply perm_skip.
trivial.
eapply perm_trans.
eapply listReplace_None_Permutation.
trivial.
rewrite <- H.
eapply perm_skip.
eapply perm_swap.
eapply perm_trans.
eapply listReplace_None_Permutation.
trivial.
rewrite <- H1.
eapply perm_skip.
eapply perm_trans.
eapply H.
trivial.
Qed.
intuition.
eapply listReplace_getSomes_Permutation_h; eauto.
Qed.
induction i1; destruct i2; destruct ls; intuition; simpl in *.
destruct i1; trivial.
rewrite IHi1.
eapply nth_nil.
omega.
eapply IHi1.
omega.
Qed.
induction ls; intuition; simpl in *.
omega.
destruct i; simpl in *.
trivial.
f_equal.
eapply IHls.
omega.
Qed.
induction i; intuition; simpl in *.
intuition.
intuition.
Qed.
induction ls; intuition; simpl in *.
right.
eapply listReplace_in_nil.
eauto.
destruct i; simpl in *.
intuition.
intuition.
edestruct (IHls); eauto.
Qed.
induction ls; destruct n; intuition; simpl in *.
f_equal.
eauto.
Qed.
induction ls1; intuition; simpl in *.
f_equal.
eauto.
Qed.
induction ls; destruct i; intuition; simpl in *.
omega.
omega.
eapply IHls.
omega.
Qed.
induction ls1; intuition; simpl in *.
rewrite <- app_assoc.
f_equal.
eauto.
Qed.
(* list_pred lifts a predicate on A and B to a predicate on list A and list B.  It is useful for reasoning about fold, map, etc. *)
Inductive list_pred(A B : Set)(pred : A -> B -> Prop) : list A -> list B -> Prop :=
| list_pred_nil :
list_pred pred nil nil
| list_pred_cons :
forall a1 a2 ls1 ls2,
pred a1 a2 ->
list_pred pred ls1 ls2 ->
list_pred pred (a1 :: ls1) (a2 :: ls2).
induction 1; intuition; simpl in *; subst.
f_equal; eauto.
Qed.
induction 1; intuition; simpl in *; subst.
f_equal.
eauto.
Qed.
induction ls2; intuition; simpl in *.
f_equal.
eauto.
Qed.
induction n; intuition; simpl in *.
Qed.
induction ls; intuition; simpl in *.
intuition.
intuition; subst.
exists O.
trivial.
edestruct IHls.
eauto.
exists (S x).
eauto.
Qed.
induction y; intuition; simpl in *.
rewrite plus_0_r.
trivial.
destruct ls.
rewrite nth_nil.
rewrite nth_nil.
trivial.
rewrite plus_comm.
simpl.
rewrite plus_comm.
eapply
IHy.
Qed.
induction b; intuition; simpl in *.
Qed.
induction b; intuition; simpl in *.
destruct ls1.
simpl in *.
apply Permutation_nil in H.
subst.
eapply Permutation_refl.
simpl in *.
rewrite <- app_cons_eq.
eapply Permutation_trans.
eapply Permutation_app_comm.
rewrite <- app_comm_cons.
econstructor.
eapply Permutation_trans.
eapply Permutation_app_comm.
trivial.
destruct ls1.
simpl in *.
eapply Permutation_nil in H.
subst.
eapply perm_flatten_listReplace_nil .
simpl in *.
eapply Permutation_trans.
eapply Permutation_app.
eapply Permutation_refl.
eapply IHb.
eapply Permutation_refl.
eapply Permutation_trans.
eapply Permutation_app_comm.
rewrite <- app_comm_cons.
econstructor.
eapply Permutation_trans.
eapply Permutation_app_comm.
trivial.
Qed.
intuition.
Qed.
induction ls1; destruct ls3; intros; simpl in *; subst.
intuition.
omega.
omega.
inversion H0; clear H0; subst.
specialize (IHls1 ls2 ls3 ls4).
intuition.
f_equal.
eapply IHls1; intuition; omega.
eapply IHls1; intuition; omega.
Qed.
induction ls1; intros; simpl in *.
intuition.
econstructor.
inversion H; clear H; subst.
eapply IHls1 in H3.
intuition.
econstructor.
intuition.
trivial.
subst.
eapply H2.
eapply in_or_app.
intuition.
subst.
eapply H3; eauto.
Qed.
induction n; destruct ls; intuition; simpl in *;
intuition.
Qed.
induction 1; intuition; simpl in *.
destruct H.
subst.
eapply in_app_or in H1.
intuition.
eapply in_or_app.
left.
eapply firstn_In.
eauto.
Qed.
induction n; destruct ls; intuition; simpl in *.
econstructor.
inversion H; clear H; subst.
econstructor.
intuition.
eapply H2.
eapply firstn_In.
eauto.
eapply IHn; intuition.
Qed.
induction 1; intuition; simpl in *.
destruct H.
subst.
eapply NoDup_app in H1.
intuition.
eapply app_NoDup; intuition.
eapply firstn_NoDup.
trivial.
eapply H3.
eapply firstn_In.
eauto.
eapply pred_firstn_In.
eauto.
eauto.
intuition.
eapply H3.
eapply firstn_In.
eauto.
eapply pred_firstn_In.
eauto.
eauto.
intuition.
Qed.
destruct n; intuition; simpl in *.
eapply app_eq_nil in H.
intuition.
discriminate.
Qed.
induction ls using rev_ind; intuition; simpl in *.
symmetry in H0.
eapply allNatsLt_nil_inv in H0.
subst.
assert (n1 = O).
omega.
subst.
simpl.
trivial.
destruct n2; simpl in *.
eapply app_eq_nil in H0.
intuition.
discriminate.
eapply app_inj_tail in H0.
intuition.
subst.
destruct (le_gt_dec n1 (length (allNatsLt n2))).
rewrite firstn_app.
eapply (@IHls); eauto.
rewrite allNatsLt_length.
trivial.
trivial.
rewrite allNatsLt_length in g.
assert (n1 = (S n2)).
omega.
subst.
eapply firstn_ge_all.
rewrite allNatsLt_length.
intuition.
Qed.
intuition.
eapply firstn_allNatsLt_h;
eauto.
Qed.
intuition.
eapply NoDup_app in H.
intuition.
Qed.
induction ls; intros; simpl in *.
intuition.
econstructor.
inversion H; clear H; subst.
intuition.
econstructor.
intuition.
eapply H2.
eapply in_map_iff.
econstructor.
intuition.
trivial.
subst.
trivial.
subst.
exfalso.
eapply H2.
eapply in_map_iff.
econstructor.
split.
symmetry.
eapply H5.
trivial.
subst.
exfalso.
eapply H2.
eapply in_map_iff.
econstructor.
split.
eapply H5.
trivial.
Qed.
induction lsc; destruct ls; intuition; simpl in *.
omega.
f_equal.
eauto.
Qed.
induction lsc; destruct ls; intuition; simpl in *.
omega.
f_equal.
eauto.
Qed.
induction lsa; intuition; simpl in *.
intuition.
destruct lsb.
simpl in *.
intuition.
inversion H; clear H; subst.
simpl in *.
intuition.
repeat pairInv.
trivial.
pairInv.
eapply in_combine_r in H0.
intuition.
pairInv.
eapply in_combine_r in H.
intuition.
eauto.
Qed.
induction lsa; intuition; simpl in *.
intuition.
destruct lsb.
simpl in *.
intuition.
inversion H; clear H; subst.
simpl in *.
intuition.
repeat pairInv.
trivial.
pairInv.
eapply in_combine_l in H0.
intuition.
pairInv.
eapply in_combine_l in H.
intuition.
eauto.
Qed.
induction lsa; intuition; simpl in *.
destruct lsb; simpl in *.
omega.
discriminate.
Qed.
induction ls1; intuition; simpl in *.
specialize (IHls1 ls2).
remember (split (ls1 ++ ls2)) as z.
destruct z.
remember (split ls1) as y.
destruct y.
simpl in *.
subst.
trivial.
Qed.
induction ls; intuition; simpl in *.
rewrite  fst_split_app_eq .
f_equal.
trivial.
Qed.
induction ls; intuition; simpl in *.
remember (f a) as z.
destruct z.
remember (split (map f ls)) as y.
destruct y.
simpl.
f_equal.
assert (l = fst (split (map f ls))).
rewrite <- Heqy.
trivial.
subst.
eauto.
Qed.
induction ls; intuition; simpl in *.
intuition.
remember (split ls) as z.
destruct z.
simpl in *.
intuition.
subst.
econstructor; intuition.
edestruct IHls; eauto.
Qed.
induction ls; intuition; simpl in *.
intuition.
pairInv.
remember (split ls) as z.
destruct z.
simpl.
intuition.
remember (split ls) as z.
destruct z.
simpl in *.
right.
eapply IHls.
eauto.
Qed.
induction ls1; destruct ls2; intuition; simpl in *.
discriminate.
inversion H; clear H; subst.
trivial.
Qed.
induction ls; intuition; simpl in *.
intuition.
intuition.
pairInv.
intuition.
right.
eapply IHls.
eauto.
intuition.
pairInv.
trivial.
eapply IHls; eauto.
Qed.
induction 1; intuition; simpl in *.
econstructor.
econstructor; eauto.
Qed.
induction ls; intuition; simpl in *.
econstructor.
econstructor.
intuition.
eapply list_pred_impl.
eapply IHls.
intuition.
intuition.
intuition.
intuition.
Qed.
induction lsa; intuition; simpl in *.
destruct lsb; intuition.
f_equal.
eauto.
Qed.
induction 1; intuition; simpl in *.
destruct a1.
destruct a2.
remember (split ls1) as z.
destruct z.
remember (split ls2) as z.
destruct z.
simpl in *.
subst.
trivial.
Qed.
induction ls; intuition; simpl in *.
remember (split ls) as z.
destruct z.
unfold unzip.
simpl.
f_equal.
f_equal.
assert (l = fst (l, l0)).
trivial.
rewrite H.
rewrite <- IHls.
trivial.
assert (l0 = snd (l, l0)).
trivial.
rewrite H.
rewrite <- IHls.
f_equal.
Qed.
induction ls; intuition; simpl in *.
intuition.
remember (split ls) as z.
destruct z.
simpl in *.
intuition.
subst.
econstructor.
intuition.
edestruct IHls.
eauto.
econstructor.
right.
eauto.
Qed.
(* There is nth_error in the Coq library, but it seems to return something in Type. *)
Fixpoint nth_option(A : Set)(ls : list A)(i : nat) :=
match ls with
| nil => None
| a :: ls' =>
match i with
| O => Some a
| S i' =>
nth_option ls' i'
end
end.
induction ls1; intuition; simpl in *.
congruence.
destruct i; trivial.
eauto.
Qed.
induction ls; intuition; simpl in *.
discriminate.
destruct i.
omega.
eapply lt_n_S.
eauto.
Qed.
induction ls1; intuition; simpl in *.
destruct i.
discriminate.
eauto.
Qed.
induction ls; intuition; simpl in *.
destruct i.
discriminate.
eapply le_n_S.
eapply IHls.
trivial.
Qed.
induction ls; intuition; simpl in *.
discriminate.
destruct n; simpl in *.
inversion H; clear H; subst.
trivial.
eauto.
Qed.
induction ls; intuition; simpl in *.
discriminate.
destruct n.
inversion H; clear H; subst.
remember (split ls) as z.
destruct z.
simpl.
trivial.
remember (split ls) as z.
destruct z.
simpl in *.
eauto.
Qed.
induction ls; intuition; simpl in *.
remember (f a) as z.
destruct z.
remember (split (map f ls)) as z.
destruct z.
simpl.
f_equal.
assert (l0 = snd (l, l0)).
trivial.
rewrite H.
rewrite Heqz0.
eapply IHls.
Qed.
intuition.
destruct (eqda a1 a2).
subst.
right.
intuition.
subst.
intuition.
left.
intuition.
Qed.
induction ls; intuition; simpl in *.
eapply cons_ne in H0.
destruct H0.
econstructor.
intuition.
intuition.
destruct H2.
intuition.
exists x.
intuition.
trivial.
Qed.
induction lsa; destruct lsb; intuition; simpl in *.
econstructor.
discriminate.
discriminate.
econstructor.
intuition.
eapply list_pred_impl.
eapply IHlsa.
omega.
intuition.
intuition.
intuition.
Qed.
induction a; intuition; simpl in *.
inversion H; clear H; subst.
trivial.
inversion H; clear H; subst.
simpl.
remember (split a0) as z.
destruct z.
simpl in *.
f_equal.
eapply IHa.
trivial.
Qed.
induction a; intuition; simpl in *.
inversion H; clear H; subst.
trivial.
inversion H; clear H; subst.
simpl.
rewrite fst_split_app_eq.
f_equal.
eapply list_pred_fst_split_eq_l .
trivial.
eauto.
Qed.
induction ls; intuition; simpl in *.
rewrite IHls.
omega.
Qed.
induction 1; intuition; simpl in *.
subst.
destruct a1.
remember (split ls1) as z.
destruct z.
simpl.
trivial.
Qed.
induction ls; intuition; simpl in *.
econstructor.
remember (split ls) as z.
destruct z.
destruct a.
simpl in *.
inversion H; clear H; subst.
econstructor.
intuition.
eapply in_split_r in H.
rewrite <- Heqz in H.
simpl in *.
intuition.
intuition.
Qed.
Fixpoint forNats(n : nat) :=
match n with
| 0 => nil
| S n' =>
cons n' (forNats n')
end.
induction n; intuition; simpl in *.
omega.
intuition.
destruct (lt_dec i n).
right.
eapply IHn.
trivial.
left.
omega.
intuition.
eapply lt_trans.
eapply IHn.
trivial.
omega.
Qed.
induction n; intuition; simpl in *;
econstructor; intuition.
assert (n < n).
eapply forNats_In.
trivial.
omega.
Qed.
induction n; intuition; simpl in *.
f_equal; intuition.
Qed.
induction n; intuition; simpl in *.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
rewrite sumList_cons.
eapply eqRat_refl.
}
destruct n.
eapply leRat_trans.
rewrite ratAdd_0_r.
eapply leRat_refl.
eapply ratAdd_leRat_compat; intuition.
eapply rat0_le_all.
rewrite ratAdd_0_l.
eapply ratAdd_leRat_compat; intuition.
eapply rat0_le_all.
Qed.
intuition.
destruct (eq_nat_dec n O).
subst.
simpl.
unfold sumList.
simpl.
eapply eqRat_trans.
rewrite <- ratIdentityIndiscernables.
intuition.
symmetry.
rewrite <- ratIdentityIndiscernables.
intuition.
assert (sumList (forNats n) f == (ratSubtract (sumList (forNats n) f) (f O)) + (f O)).
induction n; intuition.
simpl.
repeat rewrite sumList_cons.
destruct n.
simpl.
unfold sumList.
simpl.
rewrite <- ratAdd_0_r.
rewrite ratSubtract_0.
rewrite <- ratAdd_0_l.
intuition.
intuition.
rewrite IHn.
rewrite ratSubtract_ratAdd_assoc.
rewrite ratSubtract_ratAdd_assoc; intuition.
rewrite (@ratSubtract_0 (f O)); intuition.
rewrite <-ratAdd_0_r.
symmetry.
eapply ratAdd_assoc.
eapply leRat_trans.
eapply eqRat_impl_leRat.
eapply ratAdd_0_l.
eapply ratAdd_leRat_compat; intuition.
eapply rat0_le_all.
intuition.
rewrite H.
clear H.
assert (sumList (forNats n) (fun i : nat => f (S i)) == (ratSubtract (sumList (forNats n) f) (f O)) + (f n)).
induction n; intuition.
simpl.
repeat rewrite sumList_cons.
destruct n.
simpl.
unfold sumList.
simpl.
repeat rewrite <- ratAdd_0_r.
rewrite ratSubtract_0; intuition.
rewrite <- ratAdd_0_l.
intuition.
rewrite IHn.
rewrite ratAdd_comm.
eapply ratAdd_eqRat_compat; intuition.
rewrite ratSubtract_ratAdd_assoc.
rewrite ratAdd_comm.
intuition.
eapply sumList_forNats_first_ls;
intuition.
intuition.
rewrite H.
eapply ratDistance_add_same_l.
Qed.
induction ls; intuition; simpl in *.
f_equal; intuition.
Qed.
induction ls1; intuition; simpl in *.
intuition.
subst.
inversion H; clear H; subst.
eapply H3.
eapply in_or_app.
intuition.
inversion H; clear H; subst.
eapply IHls1;
eauto.
Qed.

Lemma flatten_NoDup :
forall (A : Set)(ls : list (list A)),
NoDup ls ->
(forall x, In x ls -> NoDup x) ->
(forall x1 x2, In x1 ls -> In x2 ls -> x1 <> x2 -> NoDup (x1 ++ x2)) ->
NoDup (flatten ls).