リスト構造

自然数の定義

自然数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) )
多角形を描く
• 2点間に実線を引く
• 真(#t)を返す
(define (draw-polygon apoly)
(cond
[(empty? (rest apoly)) true]
[else (and (draw-solid-line (first apoly)
(second apoly))
(draw-polygon (rest apoly)))]))
多角形を描く (正しいプログラム)
;; 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-polygon apoly)
(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
Adam (1950)
yeloow
Bettina (1926)
green
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))
Adam (1950)
yeloow
(define Bettina
(make-child empty empty 'Bettina 1926 'green))
(define Adam
(make-child Carl Bettina 'Adam 1950 'yellow))
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))
Schemeの数式の表現
Schemeのプログラム 表現
3
3
x
‘x
(* 3 11)
(make-mul 3 11)
(+ (* 3 3)(* 4 4))
(make-add (make-mul 3 3)(make-mul 4 4))
(* 1/2 (* 3 3))
(make-mul 1/2 (make-mul 3 3))
(+ (+ x x) (* y y))
(make-add (make-add 'x 'x)(make-mul 'y
'y))
数式のインタプリタ
変数を含まない場合
(define (myeval exp)
(cond
[(number? exp) exp]
[(add? exp) …]
[(mul? exp) …]))
(add-left exp)と(add-right exp)
の値を再帰的に計算