(**
  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.(**
  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.(**
  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).

Theorem BTree_rassoc_thm : forall t u : BTree, BTree_is_rassoc (node t u) = true -> BTree_is_rassoc u = true.