Section eval.
Variables (T : Type) (idx : T) (op : T -> T -> T).
Inductive env := Empty | ENode of T & env & env.
Definition pos := fix loop (e : env) p {struct e} :=
match e, p with
| ENode t _ _, 1%positive => t
| ENode t e _, (p~0)%positive => loop e p
| ENode t _ e, (p~1)%positive => loop e p
| _, _ => idx
end.
Definition set_pos (f : T -> T) := fix loop e p {struct p} :=
match e, p with
| ENode t e e', 1%positive => ENode (f t) e e'
| ENode t e e', (p~0)%positive => ENode t (loop e p) e'
| ENode t e e', (p~1)%positive => ENode t e (loop e' p)
| Empty, 1%positive => ENode (f idx) Empty Empty
| Empty, (p~0)%positive => ENode idx (loop Empty p) Empty
| Empty, (p~1)%positive => ENode idx Empty (loop Empty p)
end.
Definition cforall N T : env N -> (env T -> Type) -> Type := env_rect (@^~ Empty)
(fun _ e IHe e' IHe' R => forall x, IHe (fun xe => IHe' (R \o ENode x xe))).

Lemma cforallP N T R : (forall e : env T, R e) -> forall (e : env N), cforall e R.