2019-l08-imperative programming languages-5...

22
2019/6/3 1 プログラミング言語論 (Concepts on Programming Languages) 趙 建軍 情報知能工学部門 1 命令型言語 (5) (Imperative Programming Languages) 抽象データ型 (データの抽象などについて解説する) 2019.06.06 2 第8回

Upload: others

Post on 06-Jul-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

2019/6/3

1

プログラミング言語論(Concepts on Programming Languages)

趙 建軍情報知能工学部門

1

命令型言語 (5)(Imperative Programming Languages)

抽象データ型(データの抽象などについて解説する)

2019.06.062

第8回

2019/6/3

2

3

今日の講義

抽象とは 抽象データ型とは 抽象データ型の諸概念、利点 ADTのバリエーション データ不変条件

4

抽象 (abstraction)とは

多くの物や事柄や具体的な概念から、それらの範囲の全部に共通な属性を抜き出し、これを一般的な概念としてとらえること

事物や表象を, ある性質・共通性・本質に着目し, それを抽き出して把握すること

(三省堂 大辞林から )

反対語は、具体的、具象 (concrete)

2019/6/3

3

5

抽象 (abstraction): 例1

6

抽象 (abstraction): 例2

2019/6/3

4

抽象化とは

抽象化(Abstraction)とは、思考における手法のひとつで、対象から注目すべき要素を重点的に抜き出して他は無視する方法である

反対に、ある要素を特に抜き出して、これを無視したり、切り捨てる意味もあり、この用法については捨象するという

従って、抽象と捨象は盾の両面といえる

7

8

抽象化: 例

2019/6/3

5

9

プログラミングでの2つの抽象

抽象はプログラミングで2つの側面から使われる

具体的な実現方法を捨象して、機能に注目

プロセスの抽象 (process abstraction)

データ(型)の抽象 (data abstraction)

10

2019/6/3

6

11

プロセスの抽象 (process abstraction)

一連の手続きを括りだして、抽象化する サブルーチン、手続き、関数

そのルーチンの実現方法 (実装) を抽象し(気にせずに) 次のことのみに注目 そのルーチンの機能 そのルーチンの呼出し方: プロトコル、イン

ターフェース

12

プロセスの抽象: 例

機能: リストを順番に並べる 呼出し方: sort (リスト,リストの長さ) 順番に並べるための方法は気にしない

2019/6/3

7

クイックソート(Quick Sort)

13

14

データ抽象 (data abstraction)

データの情報内容と情報内容の操作のみを気にすればよい仕掛け どのようにメモリー内で記憶されているか どのような型定義によって実現されている

かは気にしない

これを実現するための考え方: 抽象データ型(abstract data type) オブジェクト指向プログラミング (Object-

oriented programming)

2019/6/3

8

15

抽象データ型とは

抽象データ型 (abstract data type, ADT)とは、データ構造とそれを直接操作する手続きをまとめてデータ型の定義とすることでデータ抽象を実現する手法またはそのひとまとまりとして定義されたデータ型を言う

ADT = properties + operations

ADT=データ型+データに対する操作

16

抽象データ型とは

データ構造とそれに付随する操作をひとまとまりに表現したもの

型とそれに付随する操作からなる。これは、言語が提供する型(int 型など)と同様に新たな型を定義することができる機構である

これと同様に抽象データ型の値を使うプログラムは抽象データ型の実装が変わっても影響を受けない

2019/6/3

9

17

抽象データ型 抽象データ型は次の2組からなる: データ型 (その型の変数の取りうる値の範囲)

そのデータ型のデータに対する操作 (手続き、関数)

抽象データ型を定(さだ)めると、 クライアントはそのデータ型を宣言することができる 与えられた手続きによってデータを操作できる

ADTをサポートする言語は、 ADTの具体的な実現方法(=その抽象データ型の実

装)を記述できる ADTの実装を隠蔽することができる

※クライアント=ADTを利用する側のルーチン

18

抽象データ型の例 スタックを扱うADT stack 型を考える クライアントは stack 型の変数を宣言できる

var stk1: stack; stack 型のデータを操作する手続きがある

create(stk1) stk1を新たなスタックとして用意し、初期化する

destroy(stk1) stk1の使用をやめる(メモリーを解放する)

empty(stk1) stk1を空のスタックに初期化する。

push(stk1,elm) 要素elmをstk1に積む。

elm := pop(stk1) stk1に積まれている最上位の要素を取り出す。

2019/6/3

10

抽象データ型の例:Stack

スタックポインタの指している個所が、データの先頭

19

データ1データ2データ3

PUSH DOWN POP UP

スタックポインタ

(SP)

スタックポインタ(SP)

抽象データ型の例:Stack

20

2019/6/3

11

抽象データ型の例:Stack

21

22

スタック型の実現 (1)

type stack = recordtop : integer;content : array[1..maxsize] of element

end;

proc create(s : stack);prepare memory for s;s.top :=0;

proc destroy(s : stack);release memory for s;

proc empty(s: stack);s.top :=0;

proc push(s:stack; e:element);if top=maxsize then errorelse s.top:=s.top+1; s.content[s.top]:=e;

func top(s:stack):element;if s.top=0 then errorelse s.top:=s.top-1; return s.content[s.top+1];

3

abc・・・

top

content

1 2 3

max -size

c

b

a

2019/6/3

12

23

スタック型の実現 (2)type cell = record content : element;

next : pointer to cellend;

stack = pointer to cell

proc create(s : stack);s=nil;

proc destroy(s : stack);var t : pointer to cell;while s<>nil do t := s.next; release(s); s:=t;

proc empty(s: stack);destroy(s);

proc push(s:stack; e:element);var t : pointer to cell;new(t); t.content:=e; t.next:=s;

func pop(s:stack):element;var t : pointer to cell; e : element;e:=t.content; t:=s; s:=t.next;release(t); return e;

c

b

a

c b a nil

24

スタックの操作

ADTとして定義されたデータは、実現法によらず操作できる必要があるvar stk1 : stack

create(stk1);

push(stk1,a);

push(stk1,b);

x:=pop(stk1);

push(stk1,c);

push(stk1,d);

x:=pop(stk1);

nil

a nil

b a nil

a nil

c a nil

d c a nil

c a nil

0

…1a

2ab…

1a

2ac

…3acd…2

ac

2019/6/3

13

手続きとスタック

再帰呼出しでは、各呼出し毎に局所変数が上書きされることなく、保存されなければならない 呼出し毎に、スタック上にフレームを重かさね

る 再帰呼出しから戻る際には、スタックフレー

ムを順に「ほぐして」戻る

25

手続きとスタック

例: nの階乗を再帰的に計算する関数 fact により、3の階乗を計算

26

fun fact(n) =if n≦1 then 1 else n*fact(n-1);

fact (3) ; // 3の階乗

2019/6/3

14

手続きとスタック

まず、fact(3) がコールされる

27

fact(3)のフレーム SP

手続きとスタック

fact(3) の中で、“3*fact(2)”を計算するため、 fact(2) をコール

28

fact(3)のフレームfact(2)のフレーム SP

2019/6/3

15

手続きとスタック

fact(2) の中で、“2*fact(1)”を計算するため、 fact(1) をコール

29

fact(3)のフレームfact(2)のフレームfact(1)のフレーム SP

手続きとスタック

fact(1) が、値「1」をかえす fact(2) が、値「2」をかえす fact(3) が、値「6」をかえす

30

fact(3)のフレームfact(2)のフレームfact(1)のフレーム SP

2019/6/3

16

31

抽象データ型の例:Queue

32

抽象データ型の例:Queue

2019/6/3

17

33

基本データ型とADT

基本データ型は元々ADTである 浮動小数点型が、どのようなビットパターン

で実現されているか、普段は気にしない 浮動小数点型のデータを操作する演算がはじ

めから用意されている その演算を使用せず、直接ビット操作をする

ことは許されていない

基本データ型はクライアントがその実現を気にせずに使うことができるので、組み込みのADTと考えられる

34

抽象データ型の利点

カプセル化 (encapsulation)と情報隠蔽 (information hiding) クライアントに必要な情報のみにアクセスを許す

実現の隠蔽 (implementation hiding)と表現独立(representation independence) データ構造に依存しない操作方法を提供する 実装方法が変わってもユーザプログラムの変更が要

らない

データ抽象は考え方であり、実際には上述の概念を提供する仕掛けを与えることが目標

2019/6/3

18

カプセル化と情報隠蔽

カプセル化 (encapsulation) データ構造と操作を一まとめにし、 特定のインタフェースを通してのみ外部

と通信できる

抽象データ型を実現 モジュール間の独立性を保証 他のソースコードに依存しない

35

カプセル化と情報隠蔽

情報隠蔽 (information hiding) データ構造を使用者から隠し、必要な情

報のみを公開する

使用者側のプログラムは、提供側の実装に依存しない

36

情報隠蔽は、カプセル化が本質的に持つ性質である

2019/6/3

19

カプセル化と情報隠蔽

情報隠蔽の利点 利用者側プログラムは、提供者側プログラ

ムの公開部分にだけ注目すればよい 提供者は、非公開部分のプログラムは自由

に変更できる

37

相互に、依存性が減少

カプセル化と情報隠蔽

データや操作の公開範囲 公開インタフェースと、プライベートイン

タフェースに二分される

公開範囲を多段階に制御することも多い Java は4種類のアクセス属性を持つ

(public, protected, private, 指定なし)

38

2019/6/3

20

カプセル化

スタックの例 (Java)

39

class ArrayStack {private Object[] stack = new Object[100];private int stackPointer = 0;public void push(Object element) {

stck[stackPointer++] = element;}public Object pop() {

return stack[--stackPointer];}

}

ここは情報隠蔽

ここは情報公開ここは情報公開

40

データの安全性とデータ不変条件

ADTはデータの操作を安全な操作に限定している

データが安全とは、予め決められた条件を満足していること

データの操作中以外は、この条件は常に満足しているべき

これをデータ不変条件 (data invariant) という

2019/6/3

21

41

データ不変条件: 例

stack型のデータ不変条件:

0 ≦ top ≦ maxsize

top = 0 ならば、スタックは空

Top = maxsize ならば、スタックは満杯

0<top<maxsize なら、top 個のデータが挿入順と逆に入っている

42

データ不変条件

データ不変条件中心にADTを設計するとよい

データ不変条件を決定する データの操作を決定する。ここまででADT

が決まる データ構造、操作の実装を決める

ADTの理論的基礎づけ: 公理的、代数的記述と関連

2019/6/3

22

43

まとめ

抽象はプログラミング(だけでなく、工学)での重要概念

ADTはデータの機能面に注目し、実装を隠す

ADT=データ型+データに対する操作

ADTは、 クライアントに実装を隠蔽、プログラム開発用容

易にする 実装の置き換えを容易にする 安全な操作のみをクライアントに許し、データ不

変条件を守る