プログラミング Haskell 第13章 プログラムの論証 練習問題 その3
最終章「プログラムの論証」の練習問題です。
- 6. 13.5 の reverse (reverse xs) = xs の証明とここで提示された証明で 13.5 の証明のほうが良い理由を示せ、という難しい問題ですが、おそらくここで提示されている補助定理は 13.5 で利用されている補助定理から導ける粒度の大きい定理なので、小さい汎用性のある部品を使って証明するほうが良い、ということでしょうか。
- 7.
以下の定義が与えられているものとする map f [] = [] - (a1) map f (x:xs) = f x : map f xs - (a2) (f . g) x = f (g x) - (b) map f (map g xs) = map (f . g) xs を示す xs = [] の時 (左辺) => map f (map g []) => map f [] -- (a1) より => [] -- (a1) より (右辺) => map (f . g) [] => [] -- (a1) より x = n:ns として map f (map g ns) = map (f . g) ns が成り立つと仮定する (左辺) => map f (map g (n:ns)) => map f (g n : map g ns) -- (a2) より => f (g n) : map f (map g ns) -- (a2) より => f (g n) : map (f . g) ns -- 仮定より => (f . g) n : map (f . g) ns -- (b) より => map (f . g) (n:ns) -- (a2) を逆向きに適用 = (右辺)
- 8.
以下の定義が与えられているものとする take 0 _ = [] - (a1) take (n+1) [] = [] - (a2) take (n+1) (x:xs) = x : take n xs - (a3) drop 0 xs = xs - (b1) drop (n+1) [] = [] - (b2) drop (n+1) (_:xs) = drop n xs - (b3) take n xs ++ drop n xs = xs を示す n = 0 のとき (左辺) => take 0 xs ++ drop 0 xs => [] ++ drop 0 xs -- (a1) より => [] ++ xs -- (b1) より => xs -- ++ の定義より = (右辺) また xs = [] のとき (左辺) => take n [] ++ drop n [] => [] ++ drop n [] -- (a2) より => [] ++ [] -- (b2) より => [] -- ++ の定義より = (右辺) n = m + 1, xs = (y:ys) として take m ys ++ drop m ys = ys が成り立つと仮定する (左辺) => take (m+1) (y:ys) ++ drop (m+1) (y:ys) => (y : take m ys) ++ drop (m+1) (y:ys) -- (a3) => (y : take m ys) ++ drop m ys -- (b3) => y : (take m ys ++ drop m ys) -- ++ の結合則より => y : ys -- 仮定より = (右辺)