以前こんな話を書いている。
計算の中間値を置くところを浮動小数点型に統一していたためのようだ。
ここに格納される値は必ずしもアナログ的な量に限らず、論理値も入りうる。
その論理値、具体的には –1.0, 0.0, 1.0 の3値論理が多かったのだが、
この比較のために==や!=を使っていたようである。
しかし3値論理ってなんだよって話である。
電気回路ではトライステートというと、ハイインピーダンスを含めた3状態を表す。
HIレベル, LOWレベルを出力している時を”H”,”L”と表記して、
ハイインピーダンス状態を”Z”と書くのはよくみられる。
でも、そういう話ではないんですよね。
3値論理を使って論理演算をしているんですよね。
コンピュータの世界で3値論理というとSQLのものがよく知られていて、
true, false, unknownの3状態をとるそうである。
値が存在しないNULLに関わる論理をunknownと呼んでいるそうである。
比較式 foo=1 の結果がfoo=1ならばtrue, foo=2ならばfalse, foo=NULLならばunknownとなると。
このためSQLのunknownはNULLと書かれることもある。
今回のシステムではこういう考えで生じる3値論理ではないんだけど、
論理演算の考え方はSQLの3値論理と同じで良さそうである。
X OR Y という論理演算は、XがtrueならばYの値を見るまでも無くtrue、
XがfalseならばYの論理値がそのまま計算結果になる。
これはPerlなどある種のスクリプト言語ではよく使われる仕組みで、
“or die”と付けると、結果がfalseの場合はdieを実行する意味になる。
“$x[$n] || 0”と書くと、$x[$n]にtrueと評価できる値があるときはその値、
空の場合などfalseと評価できる場合は0を与えるという式になる。
この考えをunknownが絡む演算に適用すればよくて、
true OR unknown = true, false OR unknown = unknown である。
交換則が成り立つので前後を入れ換えても同じ、あとはunknown OR unknown = unknownと定義すれば求まる。
同様に X AND Y という論理演算も、Xがfalseの場合はYを見るまでも無くfalse、
Yがtrueの場合はYの値がそのまま計算結果になる。
それゆえ false AND unknown = false, true AND unknown = unknown, unknown AND unknown = unknown となる。
論理反転は単純に trueとfalseを入れ換えるということだから、
unknownは反転してもやはりunknownになる。
排他的論理和は X XOR Y = (X AND (NOT Y)) OR ((NOT X) AND Y)で、
X=unknownとおくと、Y=trueのときは unknown OR false = unknown、
Y=falseの場合は false OR unknown = unknown となるから、
unknownが絡む排他的論理和は全てunknownになると考えるべきようだ。
3値論理で排他的論理和を考えるシチュエーションはわからないけど。
さて、このシステムで3値論理は何に使われているのか。それはヒステリシスを持たせるためである。
デジタル回路でシュミットトリガというのがありますが、
あれは2つの閾値があり L→HとH→Lで閾値電圧が変わるわけですね。
2つの閾値電圧の間で入力電圧がばたついても前状態を保つわけである。
この実現手段として、上の閾値以上、下の閾値以下、その間の3状態を持つわけである。
これにそれぞれ 1.0, –1.0, 0.0という数値を割り当てていると。
SQLの3値論理表現でいえば true, false, unknownに対応する。
その上で演算結果がunknownの場合は出力値は前回値保持にする。
true→unknown→trueと変化すればずっとtrueを出力し続けるし、
false→unknown→falseと変化すればずっとfalseを出力し続ける。
出力値が変わるのはunknown状態を越えて状態が変化したときだけである。
で、この条件を複数組み合わせるときに論理演算が必要になると。
X or Y or Z という論理演算の結果を出力する場合、
いずれかの条件がtrueとなればtrueを出力し、
全ての条件がfalseとなればfalseを出力するという形になる。
これ以外の状態、すなわちfalseとunknownが混在している場合は前回値保持である。
こういう形で複数条件を積み重ねるのが基本ということか、
さっきの閾値判定を行う処理は必ず他の論理値を取るようになっていたが、
やっていることとしてはこんなところである。
さらにこの出力処理の先にはオンディレータイマ、オフディレータイマもあるんですけどね。
オンディレータイマはON状態を出力する指示が一定継続してからONを出力するものである。
結果として一定時間以下のON指示は無視されることとなる。
こちらもバタつき対策だとは思うのだが、こちらはごく短時間の急変動を想定しているのだろうな。
一方のヒステリシスは中途半端な値でゆっくり動く場合にも対応できる。
判定処理で3値論理を出力するところに「ヒステリシス」と書かれていて、
これじゃあヒステリシスとして機能していないのでは?
と思ったけど、unknownは出力処理で前回値保持とすることで対応してたんですね。
勘違いしてたんですけど、確かにこれならいけましたね。