PROGRAMMING IN HASKELL

Slides:



Advertisements
Similar presentations
アルゴリズムと データ構造 第 3 回 基本的なデータ構造(2) : 配列 1. 前回の復習 アルゴリズムの計算量 最悪(最大)計算量 計算量の漸近的評価 (オーダ)  多項式時間アルゴリズム( polynomial time algorithm )  指数時間アルゴリズム( exponential.
Advertisements

0章 数学基礎.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
(Rubyistのための) 超音速:ML入門
第3回 論理式と論理代数 本講義のホームページ:
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
京都大学情報学研究科 通信情報システム専攻 湯淺研究室 M2 平石 拓
Relaxed Dependency Analysis
ソフトウェア基礎科学 授業資料: 論理関係(logical relations)のお話
はじめに 教科書 プログラミングHaskell Graham Hutton (著), 山本 和彦 (翻訳) オーム社、全 232 ページ
型宣言 (Type Declarations)
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
型宣言(Type Declarations)
論理式の表現を数学的に取り扱いやすくするために代数学の助けを借りる.
香川大学工学部 富永浩之 情報数学1 第5-2章 命題論理式の 同値変形とカルノー表 香川大学工学部 富永浩之
Semantics with Applications
香川大学工学部 富永浩之 情報数学1 第2-1章 合同式の性質と計算 香川大学工学部 富永浩之
アルゴリズムとデータ構造 2011年6月13日
条件式 (Conditional Expressions)
データ構造と アルゴリズム 知能情報学部 新田直也.
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
プログラミング言語論 第12回 関数型プログラミング 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
PROGRAMMING IN HASKELL
4 ソフトウェア工学 Software Engineering 抽象データ型 ABSTRACT DATA TYPE.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
プログラミング言語論 第3回 BNF記法について(演習付き)
形式言語の理論 5. 文脈依存言語.
PROGRAMMING IN HASKELL
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
PROGRAMMING IN HASKELL
6. リスト処理関数の設計(発展版) プログラミング論 I.
 型推論1(単相型) 2007.
Structural operational semantics
ATTAPL輪講 (第4回) 続 Dependent Types
オブジェクトのプロパティ プロパティとは? あたかもそういうメンバー変数(フィールド)がそのクラスに存在するかのように見せる仕組み!
書き換え型プログラムの生成・検証 研究課題:適切な実行戦略を効率よく探索する、 より自動化された手続きの実現 書き換え型プログラム
フロントエンドとバックエンドのインターフェース
プログラミング言語論 第9回 情報工学科 木村昌臣 篠埜 功.
コンパイラ 2011年10月20日
Type Systems and Programming Languages
補講:アルゴリズムと漸近的評価.
計算の理論 I -数学的概念と記法- 火曜 12:50~14:20 大月 美佳 2004年4月20日.
アルゴリズムとデータ構造 2012年6月11日
PROGRAMMING IN HASKELL
計算の理論 I -数学的概念と記法- 月曜3校時 大月 美佳.
香川大学創造工学部 富永浩之 情報数学1 第2-1章 合同式の性質と計算 香川大学創造工学部 富永浩之
2006/7/18(通信コース)2006/7/26(情報コース) 住井
PROGRAMMING IN HASKELL
関数型言語の基礎 型なしl計算 型理論 構成的プログラミング GUIにあらわれる関数概念 PBD VL
全体ミーティング 2010/05/19 渡邊 裕貴.
~sumii/class/proenb2010/ml5/
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
香川大学工学部 富永浩之 情報数学1 第5-2章 命題論理式の 同値変形とカルノー表 香川大学工学部 富永浩之
コンパイラ 2012年10月11日
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
PROGRAMMING IN HASKELL
プログラミング演習I 2003年6月11日(第9回) 木村巌.
Haskell Programming Language
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
情報処理Ⅱ 小テスト 2005年2月1日(火).
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
C言語講座 四則演算  if ,  switch 制御文.
プログラミング演習II 2003年10月29日(第2,3回) 木村巌.
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
Presentation transcript:

PROGRAMMING IN HASKELL Chapter 13 – Reasoning about Programming プログラムの論証 愛知県立大学 情報科学部 計算機言語論(山本晋一郎・大久保弘崇、2011年)講義資料 オリジナルは http://www.cs.nott.ac.uk/~gmh/book.html を参照のこと

等式推論 中学高校で学ぶ式の変形は、数と演算子に対する代数的性質を利用している 例: 加算や乗算について成り立つ性質 性質を用いた論証の例 x y = y x {* の交換則} x + (y + z) = (x + y) + z {+ の結合則} x (y + z) = x y + x z {* の + に対する左分配則} (x + y) z = x z + y z {* の + に対する右分配則} 性質を用いた論証の例 (x + a) (x + b) {左分配則} = (x + a) x + (x + a) b {右分配則} = x x + a x + x b + a b {* の交換則} = x^2 + a x + b x + a b {右分配則を右辺から左辺へ} = x^2 + (a + b) x + a b (x + a) (x + b) と x^2 + (a + b) x + a b は等しいが、 計算は前者の方が効率的(加算 2 回と乗算 1回)

Haskell に対する論証 同様に、Haskell のプログラムに対して成立する 性質を論証しよう 利用者が与えた等式は性質として使える 以下の定義 double :: Int  Int double x = x + x は、プログラムに関する論証で使用できる性質 任意の Int 型の式 a に対して、double a を a + a に置き換えて良い 左辺から右辺、右辺から左辺のどちらにも使える

Haskell に対する論証 複数の等式による関数定義に注意 ガード付き等式による等価な定義 定義式の順序は重要 isZero :: Int  Bool isZero 0 = True {常に使える} isZero n = False {n ≠ 0 の場合のみ} ガード付き等式による等価な定義 順序を気にしなくて良いので使いやすい isZero 0 = True {常に使える} isZero n | n ≠ 0 = False {常に使える}

reverse と ++ の定義(復習) reverse :: [a]  [a] -- p.167 reverse [] = [] reverse (x:xs) = reverse xs ++ [x] (++) :: [a]  [a]  [a] -- p.60 [] ++ ys = ys (x:xs) ++ ys = x:(xs ++ ys)

Haskell に対する論証の例 要素が 1 つのリストを反転しても意味がない こと reverse [x] = [x] の証明 reverse [x] {リスト表記} = reverse (x:[]) {reverse の定義 2} = reverse [] ++ [x] {reverse の定義 1} = [] ++ [x] {++ の定義 1} = [x] {よって成立、証明終了} プログラム中の reverse [x] は [x] と置き換えても 良く、より効率的になる

整数に対する数学的帰納法 全ての有限な自然数に対して成り立つ性質を証明したい 例: 全ての自然数 x に対して x + 0 = 0 全部を数え上げることはできない 数学的帰納法の出番 ただし、数学の話ではなく、Haskell 上に定義した自然数を対象とする 自然数の定義の例(10 章) data Nat = Zero | Succ Nat

再帰型による自然数(10 章)の復習

Succ :: Nat  Nat を持つ新しい型 再帰型 データ型は自分自身を使って定義することもできる。 すなわち、型は再帰的に定義されることもある。 data Nat = Zero | Succ Nat Nat は 2 つの構成子 Zero :: Nat と Succ :: Nat  Nat を持つ新しい型

Note: Nat 型の値は Zero か、あるいは Succ n の形をしている(ただし、n :: Nat)。すなわち、Nat は以下のような値の無限列を含む: Zero Succ Zero Succ (Succ Zero) 

Nat 型の値は自然数とみなせる。すなわち、Zero は 0 を、Succ は 1 つ大きな整数を返す関数 (1+) を表している。 例えば、以下の値は、 Succ (Succ (Succ Zero)) 自然数の 3 を表している 1 + (1 + (1 + 0)) 3 =

再帰型による自然数(10 章)の復習終わり

add x Zero = x の証明 加算の定義 全ての自然数 x に対して、 add x Zero = x が成り立つことを数学的帰納法で示してみる x = Zero のとき add Zero Zero {add の定義 1} = Zero {よって成立} x = n のときに add n Zero = n が成り立つと仮定する   add (Succ n) Zero {add の定義 2} = Succ (add n Zero) {帰納法の仮定} = Succ n {よって成立、証明終了} add Zero n = n add (Succ m) n = Succ (add m n)

add x (add y z) = add (add x y) z の証明 x = Zero のとき 左辺 = add Zero (add y z) {外側の add} = add y z 右辺 = add (add Zero y) z {内側の add} = add y z {よって成立} x = n のときに add n (add y z) = add (add n y) z    が成り立つと仮定する 左辺 = add (Succ n) (add y z) {外側の add} = Succ (add n (add y z)) {帰納法の仮定} = Succ (add (add n y) z) 右辺 = add (add (Succ n) y) z {内側の add} = add (Succ (add n y)) z {外側の add} = Succ (add (add n y) z) {よって成立、証明終了}

リストに対する数学的帰納法 整数に対する数学的帰納法 リストに対する数学的帰納法 対応関係 全ての整数 x に対して P(x) が成立することを示す 例: 全ての自然数 x に対して add x Zero = x リストに対する数学的帰納法 全てのリスト xsに対して P(xs) が成立することを示す 例: 全てのリスト xs に対して reverse (reverse xs) = xs 対応関係 基底 帰納段階 整数 P(0) が成立 P(x) を仮定し、 P(x+1) を示す リスト P([]) が成立 P(xs) を仮定し、 P(x:xs) を示す

reverse (reverse xs) = xs の証明 rev (rev []) {内側の rev の定義 1} = rev [] {rev の定義 1} = [] {よって成立} xs = ns のときに rev (rev ns) = ns が成り立つと仮定する rev (rev (n:ns)) {内側の rev の定義 2} = rev (rev ns ++ [n]) {rev の ++ に対する分配則} = rev [n] ++ rev (rev ns) {長さ 1 のリストの反転} = [n] ++ rev (rev ns) {帰納法の仮定} = [n] ++ ns {長さ 1 のリストの ++} = n:ns {よって成立、証明終了} 長さ 1 のリストの反転 rev [x] = [x] rev の ++ に対する分配則 rev (xs ++ ys) = rev ys ++ rev xs 長さ 1 のリストの結合 [x] ++ xs = x:xs

まとめ(12章) Haskell のプログラムの性質を論証する リストに対する数学的帰納法 (++) や reverse などのライブラリの性質は利用可能 長さ 1 のリストの反転 rev [x] = [x] rev の ++ に対する分配則 rev (xs ++ ys) = rev ys ++ rev xs 長さ 1 のリストの結合 [x] ++ xs = x:xs 利用者が与えた等式も性質として利用可能 定義 double x = x + x が与えられたら 任意の式 a に対して、double a を a + a に置き換えて良い 左辺から右辺、右辺から左辺のどちらにも使える リストに対する数学的帰納法 全てのリスト xs に対して P(xs) が成立することを示す 例: 全てのリスト xs に対して reverse (reverse xs) = xs データ構成子による場合分けが有用 整数なら Zero と Succ x、リストなら [] と x:xs で場合分け

全体のまとめ(型の観点から、No.1) 基本型 リスト型(同じ型の値の並び (0個以上)) タプル型(n 項組) Bool, Char, Int, Integer, Float リスト型(同じ型の値の並び (0個以上)) null, elem {述語} length {長さ} head, last, (!!) {要素の抽出} tail, init, take, drop {部分リストの抽出} (++), concat {連結} zip {タプルのリスト} map, filter {単純なリスト内包表記} リスト内包表記 タプル型(n 項組) () {unit 型 (意味のない値を表す)} fst, snd {要素の抽出}

全体のまとめ(型の観点から、No.2) 関数型 関数定義方法 ラムダ記法 (値としての関数を表す記法) 条件文 引数のパターンマッチ ガード付き等式 再帰定義 畳込関数 (foldr, foldl) リスト内包表記 (map, filter) ラムダ記法 (値としての関数を表す記法) カリー化 (Haskell の関数は 1 引数) 多相型 (型変数を含む型) 多重定義型 (型のテンプレート)

全体のまとめ(型の観点から、No.3) 利用者定義の型 クラス (型のテンプレート) type 宣言 (別名) data 宣言 (新しい型を定義) データ構成子 クラス (型のテンプレート) Eq (同等) Ord (順序)  Show (文字列化), Read (読み込み可能) Num (数値,除算なし) Integral (整数,商と余り), Fractional (分数,除算と逆数) Monad (return と bind を備える)

全体のまとめ(型の観点から、No.4) その他の重要な型 Maybe a Parser a IO a エラーを考慮した値を表す型 type Maybe a = Just a | Nothing Parser a a 型の値を返すパーサー type Parser a = String  [(a,String)] 読み込んだ a と読み残した String のタプルを返す 失敗: 空リスト 成功(受理): 要素が 1 つのリスト(singleton list) IO a 副作用を持つ型 入出力を表す