induction ls; intuition; simpl in *.
inversion H; clear H; subst.
destruct (in_dec eqd a u).
unfold setLet.
rewrite IHls; trivial.
rewrite (@fold_add_nat_Permutation _ _ (intersect eqd (a :: ls) u) (intersect eqd u (a :: ls))).
simpl.
destruct (in_dec eqd a u); intuition.
simpl.
repeat rewrite (@fold_add_init_nat _ _ _ (f a)).
rewrite <- minus_plus_simpl_l_reverse.
f_equal.
eapply fold_add_nat_Permutation.
eapply intersect_comm_Permutation; intuition.
eapply intersect_comm_Permutation; intuition.
econstructor; eauto.
unfold setLet.
rewrite (@fold_add_nat_Permutation _ _ (intersect eqd (a :: ls) u) (intersect eqd u (a :: ls))); trivial.
simpl.
destruct (in_dec eqd a u); intuition.
repeat rewrite (@fold_add_init_nat _ _ _ (f a)).
rewrite IHls.
rewrite minus_plus_assoc.
f_equal.
f_equal.
eapply fold_add_nat_Permutation.
eapply intersect_comm_Permutation; intuition.
rewrite (@fold_add_nat_filter_partition _ (fun a => if (in_dec eqd a u) then true else false) _ ls).
rewrite <- plus_0_r at 1.
eapply plus_le_compat; intuition.
trivial.
trivial.
eapply intersect_comm_Permutation; intuition.
econstructor; eauto.
Qed.

Lemma fold_add_nat_0 :
forall (A : Set)(ls : list A)(f : A -> nat),
(forall a, In a ls -> f a = O) ->
fold_left (fun acc a => acc + (f a))%nat ls O = O.