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.

Lemma fold_add_eq : forall (A : Set)(ls : list A)(f1 f2 : A -> Rat) init1 init2,
fold_left (fun r a => r + (f1 a)) ls init1 +
fold_left (fun r a => r + (f2 a)) ls init2 ==
fold_left (fun r a => r + (f1 a + f2 a)) ls (init1 + init2).