next up previous contents
Next: 1.5.2 ストリームの連結 Up: 1.5 プロセス・ネットワーク Previous: 1.5 プロセス・ネットワーク

1.5.1 フィルタ

与えられた数未満の自然数の和を計算するプログラムの例を 1.4.2 で 紹介したが, これは自然数のリストを作るプロセスと, その要素の総和を計算 するプロセスのふたつからなっていた.

では少し問題を変えて, 与えられた数未満の自然数の平方の総和を計算するプ ログラムを考えてみよう. 前章のプログラムを利用して作るとすると, すぐ に思いつく方法は以下のふたつだろう.

これはいずれも, ふたつのプロセスのどちらかを改修して, 必要な機能を作ろ うという方針である. もちろんこのどちらの方法でもプログラムは作れるし, この問題に限っていえばそれで十分である. しかし, もし両方のプロセスと もずっと複雑で, 簡単には改修できないとしたら, 他にどのような方法がある だろう.

与えられた数未満の自然数のリストを作るプログラムはもうある. リスト要 素の総和を求めるプログラムもある. とすると, 整数のリストをもらって, 各要素の平方を要素とするようなリストを作るプログラムをその間に入れてや れば解決である. たとえば以下のようなプログラムを作れば良い.

square([],Out) :- Out=[].
square([One|Rest],Out) :-
    Square:=One*One, Out=[Square|OutTail], square(Rest,OutTail).
この述語を使えば, プログラム全体は以下のように書ける.
square_sum_up_to(N, Sum) :-
    naturals(N,Naturals), square(Naturals,Squares), sum(Squares,Sum).

述語 square はリストを入力としてリストを出力するような述語を定義してい る. この述語の計算過程をプロセスととらえ, 入出力のリストをストリーム と解釈するとどうなるだろう. このような見方をすると, このプログラムは 一本のストリームから整数値のメッセージを受け, もう一本のストリームにそ の平方をメッセージとして送り出すプロセスを表している. このように, あ るストリームから受けとったメッセージになんらかの変換を施して, 別のスト リームに出力するようなプロセスを フィルタ (filter) と呼ぶ. 全 体のプログラムはプロセス naturals とプロセス sum が, フィルタ square を通るストリームを使って通信する, という構成になる (図 1.4).

  
図 1.4: フィルタ

この例ではフィルタとなったプロセス square は状態を持たず, 出力は入力メッ セージだけに依存している. 一般には, フィルタの動作は入力メッセージだ けではなく, フィルタ・プロセスの状態に依存しても良い. フィルタ・プロ セスは入力メッセージに応じて状態を変えられるから, 入力の履歴に応じてフィ ルタの仕方を変えることもできる.

フィルタは1本の入力ストリームと1本の出力ストリームを持つ. ふたつのフィ ルタの片方の出力をもう一方の入力につなげれば, 全体としてはやはり1入力1 出力のフィルタができる. この場合, 最初のフィルタがメッセージを次のフィ ルタに送ってしまった後, 次のフィルタがそのメッセージの処理をするのと並 列に, 最初のフィルタは次のメッセージの処理を行なえる. このようにフィ ルタをたくさんつなげていけば, パイプライン処理ができるわけである (図 1.5).

  
図 1.5: パイプライン処理



next up previous contents
Next: 1.5.2 ストリームの連結 Up: 1.5 プロセス・ネットワーク Previous: 1.5 プロセス・ネットワーク



KLIC