Let us revisit the canonical type of polymorphic binary trees with payloads in their leaves:
type 'a binary_tree =
| Leaf of 'a
| Node of 'a binary_tree * 'a binary_tree;;
The width of a binary tree is the largest number of leaves and nodes at the same depth, and the goal here is to write an OCaml function that given a binary tree, computes its width.
Intuitively, the unit-test function is simple to write – for any given binary tree, draw it and measure its width:
let test_width_int candidate_width =
(* test_width_int : (int binary_tree -> int) -> bool *)
let b0 = (candidate_width (Leaf 1)
= 1)
and b1 = (candidate_width (Node (Leaf 1,
Leaf 2))
= 2)
and b2 = (candidate_width (Node (Leaf 1,
Node (Leaf 1,
Leaf 2)))
= 2)
and b3 = (candidate_width (Node (Node (Leaf 1,
Leaf 2),
Leaf 2))
= 2)
and b4 = (candidate_width (Node (Node (Leaf 1,
Leaf 2),
Node (Leaf 3,
Leaf 4)))
= 4)
and b5 = (candidate_width (Node (Node (Node (Leaf 1,
Leaf 2),
Leaf 2),
Node (Node (Leaf 3,
Leaf 4),
Node (Leaf 5,
Leaf 6))))
= 6)
and b6 = (candidate_width (Node (Node (Node (Node (Leaf 1,
Leaf 2),
Leaf 2),
Leaf 2),
Node (Node (Leaf 3,
Node (Leaf 3,
Leaf 4)),
Node (Leaf 5,
Leaf 6))))
= 6)
(* etc. *)
in b0 && b1 && b2 && b3 && b4 && b5 && b6;;
For example,
Expand the unit-test function above with your own tests, and justify them. (For example, does mirroring a tree preserve its width?)
Specify width inductively, implement it with a structurally recursive OCaml function, and verify that it passes the unit tests.
To make sure that your implementation is structurally recursive, express it using fold_binary_tree (and verify that it still passes the unit tests).
For your convenience (and information), the accompanying resource file contains a simple imperative implementation of width to test the unit-test function with random trees. This simple implementation
By the way, why does this imperative implementation work?
Fixed a typo in the error message in the accompanying .ml file [19 Apr 2020]
Created [23 Apr 2019]