220 likes | 349 Views
自然数の定義. 自然数Nは 0 か (add1 n) である,ここで n は自然数である. (add1 0) を 1 , (add1 (add1 0)) を 2, ... と書く この定義は,リストの定義と似ている リストは empty か (cons x alist) である,ここで alist はリストである.. 自然数の操作とリストの操作の比較. cons には, first と rest があった sub1 (1を引く)が rest に対応する (sub1 (add1 n)) = n (rest (cons x alist)) = alist.
E N D
自然数の定義 • 自然数Nは • 0 か • (add1 n)である,ここでnは自然数である. • (add1 0)を1,(add1 (add1 0))を2, ...と書く • この定義は,リストの定義と似ている • リストは • emptyか • (cons x alist)である,ここでalistはリストである.
自然数の操作とリストの操作の比較 • consには,firstとrestがあった • sub1(1を引く)がrestに対応する • (sub1 (add1 n)) = n • (rest (cons x alist)) = alist
自然数の関数の基本形 (define (func-on-nat n) (cond [(zero? n) …] [else …(func-on-nat (sub1 n))…])) (- n 1)と書いても良い
'helloがn個からなるプログラム ;; hellos: N -> list of symbols ;; n個の記号'helloからなるリストを作る (define (hellos n) (cond [(zero? n) empty] [else (cons 'hello (hellos (sub1 n)))]))
階乗を計算するプログラム (define (! n) (cond [(zero? n) 1] [else (* n (! (sub1 n)))]))
整列(sort):単純挿入法 ;; sort : list-of-numbers -> list-of-numbers ;; 与えられたリストを降順に並べたリストを返す (define (sort nums) (cond [(empty? nums) empty] [else ;;(cons? nums) (insert (first nums) (sort (rest nums)))]))
挿入(insert) ;; insert : number list-of-numbers (sorted) -> list-of-numbers ;; 数nと降順に並べられたリストnumsから、nとnumsの数か ;; らなる降順に並べたリストを返す。 (define (insert n nums) (cond [(empty? nums) (cons n empty)] [else (cond [(<= (first nums) n) (cons n nums)] [(> (first nums) n) (cons (first nums) (insert n (rest nums)))])]))
リストを用いた多角形のデータ構造 • A polygon は • (cons p empty), p は posn • (cons p apoly) ,p は posn でapolyは polygon • 例 (list (make-posn 10 10) (make-posn 60 60) (make-posn 10 60) )
多角形を描く (define (draw-polygon apoly) (cond [(empty? (rest apoly)) true] [else (and (draw-solid-line (first apoly) (second apoly)) (draw-polygon (rest apoly)))])) • 2点間に実線を引く • 真(#t)を返す
多角形を描く (正しいプログラム) ;; draw-polygon : polygon -> true ;; 多角形を描く.結果として真を返す (define (draw-polygon apoly) (draw2-polygon (cons (last apoly) apoly))) ;; draw2-polygon: polygon -> true ;; to draw connections between the dots of a-poly (define (draw2-polygonapoly) (cond [(empty? (rest apoly)) true] [else (and (draw-solid-line (first apoly) (second apoly)) (draw2-polygon(rest apoly)))]))
last ;; last : polygon -> posn ;; 多角形の最後の点を取り出す (define (last apoly) (cond [(empty? (rest apoly)) (first apoly)] [else (last (rest apoly))]))
再帰的な構造:家系図 Carl (1926)green Bettina (1926)green Adam (1950)yeloow Dave(1955)black Eva (1965)blue Fred (1966)pink Gustav (1988)brown
Childのデータ構造の定義 • child 構造: • (define-struct child (father mother name date eyes)) • father及びmotherは,父の家系図(child構造) • nameは名前 • dateは生年 • eyesは目の色
Childのデータ構造の定義 • (make-child f m aname adate aeyes) • f 及び mは,以下のどちらか • empty • child構造 • anameは,記号 • adateは,数 • aeyesは,記号
再帰的な構造:家系図 Carl (1926)green Bettina (1926)green (define Carl (make-child empty empty 'Carl 1926 'green)) (define Bettina (make-child empty empty 'Bettina 1926 'green)) (define Adam (make-child CarlBettina 'Adam 1950 'yellow)) Adam (1950)yeloow
blue-eyed-ancestor? : ftn -> boolean ;; blue-eyed-ancestor? : ftn (family tree node) -> boolean ;; ;; 家系図に,青い目を持つ祖先(自分も含めて)いるかを判定する (define (blue-eyed-ancestor? a-ftree) ...)
答えの例 (blue-eyed-ancestor? Gustav) = true (blue-eyed-ancestor? Eva) = true (blue-eyed-ancestor? Dave) = false
blue-eyed-ancestor? のプログラム ;; blue-eyed-ancestor? : ftn (family tree node) -> boolean ;; 家系図に,青い目を持つ祖先(自分も含めて)いるかを判定する (define (blue-eyed-ancestor? a-ftree) (cond [(empty? a-ftree) false] [else (cond [(symbol=? (child-eyes a-ftree) 'blue) true] [(blue-eyed-ancestor? (child-father a-ftree)) true] [(blue-eyed-ancestor? (child-mother a-ftree)) true] [else false])]))
blue-eyed-ancestor? のプログラム ;; blue-eyed-ancestor? : ftn (family tree node) -> boolean ;; 家系図に,青い目を持つ祖先(自分も含めて)いるかを判定する (define (blue-eyed-ancestor? a-ftree) (cond [(empty? a-ftree) false] [else (or (symbol=? (child-eyes a-ftree) 'blue) (blue-eyed-ancestor? (child-father a-ftree)) (blue-eyed-ancestor? (child-mother a-ftree)))]))
数式のインタープリタ • Schemeの数式をデータとして入力して,評価値を返す • Schemeの数式は次のように表現する • (define-struct add (left right)) • (define-struct mul (left right))
数式のインタプリタ 変数を含まない場合 (define (myeval exp) (cond [(number? exp) exp] [(add? exp) …] [(mul? exp) …])) (add-left exp)と(add-right exp)の値を再帰的に計算