namespace Mutual mutual inductive Tree (α : Type u) where | node : TreeList α → Tree α | leaf : α → Tree α inductive TreeList (α : Type u) where | nil : TreeList α | cons : Tree α → TreeList α → TreeList α end mutual def Tree.size : Tree α → Nat | Tree.node l => -- see "TODO: linarith" in Init.WFTactics have : sizeOf l < 1 + sizeOf l := by rw [Nat.add_comm] apply Nat.lt_succ_self sizeList l | Tree.leaf _ => 1 -- use automatically synthesized size function, which is not quite the number of leaves termination_by t => sizeOf t def Tree.sizeList : TreeList α → Nat | TreeList.nil => 0 | TreeList.cons t l => have : sizeOf t < 1 + sizeOf t + sizeOf l := by rw [Nat.add_comm 1, Nat.add_assoc, Nat.add_comm 1, ← Nat.add_assoc] apply Nat.lt_succ_of_le apply Nat.le_add_right have : sizeOf l < 1 + sizeOf t + sizeOf l := by rw [Nat.add_comm 1, Nat.add_assoc, Nat.add_comm 1, ← Nat.add_assoc] apply Nat.lt_succ_of_le apply Nat.le_add_left t.size + sizeList l termination_by l => sizeOf l end end Mutual namespace Nested inductive Tree (α : Type u) where | node : List (Tree α) → Tree α | leaf : α → Tree α mutual def Tree.size : Tree α → Nat | Tree.node l => have : sizeOf l < 1 + sizeOf l := by rw [Nat.add_comm] apply Nat.lt_succ_self sizeList l | Tree.leaf _ => 1 termination_by t => sizeOf t def Tree.sizeList : List (Tree α) → Nat | [] => 0 | t :: l => have : sizeOf t < 1 + sizeOf t + sizeOf l := by rw [Nat.add_comm 1, Nat.add_assoc, Nat.add_comm 1, ← Nat.add_assoc] apply Nat.lt_succ_of_le apply Nat.le_add_right have : sizeOf l < 1 + sizeOf t + sizeOf l := by rw [Nat.add_comm 1, Nat.add_assoc, Nat.add_comm 1, ← Nat.add_assoc] apply Nat.lt_succ_of_le apply Nat.le_add_left t.size + sizeList l termination_by l => sizeOf l end end Nested