An Introduction to Guarded Horn Clauses

59
An Introduction to 並行論理型言語GHCの紹介 【見覚え】 小林浩一 (koichik) 【あります】

description

2007年頃のJavaEE勉強会で発表した「並行論理型言語GHCの紹介」の資料です。

Transcript of An Introduction to Guarded Horn Clauses

Page 1: An Introduction to Guarded Horn Clauses

An Introduction to

並行論理型言語GHCの紹介

【見覚え】小林浩一 (koichik) 【あります】

Page 2: An Introduction to Guarded Horn Clauses

Agenda

論理型言語Prologの概要

並行論理型言語GHCの概要

GHCによる並行プログラミング

Page 3: An Introduction to Guarded Horn Clauses

Prolog概要

1972年頃フランスで生まれる

一階述語論理のサブセット(ホーン論理)がベース

1980年代の人工知能ブームで注目

日本ではすっかり下火

ここ10年和書の新刊無し?

Page 4: An Introduction to Guarded Horn Clauses

変数と定数

変数英大文字または_で始まる

_のみだと無名変数

ex) A, B, Foo

数値 ex) 1, 2, 3

文字列(シンボル)英小文字で始まるまたはシングルクオートで囲む

ex) a, bbb, hoge, 'XYZ'

Page 5: An Introduction to Guarded Horn Clauses

単一化

A = B

変数Aと変数Bが「同じである」ことを示す

値が未定義の変数は一度だけ具体化できる

A = B

A = 5

B = 5

AとBは単一 (どちらも未定義)

Aと5は単一(Aは5に具体化)Bも5と単一 (Bも5に具体化)

Bは5と単一 (既に具体化済み)

Page 6: An Introduction to Guarded Horn Clauses

リストの単一化

リスト

任意の長さを持つデータ構造

ex) [1, 2, 3] [] [H|T]

リストの単一化

長さが同じリストは単一化できる

同じ位置の要素同士が単一化される

[1, 2, 3] = [X, Y, Z]

[A, 2, 3] = [1, B|C]

Xは1,Yは2,Zは3

Aは1,Bは2,Cは[3]

Page 7: An Introduction to Guarded Horn Clauses

複合項の単一化

複合項

名前と数の決まった引数を持つデータ構造

ex) point(10, 20)

複合項の単一化

名前と引数の数が同じ複合項は単一化できる

同じ位置の引数同士が単一化される

model(N, M) = model('EbiYuri', 'CanCam')

Page 8: An Introduction to Guarded Horn Clauses

Prologプログラム

述語の集合

述語

ホーン節の集合

ホーン節

ヘッドとボディを持つ (ボディは省略可)

ボディはゴールの集合

H :- B1, B2, ・・・, Bn.

Page 9: An Introduction to Guarded Horn Clauses

Prologプログラムの例

sum(1, 1).

sum(N, S) :-N1 is N - 1,sum(N1, S2),S is S2 + N.

節1(事実)

節2(規則)

述語

Page 10: An Introduction to Guarded Horn Clauses

実行イメージ(1)

?- sum(2, S).

sum(1, 1).

単一化できない

処理系に質問する

1番目の節

Page 11: An Introduction to Guarded Horn Clauses

実行イメージ(2)

?- sum(2, S).

sum(N, S).

単一化できる

処理系に質問する

Nは2に単一化SとSは単一化

2番目の節

Page 12: An Introduction to Guarded Horn Clauses

実行イメージ(3)2番目の節

sum(N, S) :-N1 is N - 1,sum(N1, S2),

N=2

N1は1に単一化

sum(1, 1).

1番目の節単一化できる

S2は1に単一化

Page 13: An Introduction to Guarded Horn Clauses

実行イメージ(4)2番目の節

sum(N, S) :-

N1 is N - 1,

sum(N1, S2),

S is S2 + N

Nは2に単一化

N1は1に単一化

S2は1に単一化

Sは3に単一化

Page 14: An Introduction to Guarded Horn Clauses

実行イメージ(5)

?- sum(2, S).

sum(N, S).

単一化できる

処理系に質問する

Sは3に単一化

2番目の節

N=2,S=3

Page 15: An Introduction to Guarded Horn Clauses

Prologの逐次性

ボディのゴール

記述順に実行する

述語が複数の節を持つ場合

記述順に試行する

H :- B1, B2, ・・・, Bn.

sum(1, 1).

sum(N, S) :-

Page 16: An Introduction to Guarded Horn Clauses

Prologまとめ

Prologプログラムは述語の集合 述語は節の集合

節は一つのヘッドと任意のボディを持つ

単一化 A=B

AとBは「単一である」

述語の呼び出しも単一化で決まる

逐次性がある ボディのゴールは記述順に実行される

述語の節は記述順に試行される

Page 17: An Introduction to Guarded Horn Clauses

Agenda

論理型言語Prologの概要

並行論理型言語GHCの概要

GHCによる並行プログラミング

Page 18: An Introduction to Guarded Horn Clauses

GHC概要

Guarded Horn Clausesの略

上田和紀氏が考案

第五世代プロジェクト並列推論マシンPIMのOS (PIMOS) の記述言語KL1の土台となった

Prologがベース逐次性を排除

i.e. Prolog - 逐次性

「Prolog + 並行性」ではない!

Page 19: An Introduction to Guarded Horn Clauses

逐次性の排除(1)

ボディの複数のゴール

並列に実行される

AND並列

H :- B1, B2, ・・・, Bn.

並列に実行

Page 20: An Introduction to Guarded Horn Clauses

逐次性の排除(2)

述語の複数の節

並列に試行する

OR並列

sum(1, 1).

sum(N, S) :-並列に試行

Page 21: An Introduction to Guarded Horn Clauses

AND並列

ex(A, B, C, D, E) :-X is A * B,Y is C * D,E is X + Y.

E = A * B + C * D

3つのゴールは並列実行される

ex(A, B, C, D, E) :-E is X + Y,X is A * B,Y is C * D.

記述順に意味なし並べ替えても同じ

Page 22: An Introduction to Guarded Horn Clauses

OR並列

not(0, Out) :-Out = 1.

not(1, Out) :-Out = 0.

Out = !In

2つの節は並列に単一化を試みる

not(1, Out) :-Out = 0.

not(0, Out) :-Out = 1.

記述順に意味なし並べ替えても同じ

Page 23: An Introduction to Guarded Horn Clauses

曖昧な節

sum(1, 1).

sum(N, S) :-N1 is N - 1,sum(N1, S2),S is S2 + N.

?- sum(1, S).

どちらの節も選択可能

(これはProlog)

Page 24: An Introduction to Guarded Horn Clauses

非決定性

選択可能な節が複数ある場合どの節が選択されるかは非決定的

Non-determinism

Non-deterministic OR-parallel

選択した節が失敗(偽)した場合やり直さない

Committed Choice

Don't care non-determinism

Page 25: An Introduction to Guarded Horn Clauses

ガード(1)

H :- G1, G2, …Gm | B1, B2, …Bn.

ヘッド

ボディガード

コミット演算子

ガード付きホーン節

Page 26: An Introduction to Guarded Horn Clauses

ガード(2)

ガードが真となる節のみ選択される

複数の節のガードが真となる場合は?

一つの節だけが選択される

ボディが実行される節は一つだけ

選択は非決定的

節が排他的になるようガードを書くべき

Falt GHC

ガードゴールでは一部の組み込み述語しか利用できないGHCのサブセット

KL1のベース

Page 27: An Introduction to Guarded Horn Clauses

ガード(3)

sum(1, S) :- true |S = 1.

sum(N, S) :- N>1 |N1 is N - 1,sum(N1, S2),S is S2 + N.

?- sum(1, S).

1番目の節が選択(記述順に依存しない)

Page 28: An Introduction to Guarded Horn Clauses

AND並列の同期sum2(N, S) :-

sum(N, N1),sum(N1, S).

sum(N, N1) sum(N1, S)

sum2(N, S)

AND並列

依存関係

2つのゴールは並列に実行していいが…

Page 29: An Introduction to Guarded Horn Clauses

OR並列の同期

sum(1, S) sum(N, S)

sum(N1, S)

OR並列

不確定

2つの節は並列に試行していいが…

sum(1, S) :- true |...

sum(N, S) :- N>1 |...

Page 30: An Introduction to Guarded Horn Clauses

GHCの同期メカニズム

ガードによる同期

ガードは呼び出し側の変数を具体化できない

ボディでは可能

自分の変数は具体化できる

ガードの実行に必要な変数が具体化されるまで待機 (同期化) する

「単一化できる」or「単一化できない」が確定するまで待機 (サスペンド) する

他の節が選択されるまで待機 (サスペンド) する

Page 31: An Introduction to Guarded Horn Clauses

GHCの同期(1)

sum(1, S) :- true |...

sum(N, S) :- N>1 |...

sum(N1, S)

OR並列

N1は具体化されてない

呼び出し側のN1を具体化できない

N(=N1)が具体化されないと

評価できない

N1が具体化されるまで

待機

Page 32: An Introduction to Guarded Horn Clauses

GHCの同期(2)

sum(1, S) :- true |...

sum(N, S) :- N>1 |...

sum(N1, S)

OR並列

N1 = 2

呼び出し側のN1(=2)と1は

具体化できない

N(=N1=2)は1より大きい

右の節が選択され

ボディ実行

Page 33: An Introduction to Guarded Horn Clauses

GHCの出力引数

sum(1, 1).

Prolog

sum(1, S) :- true |S = 1.

GHC

ヘッドで出力(第2引数)を単一化する

ボディで出力(第2引数)を単一化する

Page 34: An Introduction to Guarded Horn Clauses

GHCまとめ

逐次性の排除 AND並列:ボディのゴールを並列に実行

OR並列 :複数の節を並列に試行

細粒度の並行性

ガードによる同期 ガードでは呼び出し側の変数を具体化できない

必要なら具体化されるまで待機

処理系 (KL1) KLIC

http://www.klic.org/index.ja.html

Page 35: An Introduction to Guarded Horn Clauses

Agenda

論理型言語Prologの概要

並行論理型言語GHCの概要

GHCによる並行プログラミング

Page 36: An Introduction to Guarded Horn Clauses

ジェネレータ

From~Toまでの数列 (リスト) を生成

gen(From, To, X) :- From =< To |X = [From|Xs],Next is From + 1,gen(Next, To, Xs).

gen(From, To, X) :- From > To |X = [].

Page 37: An Introduction to Guarded Horn Clauses

ジェネレータ

gen(1, 2, X) X = [1 | Xs]

gen(2, 2, X) X = [2 | Xs]

gen(3, 2, X) X = []

X = [1, 2]結果

Page 38: An Introduction to Guarded Horn Clauses

フィルタ

入力リストの要素を2倍にしたリストを出力

twice([X|Xs], Y) :- true |Y1 is X * 2,Y = [Y1|Ys],twice(Xs, Ys).

twice([], Y) :- true |Y = [].

Page 39: An Introduction to Guarded Horn Clauses

フィルタ

twice([1,2], Y) Y = [2 | Ys]

twice([2], Y) Y = [4 | Ys]

twice([], Y) Y = []

Y = [2, 4]結果

Page 40: An Introduction to Guarded Horn Clauses

パイプ&フィルタ

ジェネレータとフィルタを共有変数で連結

パイプライン並列 or ストリーム並列

pipe(From, To, Y) :- true |gen(From, To, X),twice(X, Y).

Page 41: An Introduction to Guarded Horn Clauses

パイプ&フィルタ

gen(1, 2, X)

X = [1 | Xs]

gen(2, 2, X)

X = [2 | Xs]

gen(3, 2, X)

X = []

Y = [2, 4]

twice(X, Y)

Y = [2 | Ys]

twice(X, Y)

Y = [4 | Ys]

twice(X, Y)

Y = []

X = [1, 2] 結果

Page 42: An Introduction to Guarded Horn Clauses

動的なプロセスネットワーク

エラストテネスのふるいによる素数の生成

primes(N, J) :- true |gen(2, N, I), sift(I, J).

sift([P|I], J) :- true |J = [P|L], filter(I, P, K), sift(K, L).

filter([N|I], P, K) :- N mod P =:= 0 |filter(I, P, K).

filter([N|I], P, K) :- N mod P =¥= 0 |K =[N|K1], filter(I, P, K1).

Page 43: An Introduction to Guarded Horn Clauses

素数

primes

gen

sift

J =

Page 44: An Introduction to Guarded Horn Clauses

素数

primes

gen

sift

2

J =

Page 45: An Introduction to Guarded Horn Clauses

素数

primes

genfilter

2

2

sift sift

J =

3

Page 46: An Introduction to Guarded Horn Clauses

素数

primes

genfilter

2

2

sift sift

J =

4

3

Page 47: An Introduction to Guarded Horn Clauses

素数

primes

genfilter

2

2

sift sift

filter3

sift

3J =

4

5

Page 48: An Introduction to Guarded Horn Clauses

素数

primes

genfilter

2

2

sift sift

filter3

sift

3J =

6 5

Page 49: An Introduction to Guarded Horn Clauses

素数

primes

genfilter

2

2

sift sift

filter3

sift

3J =

7

5

6

Page 50: An Introduction to Guarded Horn Clauses

素数

primes

genfilter

2

2

sift sift

filter3

sift

filter5

3 5J =

8 7

Page 51: An Introduction to Guarded Horn Clauses

クイックソート

並列に適したアルゴリズム

quicksort(X, Y) :- true | qsort(X, Y, []).

qsort([X|Xs], Y, Z) :- true |partition(Xs, X, S, L),qsort(S, Y, [X|Ys]), qsort(L, Ys, Z).

qsort([], Y, Z) :- true | Y = Z.

partition([H|R], X, S, L) :- H =< X |S = [H|S1], partition(R, X, S1, L).

partition([H|R], X, S, L) :- H > X |L = [H|L1], partition(R, X, S, L1).

Page 52: An Introduction to Guarded Horn Clauses

クイックソート

quicksort

qsort

partitionqsort qsort

partition

qsort qsort

partition

qsort qsort

高い独立性

Page 53: An Introduction to Guarded Horn Clauses

アクタープログラミング

アクター?

任意の数のメッセージを受け取ることができる

任意の数のメッセージを送ることができる

GHCによるアクタープログラミング

アクター

メッセージの列を受け取る述語

メッセージの列

リスト

メッセージ

リストの要素

Page 54: An Introduction to Guarded Horn Clauses

アクタープログラミング

アクターMsg

アクター

アクター

アクター

MsgMsg

概念 メッセージの列(リスト)

(本当はmerger必要)

Page 55: An Introduction to Guarded Horn Clauses

アクタープログラミング

pingpong

hello

world

サンプル

pingpong

Page 56: An Introduction to Guarded Horn Clauses

アクタープログラミング

pingpong(N) :- true |ping(N, [hello(X)|_]), pong([X|_]).

ping(N, [hello(Resp)|Msgs]) :- N > 0 |Resp = [world(Msgs)|_],N1 is N - 1, ping(N1, Msgs).

ping(0, [hello(Resp)|_]) :- true |Resp = [].

pong([world(Resp)|Msgs]) :- true |Resp = [hello(Msgs)|_],pong(Msgs).

pong([]).

Page 57: An Introduction to Guarded Horn Clauses

要求駆動

必要とされた時に数列を生成

gen(From, [X|Xs]) :-true |

X = From,Next is From + 1gen(Next, Xs).

gen(_, []).

gen(1, X),...X = [N1|X1],...X1 = [N2|X2],...X2 = [],...

初期化

N1 = 1

N2 = 2

終了

Page 58: An Introduction to Guarded Horn Clauses

GHCによる並行プログラミングまとめ

プロセスネットワークの構築

パイプ&フィルタ

動的な構築が可能

多様なプログラミングスタイル

アクタープログラミングはスタイルに過ぎない

オブジェクト指向もスタイルに過ぎない

遅延評価はスタイルに過ぎない

データ駆動 (先行評価的)

要求駆動 (遅延評価的)

実は低水準なプログラミング言語

Page 59: An Introduction to Guarded Horn Clauses

参考文献

並列論理型言語GHCとその応用淵一博監修

古川康一・溝口文雄 共編

ISBN4-320-02266-1

並行論理プログラミング言語 GHC/KL1上田和紀

http://www.ueda.info.waseda.ac.jp/̃ueda/readings/GHC-intro.pdf