Section binary_trees.
(** Represents the values stored in binary trees. *)
Variable Term : Set.
(** Represents binary trees.  Binary trees can be used to represent many different types of algebraic expressions. Importantly, when flattened, they are isomorphic with lists. Flattening, projecting onto lists, sorting, and folding may be used normalize ("simplify") algebraic expressions. *)
Inductive BTree : Set
:= leaf : Term -> BTree
|  node : BTree -> BTree -> BTree.
(** Accepts a binary tree and returns true iff the tree is a node term. *)
Definition BTree_is_node
:  BTree -> bool
:= BTree_rec
(fun _ => bool)
(fun _ => false)
(fun _ _ _ _ => true).
(** Accepts a binary tree and returns true iff the tree is a leaf term. *)
Definition BTree_is_leaf
:  BTree -> bool
:= BTree_rec
(fun _ => bool)
(fun _ => true)
(fun _ _ _ _ => false).
(** Accepts a binary tree and returns true iff the tree is right associative.  Note: right associative trees are isomorphic to lists. *)
Definition BTree_is_rassoc
:  BTree -> bool
:= BTree_rec
(fun _ => bool)
(fun _ => true)
(fun t _ _ f
=> BTree_is_leaf t && f).

(** Proves that the right subtree in a right associative binary tree is also right associative. *)
Theorem BTree_rassoc_thm
:  forall t u : BTree, BTree_is_rassoc (node t u) = true -> BTree_is_rassoc u = true.