平方と立方の総和を求めるプログラムでは, 平方を作るフィルタ, 立方を作る フィルタの両者に同じ入力メッセージを与えれば良かった. では, そうはい かない場合 --- 入力メッセージの内, あるメッセージはひとつのフィルタを, 他のメッセージは別のフィルタを通したい場合はどうしたら良いだろう.
例として, こんどは与えられた数未満の自然数について, 偶数は平方し, 奇数 は立法したものの総和を求めることを考えよう. まず, 入力を偶数か奇数か に応じて, 別々のストリームに振り分けて出力するようなプロセスを作れば良 い. そのプログラムは以下のようになる.
dispatch([],Odd,Even) :- Odd=[], Even=[].
dispatch([One|Rest],Odd,Even) :- One mod 2=\=0 |
Odd=[One|OddTail], dispatch(Rest,OddTail,Even).
dispatch([One|Rest],Odd,Even) :- One mod 2=:=0 |
Even=[One|EvenTail], dispatch(Rest,Odd,EvenTail).
もうプログラムの細かい説明をするまでもあるまい. この述語で実現される
プロセスは, 入力ストリームが1本, 出力ストリームが2本あり, 入力メッセー
ジの内容に応じてどちらのストリームに出力するか決めている. このような
プロセスを ディスパッチャ (dispatcher) と呼ぶ.
これを用いると, プログラムの全体は以下のようになる.
queer_sum(N,Sum) :-
naturals(N,Naturals), dispatch(Naturals,Odd,Even),
square(Even,Squares), cube(Odd,Cubes),
merge(Squares,Cubes,Both), sum(Both,Sum).
プロセス構成を図 1.8 に示す.