lemma ht_height[simp]: "avl t \ ht t = height t" by (cases t rule: tree2_cases) simp_all
text\<open>First, a fast but relatively manual proof with many lemmas:\<close>
lemma height_balL: "\ avl l; avl r; height l = height r + 2 \ \
height (balL l a r) \<in> {height r + 2, height r + 3}" by (auto simp:node_def balL_def split:tree.split)
lemma height_balR: "\ avl l; avl r; height r = height l + 2 \ \
height (balR l a r) : {height l + 2, height l + 3}" by(auto simp add:node_def balR_def split:tree.split)
lemma height_node[simp]: "height(node l a r) = max (height l) (height r) + 1" by (simp add: node_def)
lemma height_balL2: "\ avl l; avl r; height l \ height r + 2 \ \
height (balL l a r) = 1 + max (height l) (height r)" by (simp_all add: balL_def)
lemma height_balR2: "\ avl l; avl r; height r \ height l + 2 \ \
height (balR l a r) = 1 + max (height l) (height r)" by (simp_all add: balR_def)
lemma avl_balL: "\ avl l; avl r; height r - 1 \ height l \ height l \ height r + 2 \ \ avl(balL l a r)" by(auto simp: balL_def node_def split!: if_split tree.split)
lemma avl_balR: "\ avl l; avl r; height l - 1 \ height r \ height r \ height l + 2 \ \ avl(balR l a r)" by(auto simp: balR_def node_def split!: if_split tree.split)
text\<open>Insertion maintains the AVL property. Requires simultaneous proof.\<close>