ここでの判断(意思決定)という言葉は、英語ではDecisionを使うことが多いですが、James Taylorは著書 Smart (Enough) Systems において、企業におけるDecisionは、次の3種類に分けられると言っています(図1)。
下図のように厳密に分けられるというわけでもないですが、Decisionに対するひとつの視点としては有効でしょう。

意思決定の自動化といった場合、このうち、運用的(業務上の)意思決定がボリュームも多く(たとえば顧客との接点が発生するたびに意思決定も発生)、何度も繰り返されるので自動化に適したものと言えましょう。また戦術的な意思決定も、月次や週次などで決定され繰り返されるものも多いので、必ずしも完全に自動化をしないまでも人との協働作業で意思決定をなすことが考えられます。逆に戦略的な意思決定はそれほど頻繁になされるわけではなく、定型的なものでもないので、あえて自動化を目指すものでもないということになります。
運用的意思決定の自動化は、非常に大きなビジネスインパクトを持ちます。経営レベルの戦略的な意思決定はもちろん大きなビジネスインパクトを持ちますが、それとは別な視点、すなわち意思決定量の多さからくる圧倒的なビジネスインパクトを持っています。すでにほぼ自動化されている例になってしまいますが、ECサイトのレコメンド機能とか、クレジットカード取引の不正検知とか…。自動化されていなかったとしたら取引量に大幅な制約が発生し、ビジネスが、量というよりも質的にも変わってきてしまうことが予想されます。
もっとも運用的意思決定もピンキリで、自動化してインパクトありそうなものと、それほど期待できなさそうなもの、いろいろあると思うのですが、意外に職場に転がっているのではないでしょうか。たとえば「あの取引先は○○だから△△しておけ」とか…。これも立派な運用的意思決定です(まあ、正確に言うと、ある運用的意思決定を構成するひとつのルールになりそうですが)。自動化のネタだしにちょっと考えてみるのもいいかもしれません。
]]>ハイパーオートメーションは、すでにさまざまな記事がネットで閲覧できるようになっており、たとえば本家ガートナーの
ハイパーオートメーションとは?RPAと何が違う?ガートナーが説く構築の3つのステップ
や、
「自動化の取り組み」という視点から考えるハイパーオートメーション ~計測・モニタリング・再評価まであらゆる手順を対象とする体制や仕組みづくりをトップダウンで推進
のあたりが参考になるかと。
ハイパーオートメーションは基本的には昔から言い古されている「業務の自動化」で、近年ではRPAに代表されるところではありますが、このハイパーオートメーションは何が新しいかというと、RPAからさらに進んでさまざまなツールを組み合わせて、より包括的な(ほぼ)完全な自動化を目指すところにあります。
RPA、AI/ML、DMP(意思決定プラットフォーム≒BRMS)…
これらを組み合わせて使うことによって、単純な定型作業の自動化にとどまらず、ちょっとした判断を含むような非定型作業をも自動化するという動きです。
ハイパーオートメーションではさらに自動で行われた結果をモニタリング、評価して、さらにパフォーマンスを改善していくといったところも含まれてきます*1。
*1:この辺はまさにDigital Decisioningというところとも関係してきます。いずれ記事にまとめようかと思っております。
このハイパーオートメーションについては、ハイパーオートメーションという言葉こそ使っていませんが、業務の自動化という視点で国内企業の現状を調査したレポートがあります。
ITR White Paper:業務自動化に向けた国内企業の現状と展望 (2022年8月)
ITRによる国内企業に対する業務の自動化に関してのアンケートの結果をまとめたレポートなのですが、その中に以下のような図が掲載されていました

この図を参照すると、現在の一般的な業務の自動化は、③~④程度までにとどまり、先進的な例ではチャットボットを使った⑤や、さらにAIを組込んだ⑥などがちらほらという感じでしょうか。ちなみにいわゆるDMP(Decision Management Platform ≒BRMS)も⑥に位置します(まあ、歴史的にみてもともとAIですし)*2。
*2:Digital Decisioningという概念は、この図で⑥および⑤に対応してきます。
さて、ハーパーオートメーション。人間の判断を含めた自動化、さらに結果をモニタリングしてパフォーマンスの改善を加えていく…。以下の例えに思い至りました。

(かなり)昔は1個1個手ではじいていたパチンコ、今はほぼすべてが玉をはじくこと自身は台が行って人間は結果をみながらハンドルで調整するタイプになってます。
オフィス作業についても1件1件手打ちしているようなものが、いずれは完全に自動化されて、人は、システムが自動で作業する様子を観察しながら、それを調整するのが仕事、という時代になっていくのでしょうね。
]]>ニューラルネットは、人間の脳のニューロンのふるまいをモデル化したあたり、可能性は感じつつも結局、トイプログラム以上のものにはならないなあと思ってたのも今は昔(って何十年も前)。
2012年に物体認識のコンテストILSVRC(ImageNet Large Scale Visual Recognition Challenge)でトロント大学のチームがディープラーニングのモデルをひっさげて圧勝したのが転機になったでしょうか…それ以来、こと画像認識や音声認識、自然言語処理、ゲームなどの分野では、ディープラーニングが席巻してしまうといった、まさかまさかの急展開が繰り広げられる状況になったわけです。
それから10年、ディープラーニング*1は、問題点が露呈したり*2して、さまざまな批判は受けつつも着実に根はおろしてきていると言えるでしょう。ここではディープラーニングの特徴について私なりの考えをまとめておきたいと思います。
*1:最近の風潮… AI=ディープラーニング になっているような気が …笑
*2:たとえば、こんなこと 焦点:アマゾンがAI採用打ち切り、「女性差別」の欠陥露呈で

ディープラーニングは、入力と出力の間で多段のネットワークを構成し、あとはひたすら学習、エッジの重みづけを最適化していく…そういった機械学習のしくみ。実はそこに「何がこうなったからこう」といった数理論理的な論理処理は介在していません*3。
*3:ちなみに一応念のためですが、ニューラルネットのメカニズムを支えるプログラムの中ではif-thenやfor、whileループなどの論理的な処理はありありですが、ここで言っているのはより高次のニューラルネットワークのモデルレベルの話
一方、従来のコンピュータは、ほぼ理屈(論理)で処理する方式。たとえば
今日は25日だから給料振り込むよ
とか
最高血圧が○○以上だから通常より保険料が△△円高くなる
とか、仮に結論に至るまでに何段階も(たとえば~ならば~であるといった)論理を積み重ねることになったとしても必ずその筋道は明確に決められているはずのものです。きちんと説明できるはずのものです。
ところで、画像の認識や音声の認識について、人間は理屈というよりも本来直感で決めてませんか?
ちょっと前にも書きましたが、人が猫を認識するとき、猫は猫であってそれ以上でもそれ以下でもない。西川きよしさんを西川きよしさんと認識するとき単純に目が大きいからということだけから認識するわけではないでしょう。目が大きいということだけだったら、もしかして今田美桜さんかもしれない。
画像を、言葉で論理的に説明しつくせるのであれば、「百聞は一見に如かず」*4 のことわざもないかもしれません。
*4:ちなみにこれには続きもあるそうで…本記事の意図とは全然違いますが、興味のある方は「百聞は一見にしかず 続き」ででも調べてください。
つまるところ、現在のディープラーニングの本質は、理屈を超えたパターン認識…そういったところにあるのだろうと思います。現在のディープラーニング(第3世代AI)が、即応するAI、右脳のAIなどと言われるゆえんでしょう。
実際に使われているところをみると、製造業であれば不良品/検品の目視検査であったり、機械の異常を音・振動によって検知したり、医療であればX線写真から異常を発見したり…。
本日テレビでは、雑踏の中を行き交う人々が正しくマスクをしているかを示す映像を放映していましたが、結局現在のディープラーニングの使いどころも人間の目や耳の機能を代替したり、人間の勘などといった理屈を超えたところがその使いどころなのだろうなと思います。
最近、XAI(説明可能なAI)の研究が流行っていますが、すくなくとも現在のディープラーニングは、あのゴッドファーザー、ヒントンも言う通り、そもそもが説明できないところへ適用されて成功を収めたわけで、あまり過剰な期待を持つのもどうかと…。
もっとも、人間も後付けで理屈をつけたりして、それがきっかけで進歩したりするところもあるので、XAIのようなやり方もありと言えばありかなと…。そういった意味ではXAIも適切に守備範囲を理解したうえで使うことが肝要かなあと思う次第。
以上、現在のディープラーニングについて思うところを書いてきました。ここで「現在の」とあえて修飾をつけているのは、将来的に、第4世代AIなど、もう少し本質的なところでディープラーニングと論理が結びつくなどありそうだから…。また、ディープラーニングが学習を続けていくことで、言語が、論理が創発してくるとか…実用性はともかく、研究的な面ではおもしろいかもですね。もし、そうなったらそれがシンギュラリティということなのでしょうけど。
]]>というわけで今日は、ここ四半世紀にわたって世界的に人工知能(機械学習以外も含む)全般の標準的な教科書であり続けている
Artificial Intelligence: A Modern Approach, 4th Global ed. (amazon)
の紹介。この教科書、個人的には第1版(1995)のときからずっとお世話になっている教科書です。…が、全部通して読んだことはありません(っていうか、半分も読んでません…笑)。というのも海の向こうの教科書によくあるような 1000 ページを超える超大部の本なので…。今は第4版を手元に置いております、ただ邦訳は第2版までしか出ていません(これも本棚の重しとして持ってます)。ちなみにこの記事を書くにあたってちょっと調べたところ、この本、有名な教科書だけあって日本語で一部、要約を公開してくれているサイトがありました。
Artificial Intelligence: A Modern Approach (Fourth Edition) 各章の要約
一応、章立てを見てみると
こんな感じ。
第1世代の探索(第Ⅱ部)から、第2世代の論理/知識表現(第Ⅲ,Ⅳ部)、第3世代の機械学習(第Ⅴ部)、AIの応用、哲学、倫理等々(第Ⅵ、Ⅶ部)とAIの全貌がひととおり掴めるというわけ。でも、たぶん通読している人はそうそういないんだろうな(笑)。
]]>*1:エキスパートシステムの技術を応用してできたツールが、BRMS(ビジネスルール管理システム/ルールエンジン)です。ビジネスルールが「知識」として表現されるということになります。

実際、機械学習ベースのAIが主流の今日でも、論理をベースにしたAIの分野はまだまだ盛んに研究されたり利用されたりしています。Googleの検索エンジンの裏にあるGoogle Knowledge Graphなどは、その最たるものでしょう。囲碁のトップ棋士を負かしたAlphaGoの裏にもディープラーニングだけでなく、モンテカルロ木探索*2が使われています。この論理/記号処理の研究の蓄積を使わぬ手はないであろうというのが、理論知識型AI+データ駆動型AI である第4世代AI。
*2:よく考えると木探索はむしろ第1世代のAIの延長ですかね? いずれにしても過去のAIの研究の蓄積は今でも生きているということです^^。
第4世代AIについては、日本では昨年の6月に、こんな提言書
が出ていたりしますが、ちょっと前にも書きましたが第4世代AIを目指す潮流は日本に限らず世界的なもののようです。ハイブリッドAIを主張する論文としてよく出てくるのは
The Next Decade in AI: Four Steps Towards Robust Artificial Intelligence
あたりですか。
さて第4世代AIを表す言葉として(厳密には≒というべきかもしれませんが)は、上の論文に出てくるハイブリッドAIという言葉だったり、またニューロシンボリックAI(neurosymbolic AI – ニューラルネット+記号処理 AI)などという言い方もあるそうです。割と有名な研究がこれ
The Neuro-Symbolic Concept Learner: Interpreting Scenes, Words, and Sentences From Natural Supervision
(この論文には、こんなのありました
[DL輪読会]The Neuro-Symbolic Concept Learner – SlideShare)
あとこんなアーカイブもあります。
Neuro-Symbolic AI Archives – MIT-IBM Watson AI Lab
また、最近知った言葉として、直接、ハイブリッドを意味しているわけではないですが、目指す方向は共通とするところの多い Engineerable AI などという言い方もあるようです。
]]>1.理論知識型AI+データ駆動型AI (AL ハイブリッドAI)
であったり、またあるときは
2.物理モデル+機械学習 (ハイブリッドAI|物理学と機械学習を組み合わせたAIが産業界を変革する)
であったりします。
ただおおよそ、共通に意味するところでいえば
人間が持っている明文化できるような論理的な知識+データを用いた機械学習
というハイブリッドでしょう。人間の脳にたとえて言うと、
人間が持っている明文化できるような論理的な知識が左脳なら、
データを用いた機械学習が右脳、

といえ、さらに誤解をおそれずに例えれば
ハイブリッドAIは、人間でたとえると左脳と右脳が協調して問題を解決するAI
…でしょうか。
さて昨今機械学習系AIの活用が盛んですが、もう70年にもおよぼうとするようなAIの歴史の中で、機械学習がこれほどまでに脚光を浴びるようになったのは、おそらく、2012年に画像認識のコンテストにおいてトロント大学のチームが深層学習(ディープラーニング)を使ったモデルで圧倒的なパフォーマンスをあげたことにはじまるのではないかと思います。これ以降、機械学習、特に深層学習は画像認識はもちろん、音声認識、自然言語処理などでめざましい成果をあげていることはご存じのとおり。
しかし今、成果をあげている、この機械学習に基づくAI…第3世代AIと言われますが、この第3世代AIと言われる機械学習にもデメリットが見えてきました。これには、前にも書きましたが、以下の項目などがデメリットとしてあげられています。
上記のパターン処理に関して言えば、実際に第3世代AIで成功している分野の多くは、画像認識など論理で割り切れない分野です。たとえば人間が画像を見て猫と認識するという場合に、
猫は猫
であり、別に、ひげがあるとか、目が猫だとか意味づけをもって猫だと判断しているわけではありません。見たその場で猫だと判断して、ひげがあるとか、目が猫だとかは必要あれば後付けで理屈をつけるというだけです。
実は深層学習による画像認識も人間と同様で○○だから猫というわけではなく、たくさんの猫の画像を見て学習し、

猫は猫
と認識するようになります。
第3世代AIは、このように意味づけを越えたパターンの認識が得意であるといったところに特徴があり、非常に即応的で、逆にこれが熟考を要する論理には弱いというデメリットにもつながっているわけです。
さて、この第3世代AIの論理面での弱さに対して論理の仕組みを取り入れて対応していこうという動きが、XAI(説明可能なAI)であったり、ハイブリッドな第4世代のAI(理論知識型AI+データ駆動型AI)であったりするわけです(この項続く)。
]]>さて、木曜日(26日)の日経新聞朝刊にイアン・ブレマー(毎年、今年の10大リスク…などとよく新聞に載っている、あのイアン・ブレマー氏です)が、オピニオン欄でこんなことを言っていました。「中国はこれからも強いのか」という記事の中で以下のように語っています。
(…略…)
確かに人権保護の制約がない中国では米国をはるかに上回るデータを収集できる。だが、それだけでAIの総合力は決まらない。
AI技術は、読み込ませたデータから得られる経験則に基づき診断や予測を導く「機械学習」だけにとどまらない。人類の「知識」や「常識」をプログラムに織り込んでおく「ルールベースAI」という方法論もある。世界の先端研究者たちは両者の良さを融合したAIの確立を急いでいる。
(…略…)
(日本経済新聞 2022年5月26日朝刊 「中国はこれからも強いのか イアン・ブレマー氏」から引用)
中国のAIと米国のAIとの比較の文脈の中で出てきた言葉ですが、政治学者のイアン・ブレマーの口から「ルールベースAI」という言葉が出てきたことにちょっとびっくりしてしまいました。「ルールベースAI」はBRMS(BDMS)の基盤となっている基礎技術。というかルールベースと言えば、ほぼそのままBRMSなのですが、ここではもうちょっと広く知識・記号処理型のAIを意味すると考えるべきでしょうか (ルールベースが知識・記号処理型のAIの分野の中でどういった位置づけにあるかというのは、いずれまとめておこうかと思っています)。
ここ何年かAIの潮流は、「データ」命とも言える、統計的機械学習、「データ駆動」のAIが主流となっていましたが、
①学習に大量の教師データや計算資源が必要であること
②学習範囲外の状況に弱く、実世界状況への臨機応変な対応ができないこと
③パターン処理は強いが、意味理解・説明等の高次処理はできていないこと
(第4世代AIの研究開発 -深層学習と知識・記号推論の融合- 国立研究開発法人 科学技術振興機構 研究開発戦略センター 2020年3月 から)
という限界も見え始め、知識・記号処理のAIも見直されてきています。確かに知識が明文化されているものであれば、それをきちんとインプリメントして供することで事足りるはずなのに、わざわざ機械学習をするまでもないわけです(たまに首をかしげるような機械学習AIの適用の仕方を小耳にはさんだりします(笑))。
こんな状況を受け、最近のAI技術の動向、特に研究においては、第4世代AI データを元に帰納的に学習をしていくデータ駆動AIと、演繹的な知識・記号処理型のAIの融合がさかんになってきています。
ニーズ即応型技術動向調査「AI関係技術ー演繹と帰納の融合ー」 特許庁 令和3年12月
現実においても
「データ×人知」AIで実務革新 シンガポール新興タイガー 経理や法務、安価で正確 日本経済新聞 2021年1月22日
AI運用「人との協働」で好成績 コロナ禍しのいだ想像力 日本経済新聞 2021年10月21日
など、データ駆動のAIと意味を理解する人間/AIの協働作業で、データ駆動AI単独では得られないパフォーマンスをあげている事例も見られます。
そういえばフリースタイルチェス(コンピュータと人間が協働したチーム間で対戦するチェス)で最初に優勝したのは、すぐれたAIを持ったチームではなく、AIと人間がうまく協働できたチームだったとか(実際優勝したチームは、そこそこのAIとアマチュアのチェスプレーヤーが協働していた)。決して、トップのAIを持っていたチームでも、チェスの人間のチャンピオンを擁するチームでもなく、そこそこのAIとアマチュアのチェスプレーヤーが協働したところが優勝したというところが面白いところ。これからの時代、人知とデータとがうまく協働することが重要なことなのでしょうね。
]]>まずは、ルール処理の対象となるファクトを準備します。
SampleFact.java
package com.sample;
public class SampleFact {
private int num;
private String name;
public SampleFact() {
super();
}
public SampleFact(int num, String name) {
super();
this.num = num;
this.name = name;
}
/**
* @return the num
*/
public int getNum() {
return num;
}
/**
* @param num the num to set
*/
public void setNum(int num) {
this.num = num;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SampleFact [num=" + num
+ ", name=" + name + "]";
}
}
そして、mainプログラム
DroolsTest.java
package com.sample;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
/**
* This is a sample class to launch a rule.
*/
public class DroolsTest {
public static final void main(String[] args) {
try {
// load up the knowledge base
KieServices ks
= KieServices.Factory.get();
KieContainer kContainer
= ks.getKieClasspathContainer();
KieSession kSession
= kContainer.newKieSession("ksession-rules");
// go !
SampleFact sf1 = new SampleFact(1, "A");
SampleFact sf2 = new SampleFact(2, "B");
SampleFact sf3 = new SampleFact(3, "C");
SampleFact sf4 = new SampleFact(4, "D");
SampleFact sf5 = new SampleFact(5, "E");
kSession.insert(sf1);
kSession.insert(sf2);
kSession.insert(sf3);
kSession.insert(sf4);
kSession.insert(sf5);
kSession.fireAllRules();
} catch (Throwable t) {
t.printStackTrace();
}
}
上のように5つのファクトをワーキングメモリに追加して、以下のルール
Sample.drl
package com.sample
rule "サンプルルール1"
when
SampleFact($num: num, $name: name)
then
System.out.println("num=" + $num
+ ", name=" + $name);
end
を実行しました。
コンソールには、どのように表示されるでしょうか。
まあ、これはワーキングメモリに5つのファクトがあるので、単純に
条件節(when部分)のSampleFactにマッチして、5回ルールのサイクルが回ります。
num=5, name=E
num=4, name=D
num=3, name=C
num=2, name=B
num=1, name=A
つまり条件部にマッチしたファクトが
SampleFact(1, “A”);
SampleFact(2, “B”);
SampleFact(3, “C”);
SampleFact(4, “D”);
SampleFact(5, “E”);
の5つだったということ。
では、上記のサンプルルール1のかわりに次のルールがあった場合は
どうなるでしょうか
Sample.drl(改)
package com.sample
rule "サンプルルール1a"
when
SampleFact($num: num > 3, $name: name)
then
System.out.println("num=" + $num
+ ", name=" + $name);
end
このときは条件節に num > 3 という条件が加わったので
num=5, name=E
num=4, name=D
の2つのみが表示されます。
すなわち条件部にマッチしたファクトが
SampleFact(4, “D”);
SampleFact(5, “E”);
の2つということ。
さらに次はどうでしょう。
Sample.drl(改々)
package com.sample
rule "サンプルルール2"
when
SampleFact($num: num, $name: name)
SampleFact($num1: num, $name1: name)
then
System.out.println("num=" + $num
+ ", name=" + $name
+ ", num1=" + $num1
+ ", name1=" + $name1);
end
今度は、条件節のSampleFactのパターンが2つになりました。結果は、
num=1, name=A, num1=1, name1=A
num=1, name=A, num1=2, name1=B
num=1, name=A, num1=3, name1=C
・・・(中略)・・・
num=5, name=E, num1=4, name1=D
num=5, name=E, num1=5, name1=E
以上、25行表示されました。
これは、条件節の最初のパターン
SampleFact($num: num, $name: name)
に5つのファクトがマッチして、さらに2番目のパターンにも
SampleFact($num1: num, $name1: name)
5つのファクトがマッチして結局その組合せとして5×5=25(通り)の
組合せが表示されているということを表しています。つまり
条件部にマッチしたファクトの組を
[<最初のパターンにマッチしたファクト>,<2番目のパターンにマッチしたファクト>]
の形であらわすとすると、
[SampleFact(1, “A”), SampleFact(1, “A”)]
[SampleFact(1, “A”), SampleFact(2, “B”)]
[SampleFact(1, “A”), SampleFact(3, “C”)]
・・・(中略)・・・
[SampleFact(5, “E”), SampleFact(4, “D”)]
[SampleFact(5, “E”), SampleFact(5, “E”)]
の25個のファクトの組が条件部にマッチしたことになります。
では、こんなルールであったらどうでしょうか。
Sample.drl(もひとつ改)
package com.sample
rule "サンプルルール2a"
when
SampleFact($num: num, $name: name)
SampleFact($num1: num > $num, $name1: name)
then
System.out.println("num=" + $num
+ ", name=" + $name
+ ", num1=" + $num1
+ ", name1=" + $name1);
end
(この項続く)
]]>目次だけ見ると、セキュリティ目的での使用が増えてきたりしている一方、当然のことながらIoTがらみでも増えてくるような予感。どこかでちゃんとCEPもまとめておきたいところなのですが…。
たとえば、
複合イベント処理の世界市場:2017~2021年
https://www.gii.co.jp/report/infi551749-global-complex-event-processing-market.html
とか…
さて、ちょっと唐突ですがプログラムにおけるif-then文と、一般的なルールとしてのif-thenの違いはどこにあるでしょうか。
(なお、ここで言うルールとしてのif-thenは、実際にBRMSに実装されるif-thenルールではなく、それ以前のまずは仕様(文書)としてまとめられた(ビジネス)ルールとします)
これら if-then文 と if-then ルール、同じ if-then ではあるので、それほど変わらないように感じられるかもしれません。私自身もふだんは明確な使い分けをせずあいまいな書き方をしていたりもしますが、実は大きな違いがあります。
まず、プログラムにおけるif-then文。これは、プログラムの上から下に流れる処理の流れが前提にあって、何もしなければif-thenは1回しか通りません。もう一度通すためには繰り返しを書く必要があります。つまりプログラムのif-then文は処理の流れを意識しないと成り立たず、処理の流れはすべて記載しなければなりません。すなわちプログラムのif-then文は、いわゆる手続き的 (procedural) にしか解釈されません。
一方、ルールにおけるif-thenというものは、どうでしょう。一般にルール(規則)というものは、条件 (if部) が合うのであれば常に適用されるもので、そこに処理の流れというものは存在しません。仮にいくつかif-thenルールがあったとしましょう。原則それぞれのルールは独立してそれぞれ条件が合うかどうかのみで、適用される/されないが判断されます。そこにどの順に処理するかという処理の流れはありません。
たとえば
if 赤信号 then 止まる
というルールですが、これを手続き的に解釈して処理の手順を考え、先ほど赤信号を処理したので、次の赤信号は処理できず結果的に無視してしまうということはないでしょう。どんな状況でも、条件さえ合えば常に適用されるというのがルールです。
無理やり手続き的に書こうとすると、「if 赤信号 then 止まる」という if-then文 をループで囲って、1回赤信号を処理しても、次の赤信号も処理できるように待っているといった書き方になります。
また、個々のデータが○か×の値をとる配列があり、
if × then エラー出力
などといったルールでも同じです。ルールそのものは上記で書けても、手続きを明示しないといけないので、if-then文 を配列全体にわたってループする・・・という追加の記述が必要になります。
まとめますと、仕様としての if-then ルールを手続き的に書こうとすると、ループなどの処理手順も明示する必要があり、それが複雑になると本来の仕様が処理手順に埋もれてしまうということになります。たとえば前回の記事などのようにデータに親子関係があり、複数の子の間での制約など if-then ルールとして記述すれば比較的わかりやすいけれども、手続き的に書こうとすると面倒というケースです。従来の手続き的なプログラミングの問題点の一つはそんなところにもあるのではないでしょうか。
***
さて、みなさまは「宣言的」(あるいは宣言型)プログラミングという言葉をお聞きになったことがありますか?
Wikipediaの宣言型プログラミングという項には、
「宣言型プログラミング(英: Declarative programming)は、プログラミングパラダイムの名称だが、2種類の意味がある。第一の意味は、処理方法ではなく対象の性質などを宣言することでプログラミングするパラダイムを意味する。第2の意味は、純粋関数型プログラミング、論理プログラミング、制約プログラミングの総称である。」
とあります。
上にあげた第2の意味は、現在一般的に認知されているプログラミングパラダイムの中で、第1の意味での宣言型プログラミングを具現化しているものとも解釈できるかと思います。そういった視点で第2の意味に加えるとしたら、プログラミングパラダイムとして一般的に必ずしも認知されているわけではないけれども、たとえばSQLなどはあげられるでしょう。実は、前回あげた ルールベース(プロダクションシステム)のプログラミングも宣言的なプログラミングの仲間に入れていいかと思います。
宣言型プログラミングの第1の意味では、処理方法ではなく対象の性質などを宣言することでプログラミングするパラダイムを言いますが、「対象の性質」と言っても、なかなかわかりにくいのでもう少しかみ砕いた記述を見てみましょう(宣言型プログラミングの可能性と限界より)。
「宣言型プログラミングが記述するものは、問題の定義、すなわち解くべき問題の性質や、その際に満たすべき制約の記述です。」
「対象の性質」をかみ砕くと「問題の定義、すなわち解くべき問題の性質や、その際に満たすべき制約」ということになるでしょうが、これをルールベースによる宣言的プログラミングに置き換えると、if-then ルールを使って、問題の性質や制約を記述することになりましょう。このことは何を意味しているのでしょうか。
***
仕様としての if-then ルール、これは問題の定義-問題の性質や制約を記述-を記述したものなので、実は「宣言的プログラミング」の意味での「宣言的」であるといえます。
これを実装する場合、従来のプログラミングでは if-then ルール を手続き的に直して書くだけだったので、本来の仕様以外に処理手順なども記述する必要がありました。

これにより本質がぼやけてしまいプログラムの可読性が落ちることもありましたが、これはすなわち本来宣言的に表しているものを手続き的に表そうとすることで仕様と実装との間でのミスマッチ(注0)が起こっていたということなのです。
もし宣言的に表されている仕様を、そのまま宣言的に表せるプログラム手法があるのであれば、それに越したことはなく、プログラムの可読性を落とすことなく実装を行うことができます。

ここであらわれたのがルールベースのプログラミング(プロダクションシステム)でした。もともとルールベースの技術は人工知能の応用としてエキスパートシステムの構築のために生まれてきたわけですが、このルールベースにおける if-then ルールの動きというものが、条件 (if部) さえ合うのであれば常に適用されるという、まさに仕様としての if-then ルールの動きと一致したわけです(注1)。
すでに前回にも書きましたが、ルールベースのプログラミングでは、if-then 文とループを使って処理手順を記述するのではなく、if-then ルールのみの仕様を記述することでプログラミングを行います。
で、if-then ルールを書けば、あとはルールのエンジンが、いい塩梅で実行してくれるというわけ。
たとえて言えば、手続き型のプログラミングは、処理の手順を一から教えなければならない新入社員のようなものである一方、ルールベースによる宣言的プログラミングは、「これこれをやっておいて(問題の性質や制約 ! )」と伝えておけば、それなりにいいようにやってくれる、常識的な処理手順はわかっている入社1~2年目の社員といったところでしょうか。
***
もっとも、このルールベースでのプログラミング、他の宣言的なプログラミング手法と同様、実際に実行するという視点から言えば良いことばかりではなくて、エキスパートシステム構築ツールの時代からメモリなどのコンピュータリソースを食うデメリットがありました。
ただ、昔のスーパーコンピュータの性能が ipad2と同じくらいであるといわれるようになった今日、プログラムの開発・メンテナンスのコストに対し、コンピュータリソースのコストは相対的に飛躍的に減少しているので、それほど気にすることはないでしょう。
***
まあ、そうは言っても実際のところ単項目のエラーチェックなどで、if-then文とif-thenルールとの違いがあまり表面化しない場合(単純なデータ構造で1回 if-then のチェックをすればよい場合など)も多々あるので、if-thenルールを記述できるBRMSを使うまでもないということもあるでしょう。
そんなときには、ちょっと手軽で安価な、手続き的に if-then文 を処理するBRMS (たとえばOpenRulesのsequential rule engine) を使ってもよいかと思います。
ただルールを手続き的な if 文で書こうとすることは、本質的にはJava(注3)やCobolなどなど従来の手続き型プログラミングをなぞっているという域を出るものではなく、本来のルールの宣言性を生かした宣言型のプログラムにはならないということは、きちんと認識しておいた方がよいかと思います。
手続き的な処理方法のBRMSで多少複雑な処理を行おうとすると、本来のBRMSのメリットである可読性が失われてしまい、メンテナンスの視点からは、結局従来のプログラムと何ら変わらないことになってしまうでしょう(注2)。要するに限界は限界として認識した上で、向き、不向きを判断して使うことが重要かと思います。
***
今回は、概念的な宣言的プログラミングの説明で終わってしまいましたが、どこかで宣言的プログラミングの例をもう少し書いてみたいと思います。たとえばビジネスの例ではありませんが、ポーカーの役の判定などは、手続き的に書くとするとループを回したりする必要がありますが、ルールベースで書くと役の定義に素直に、比較的直感的に書けるので、良い例になりそうだと思っています。
(注0) ミスマッチという言葉を使ったのは、ここを書いていて、一昔前によく言われていたオブジェクト指向言語からRDBを呼び出す際に、それぞれの拠って立つモデルが違うことから実装が複雑になる「インピーダンス・ミスマッチ」という言葉が頭に浮かんできたので・・・。
(注1) ちなみに、これが、現在の一般的なBRMSの多くが、エキスパートシステム構築ツールをルーツに持っているという所以です。たとえば、IBMのOperational Decision Manager、FICOのBlaze Advisor、RedHatのJBoss Rules、Oracle Business Rulesは、いずれもReteアルゴリズムベースのエキスパートシステム構築ツールをルーツに持ちます。またSAPのルールエンジンはReteベースのようですし、ProgressのCorticonは、DeTIという独自のアルゴリズムですが、動き的にはReteと同等です。
(注2) なお、OpenRulesにはそのために制約プログラミングをベースとした Rule Solver というもうひとつのルールエンジンがあり、上記にあげたルールベース的な動きではありませんが、宣言的なプログラミングができるようになっています。
(注3) 余談ですが、最近では Java も流行の関数型のパラダイム (上にも書きましたが宣言型のパラダイムの一つ) を取り入れるようになってきています。ルールベース的な宣言とは、ちょっと違うのですが、個人的には、関数型は関数型で結構好きだったりもします。
]]>