多くの人々が「チェスのような複雑なゲームをマスターできるコンピュータなら確かに知能があると見なせる。チェスのような抽象的な活動が知能の研究の道具としてベストだ」と考えている。また、「人間の幼児に対する教育過程を応用して、マシンが質問に答えられるようにすべきだ」とも言える。私は研究の対象を、例えばチェスといったように限定すべきか、それとも人間の言語習得のように汎用的なものにすべきか、どちらにすべきか判らない。多分両方を試すべきだろう。そして、その後の人工知能の研究はチューリングの言うとおり、2つの方向を行ったり来たりすることとなります。第2の方向を取り、コンピュータに「学習」をさせようとしていた研究は1960年代に挫折します。これは、当たり前の帰結でした。汎用的な知識をコンピュータに学習させるのは、余りにも早すぎた研究でした。「人工知能なんか駄目だ」としきりに言われたのはこの時代です。

図14.1 プロダクション・システム(1)

図14.2 プロダクション・システム(2)
個々のルールに対して、現在のWMEとルールのLHSとの照合を行う。
マッチングに成功したルールがいくつか存在する場合は、発火させるルールを選ばなくてはなりません。その選び方にも実はいろいろありますが、ここでは一番簡単な「最初に見つかったルールを採択する」ことにしましょう。
ルールのRHSによってワーキング・メモリの書き換えを行います。新たなWMEを生成することもあるだろうし、既に存在するWMEを削除することもあります。
IF 総出席時間が80%以上で教科出席時間が60%以上
THEN 定期試験受験資格あり
IF 不合格単位数が8単位未満
THEN 進級決定
などがあるでしょう。この推論の結果は「進級決定」、「留年決定」などになるはずです。このようにプロダクション・システムはIF-THENの形式で記述されたルールを用いて推論を行い、結論を得ようとします。
?- assert(wm(test)).
という操作が必要です。このwm(test)がワーキング・メモリ・エレメントです。勿論、自分でプロダクション・システムを作るときには、必ずしもwm節になっていなくても構いません。
rule(1,[wm(test)],[retract(wm(test)),write(ok),nl]).
これは3つの引数を持ちます。第1パラメータはルールの識別をするための通番です。第2パラメータはLHSにあたるリストで、第3パラメータはRHSにあたるリストです。したがって、このルールは
rule(1,[もしwm(test)という節が存在していたら],
[その節を削除して、画面にokと出力し、改行しなさい]).
ということになります。
上に示したようにwm(test)節を生成したら、
?- ps.
と入力してプロダクション・システムを動かしてみてください。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% プロダクション・システム
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 推論エンジン
% ps.で推論を開始する。
% psはps_subを繰り返し呼ぶ。
%
ps:-
repeat,ps_sub,!,
write(end).
ps_sub:-
(matching(M_rules),
select_rule(M_rules,Rule_no),
action(Rule_no),
!,
fail)
;true.
%
% マッチング
% 条件が該当するルールを全てピックアップする。
% CS_listはルール番号のリストとなる。
%
matching(M_rules):-
findall(Rule_no,match_sub(Rule_no),M_rules),
!,
M_rules\==[].
findall(X,G,_):-G,assert(ans(X)),fail.
findall(_,_,R):-collect([],L),reverse(L,R).
collect(L1,L2):-
retract(ans(X)),
\+(member(X,L1)),
!,
collect([X|L1],L2).
collect(L,L).
match_sub(Rule_no):-
rule(Rule_no,LHS,_),
slice(LHS).
%
% 競合解消戦略
% ここでは、最初に見つかったルールを採択している。
%
select_rule([Rule_no|_],Rule_no).
%
% Actionの実行
%
action(Rule_no):-
rule(Rule_no,_,RHS),
slice(RHS).
%
% サブルーチン
%
% 第1パラメータを逆順にして第2パラメータとする
reverse(X,Y):-reverse_sub(X,[],Y).
reverse_sub([],X,X).
reverse_sub([H|X],Y,Z):-reverse_sub(X,[H|Y],Z).
% 第1パラメータが第2パラメータに含まれているかどうかの
% 判定を行う
member(X,[X|_]).
member(X,[_|L]):-member(X,L).
% LHS,RHSなどのリストから1つづつ切り分けて実行する
slice([]).
slice([Head|Rest]):-
Head,
slice(Rest).
%
% テスト用ルール
%
rule(1,[wm(test)],[retract(wm(test)),write(ok),nl]).
雑誌や何かにYes/Noで分岐していって「あなたは○○タイプです!!」みたいな結論になる奴があるじゃないですか。初めてプロダクション・システムを作るのなら、そういうのを基にして作ると楽です。そうして、感覚が掴めたら、もちっと本格的なのにトライすると良いと思います。