プログラミング Haskell 第13章 プログラムの論証 練習問題 その4
最終章「プログラムの論証」の練習問題です。ついに最後です。
- 9.
以下の型が与えられているとする data Tree = Leaf Int | Node Tree Tree この木の葉の個数は、節の個数よりも、常に1多いことを示す まず葉の個数を数える関数 countLeaf と、節の個数を数える関数 countNode を定義する countLeaf :: Tree -> Int countLeaf (Leaf _) = 1 countLeaf (Node l r) = (countLeaf l) + (contLeaf r) countNode :: Tree -> Int countNode (Leaf _) = 0 countNode (Node l r) = (countNode l) + (countNode r) + 1 この時任意の Tree t について countLeaf t = 1 + countNode t が成り立つことを示せばよい。 t = Leaf n の時 (左辺) => countLeaf (Leaf n) => 1 -- countLeaf の定義より (右辺) => 1 + countNode (Leaf n) => 1 + 0 -- countNode の定義より => 1 t = Node l r の時 countLeaf l = 1 + countNode l countLeaf r = 1 + countNode r は成り立つと仮定する (左辺) => countLeaf (Node l r) => (countLeaf l) + (countLeaf r) => (1 + countNode l) + (countLeaf r) -- l についての仮定より => (1 + countNode l) + (1 + countNode r) -- r についての仮定より => 1 + ((countNode l) + (countNode r) + 1) -- 分配則より => 1 + countNode (Node l r) -- countNode の定義を逆に適用 = (右辺) よって任意の Tree t について葉の数は常に節の数+1になる
- 10. comp' e c = comp e ++ c を満たすような comp' の定義が欲しい
(本文で定義されている comp とそれに関連する型の定義) data Expr = Val Int | Add Expr Expr data Op = PUSH Int | ADD type Code = [Op] comp :: Expr -> Code comp (Val n) = [PUSH n] comp (Add x y) = comp x ++ comp y ++ [ADD] e = Val n の時 (右辺) comp (Val n) ++ c => [ PUSH n ] ++ c => (PUSH n) : c e = Add l r の時 (右辺) comp (Add l r) ++ c => comp l ++ comp r ++ [ADD] ++ c => comp l ++ comp r ++ (ADD:c) => comp l ++ (comp' r (ADD:c)) => comp' l (comp' r (ADD:c)) よって以下の定義を得る comp' :: Expr -> Code -> Code comp' (Val n) c = (PUSH n) : c comp' (Add l r) c = comp' l (comp' r (ADD:c))
ついに「プログラミング Haskell」の本文も終わりました。あとは付録を読んで終了です。
次に読むのは「プログラミングコンテストチャレンジブック」にしようかなと思ってます。