HOME    BRMSブログ  No.16 変化する市場、外部環境への迅速な対応を可能にするCorticon

BRMS徹底活用ブログ

No.16 変化する市場、外部環境への迅速な対応を可能にするCorticon

2017.06.06 Progress Corticon

本エントリーは株式会社アシスト様が寄稿したエントリー(https://www.ashisuto.co.jp/product/category/brms/progress_corticon/column/detail/brmstech16.html)を転載したものとなります。

No.16   変化する市場、外部環境への迅速な対応を可能にするCorticon

2016年4月からProgress製品を担当しています棚橋浩志です。自宅に10才の子供に借りた「相対性理論」の本が放置してあり、今私が読み耽っています。 大学選考で物理学科を志望していたことがあり、その時にも「相対性理論」をさらっと学習しましたが改めてその理論の奥深さに日々悩まされる毎日となりました。 「光の速度だけが絶対であってそれ以外は全てが"相対"になるんだ!」とすんなり割り切れない性格のため、またしばらくの間悩まされる事になると思います。
さて今回はルールシートの条件(条件文)について「相対性理論」のように宇宙をテーマに考察してみたいと思います。
昨今の社会情勢は、ポイントカードが広く普及して、購入ポイントや提示ポイント、さらには期間限定のボーナスポイントが常に発生しています。宇宙でもポイントシステムの導入が開始されようとしていますという仮想の題材から・・・

条件制御構文

プログラミングで条件(条件文)と言えば if文 の事になります。ある条件を満たした時に処理したい場合の制御構文になります。 本文では"ある条件"の事を『条件』または『条件文』、"条件が満たされた時に実装される処理"を『実行処理』と記述します。 低級プログラミング言語の頃には条件制御構文は IF しかなく一条件一択しか出来ませんでした。ELSE の登場で一条件二択できるのは後になります。今でもたまに一条件一択の記述しか出来ないスクリプトが存在します。

一条件二択はその昔以下のような条件文を書いて物言いがありました。

if(x != 10){
	y=100;
}
else{
	y=0;
}

このような二重否定を使用するなと言われました。プログラムの構文は問題ないのですが、倫理というか論理というかメンテナンスの効率は悪いと反省して以後書かなくなりました。

ロジックによっては一条件多択しなければならない処理もでてきて、その場合には『条件文』の中に『条件文』を記述する『条件』のネスト(入れ子)を作成します。 Basicでは ELSEIF というプログラムを作成する人のみ楽にさせる制御構文が実装されましたが、メンテナンスをする人にとってはロジックを追うのが非常に不便でした。
メンテナンスを重視するのでネスト(入れ子)にはインデントを必須で使用させました。格段にプログラムが追いやすくなります。

if(x==0){
	y=0;
}
else{
	if(x==1){
		y=1;
	}
	else{
		if(x==2){
			y=2;
		}
		else{
			if(x==3){
				y=3;
			}
			else{
				if(x==4){
					y=4;
				}
				else{
					if(x==5){
						y=5;
					}
					else{
						else{
					}
				}
			}
		}
	}
}
IF x=0 THEN
	y=0
	ELSEIF x=1
		y=1
	ELSEIF x=2
		y=2
	ELSEIF x=3
		y=3
	ELSEIF x=4
		y=4
	ELSEIF x=5
		y=5
ELSE
	y=-1
END IF

このネスト(入れ子)を使用すると『条件』に主従関係が出来ます。最初の『条件』が"主"になり、その配下の『条件』が"従"になります。 「xが1かどうか」という"主"『条件』の配下に、「xが2かどうか」という"従"『条件』が配置されています。 これはプログラミングでの主従関係であり、xの値には主従関係はありません。

xが4である事は、xが0であるかどうかという『条件』の従属関係ではありません。x=2であることも、X=4である事もxにとっては独立した事象であり、プログラムを記述するためにだけに従属関係にしたということになります。 これがメンテナンスの時の難しさにもなります。従属関係の『条件』が書かれているプログラムから、xが独立した数値を取得した時の処理を書いているのか!となかなか関連出来ません。

さらには『実行処理』が同じ場合に下記の様に纏めて作成する人がいましたが、主従関係が複雑になる、メンテナンスが悪くなるという理由で書き直させました。上記で言及したように『条件』をネストさせる時点で既に本来の処理が見にくくなっているところに、『実行処理』が同じだからと纏めてしまってはますます本来の処理が想像できなくなります。

if(x==0){
	y=0;
}
else{
	if(x==1){
		y=1;
	}
	else{
		if(x==2 || x==5){
			y=2;
		}
		else{
			if(x==3 || x==4){
				y=3;
			}
			else{
				y=-1;
			}
		}
	}
}

その後一条件多択できる switch が実装されたC言語が登場しました。

switch (x)
{
	case 0:
		y=0;
		break;
	case 1:
		y=1;
		break;
	case 2:
		y=2;
		break;
	case 3:
		y=3;
		break;
	case 4:
		y=4;
		break;
	case 5:
		y=5;
		break;
	default:
		y=-1;
		break;
}

主従関係がなくなりすっきりとしました。メンテナンスの時にもxが独立した数値を取得したいのか!と容易に本来の処理が想像できるようになりました。 プログラマーだけでなくメンテナンスする人にとっても非常ありがたい条件制御構文の登場でした。

switchではswitchのネスト(入れ子)も可能でしたし、 if文 を加える事もできました。 C言語の時には『条件』はintegerの変数のみでしたが、現在の言語では文字列型でも何でも可能なように進化しました。

これで一条件多択は本来の処理が想像し易くなりすっきりとなりました。

複数条件 独立

次に『条件』が複数出てくる場合について考察してみます。 『条件』『実行処理』が独立して発生する場合には独立した記述ができます。以下の仕様について検討してみましょう。

火星カードを見せると火星記念グッズを受け取ります。
土星カードを見せると土星記念グッズを受け取ります。


この場合『条件』『実行処理』は完全に独立です。『条件』『実行処理』を2回実施するのでプログラムでは2回記述します。

if(火星カードを見せる==true){
	火星記念グッズを受け取る=true;
}
else{
	火星記念グッズを受け取る=false;
}
if(土星カードを見せる==true){
	土星記念グッズを受け取る=true;
}
else{
	土星記念グッズを受け取る=false;
}

このように纏めても問題ありません。

火星記念グッズを受け取る=false;
土星記念グッズを受け取る=false;
if(火星カードを見せる==true){
	火星記念グッズを受け取る=true;
}
if(土星カードを見せる==true){
	土星記念グッズを受け取る=true;
}

Corticon ではルールシートを2枚作成して、ルールフローでルールシートを2つ配置すれば完了です。

画像1-2-3

下記の様にルールシート1枚でも可能ですが、2次元のマトリクスで関連がでてきてしまう事と、表面積が大きくなるとパフォーマンスに影響を及ぼすという観点ではお薦めしたくはない方法です。

画像4

複数条件 独立 主従関係

記念グッズが減ってきたので以下の様に仕様を変更しました。

火星に到着して、火星カードを見せると火星記念グッズを受け取ります。
土星に到着して、土星カードを見せると土星記念グッズを受け取ります。


『条件文』のネストになります。火星にいる事が「主」になり、火星カードを見せるが「従」になります。今回の場合は主従が逆転しても問題になりませんが、「従」で二択や三択になると問題になるので主従を見極めて定義します。

画像5

上記の様に Corticon でルールを作成しましたが、"火星に到着する=false" の場合を全く定義していないので『完全性チェック』では "火星に到着する=false" の場合が補完されます。厳密に作成すれば下記の様なルールシートになります。

画像6-7

複数条件 独立 主従関係

記念グッズがなくなったので第二弾を下記の様な仕様で開始しました。

参加者には事前に惑星カードが1枚配られます。そのカードには1つの惑星のスタンプのみを押すことが出来ます。
火星に到着すると惑星カードに火星デザインのスタンプを押してもらえます。
土星に到着すると惑星カードに土星デザインのスタンプを押してもらえます。


『条件』は独立ですが、『実行処理』は独立ではなくなりました。惑星カードという共通のものにそれぞれのスタンプが押される処理になります。

画像8-9

ルールシートは出来ましたが処理が独立ではないために、時間を考慮する必要が出てきます。惑星カードに火星でスタンプを既に貰っている人が土星に到着した場合はどうすれば良いのでしょうか。逆の場合はどうすれば良いのでしょうか。
このような場合には、明示的に条件を加えて制御する必要があります。
スタンプを押す優先順位がない場合には「惑星カードにスタンプが押されていない場合(=惑星カード=null)」をそれぞれの条件の「従」条件に追加して以下のようになります。

画像10-11

複数条件 拡張

惑星カードは1つ以上のスタンプが押せなくて不評に終わったので、共通の惑星ポイントカードを導入して第三弾を下記の様な仕様で開始しました。

参加者には事前に惑星ポイントカードが1枚配られます。0点で初期化されているものとします。
火星に到着すると惑星ポイントカードに 3点加算されます。
土星に到着すると惑星ポイントカードに 9点加算されます。


『実行処理』は独立ではないですが、惑星ポイントカードは性質上、時間を考慮する必要がなく独立の様に扱うことが出来る為に以下のようになります。

画像12-13

このような『実行処理』が独立ではない場合には以下のようにルールシートを纏めます。

画像14

さらに『条件』を単純にして"宇宙船の位置"にしましょう。

画像15

『条件』または『条件文』および『実行処理』が独立ではない形になりました。

複数条件 拡張

惑星ポイントカードは大変好評で、以下の様な仕様が追加されました。

火星人が火星に到着すると惑星ポイントカードに 3点が3倍されて加算されます。

さてロジックの修正箇所が見えますか?

さらに惑星ポイントカードには以下の様な仕様が追加されました。

2017/12/31迄は地球人が火星に到着すると惑星ポイントカードに 3点が10倍加算されます。
2020/12/31迄は地球人が土星に到着すると惑星ポイントカードに 9点が10倍加算されます。


もうプログラミング言語でのロジックでは修正箇所が簡単には見えてこず、くそ!惑星ポイントのおかげで今日も残業だ!となる事だと思います。しかし条件を表形式で管理する Corticon では、以下のように簡単に修正出来ます。

画像16-2s

画像をクリックで拡大

拡張性とメンテナンス性を重視して、まずは基本ポイントを付与して、続いて条件によってボーナスポイントを付与する形にしました。プログラミング言語だと・・・・・考えたくなくなるほど Corticon での実装が簡単です。

惑星ポイントカードは好評で、さらに以下の様な仕様が追加されました。

2018/12/31迄は地球人が土星発金星行の宇宙船に乗船して金星に到着すると惑星ポイントカードに 2点が20倍加算されます。
土星発火星行の全惑星に着陸する宇宙船に乗船して金星に到着すると惑星ポイントカードに 3点が20倍加算されます。
金星に到着すると惑星ポイントカードに 2点加算されます。
ポイント加盟記念として2017/10/31迄金星に到着すると惑星ポイントカードに 2点が10倍加算されます。
木星に到着すると惑星ポイントカードに 7点加算されます。
ポイント加盟記念として2017/10/31迄金星に到着すると惑星ポイントカードに 7点が10倍加算されます。


きっと改修に明け暮れる毎日がまっている事でしょう。そしていつか改修による不具合が発生するのではないでしょか?

最後に

現実の社会でもポイントシステムの裏では誰かがシステムを改修している一方で、
誰かが次の新しい企画を検討しています。
この様な"いたちごっこ"から脱却するには見方を変える必要があるのではないでしょうか。
既存のプログラミング言語では手詰まりの状態ではないのでしょうか。
「相対性理論」においては自分が動いているか相手が動いているかは問題ではありませんでした。
この様に『条件』をプログラミング言語でネストを使用して書こうが、Corticon で表形式で書こうが問題ではないと思うようになってきました。
むしろますます複雑に連携していく社会においては、メンテナンス性や拡張性という点では Corticon の方がきっと残業時間は減ると思います。