Section expec_ctors.
Variables (T: Set) (f: T -> nat).
End expec_ctors.
(* misc expec *)
Add Parametric Morphism (A: Set): (@expec A)
with signature (@ext_eq A nat) ==> (@ext_eq (ne_tree.T A) R)
as expec_ext_morph.
Proof with auto.
induction t.
repeat rewrite expec_Leaf.
apply plus_INR.
repeat rewrite expec_Node_one...
repeat rewrite expec_Node_cons.
rewrite IHt.
rewrite IHt0.
field...
Qed.
Hint Resolve expec_nonneg.
Proof with auto with real.
induction t; intros.
simpl.
repeat rewrite expec_Leaf...
repeat rewrite expec_Node_one...
repeat rewrite expec_Node_cons.
apply Rmult_le_compat_r...
apply Rplus_le_compat...
apply Rmult_le_compat_r...
apply IHt0.
intros.
apply H.
right.
inversion_clear H0...
Qed.
Proof with auto with real.
induction t.
simpl.
intros.
inversion_clear H0.
apply arith_lems.INR_0_inv...
simpl.
rewrite expec_Node_one.
intros.
inversion_clear H0.
inversion_clear H1...
rewrite expec_Node_cons.
intros.
inversion_clear H0.
destruct (arith_lems.Rmult_0_inv H).
assert (expec f t = 0).
apply Rplus_eq_0_l with (expec f (ne_tree.Node l) * INR (length (ne_list.to_plain l)))...
apply Rmult_le_pos...
assert (expec f (ne_tree.Node l) = 0).
rewrite Rplus_comm in H0.
cut (expec f (ne_tree.Node l) * INR (length (ne_list.to_plain l)) = 0).
intro.
destruct (arith_lems.Rmult_0_inv H3)...
cset (arith_lems.INR_0_inv _ H4).
destruct l; discriminate.
apply Rplus_eq_0_l with (expec f t)...
apply Rmult_le_pos...
inversion_clear H1...
elimtype False.
apply (Rinv_neq_0_compat (INR (S (length (ne_list.to_plain l)))))...
Qed.

Lemma expec_constant (T: Set) (f: T -> nat) (c: nat) (t: ne_tree_monad.M T):
(forall x, ne_tree.In x t -> f x = c) -> expec f t = INR c.