Set Implicit Arguments.
(*Require ne_list.*)
Require ne_tree.
Definition C := ne_tree.T.
Definition ret {A: Set}: A -> C A := @ne_tree.Leaf A.
Fixpoint bind (A B: Set) (m: C A) (k: A -> C B): C B :=
match m with
| ne_tree.Leaf a => k a
| ne_tree.Node ts => ne_tree.Node (ne_list.map (fun x => bind x k) ts)
end.
Let runit (a b: Set) (x: a) (f: a -> C b): bind (ret x) f = f x.
Definition M: Monad := Build_Monad C bind (@ret) runit lunit assoc.
Proof with auto.
unfold extMonad.
induction x using ne_tree.alt_ind; simpl...
replace (ne_list.map (fun x: C A => bind x f) l) with (ne_list.map (fun x: C A => bind x g) l)...
generalize H0. clear H0.
induction l; simpl; intros; rewrite H0...
rewrite IHl...
Qed.
Definition deterministic (X: Set) (x: M X) (v: X): Prop := x = ne_tree.Leaf v.

Lemma bind_eq (X X' Y XM: Set)
(f: X -> M Y) (f': X' -> M Y)
(xm: X -> XM) (xm': X' -> XM):
(forall p q, xm p = xm' q -> f p = f' q) ->
forall (x: M X) (x': M X'),
ne_tree.map xm x = ne_tree.map xm' x' ->
bind x f = bind x' f'.