+、・演算子は、OR、AND関数で記述する。
各変数に真理値表のビットパターンを設定して、式を計算して真理値表を得る。
!論理式の計算
DEF AND3(a,b,c)=AND(AND(a,b),c) !3変数以上の場合
DEF AND4(a,b,c,d)=AND(AND(a,b),AND(c,d))
DEF OR3(a,b,c)=OR(OR(a,b),c)
DEF OR4(a,b,c,d)=OR(OR(a,b),OR(c,d))
LET C1=NT(0) !1 ※-1のビットパターン
!------------------------------ ここまでがマクロの定義
LET N=3 !変数の数 ※1~5
LET A=BOOL(N,1) !N個の変数の1番目
LET B=BOOL(N,2)
LET C=BOOL(N,3)
!LET D=BOOL(N,4)
!LET E=BOOL(N,5)
LET nA=NT(A) !A' 補元
LET nB=NT(B)
LET nC=NT(C)
!LET nD=NT(D)
!LET nE=NT(E)
!●論理式の真理値表をつくる
PRINT BitPTN$(N, A); ":A"
PRINT BitPTN$(N, B); ":B"
PRINT BitPTN$(N, C); ":C"
LET f=OR3(AND3(A,B,C), AND3(A,nB,C), AND3(A,B,nC))
PRINT BitPTN$(N, f); ":ABC+AB'C+ABC'"
PRINT
!●論理式を主加法標準展開、主乗法標準展開する
LET f=OR(A,AND(B,C))
!PRINT BitPTN$(N, f); ":A+BC"
CALL PrintPDCF(N,f)
CALL PrintPCCF(N,f)
PRINT
!●クワイン・マクラスキー法(Quine-McCluskey algorithm)で式を簡単化する
!ステップ0 論理式の真理値表をつくる
LET f=OR4(AND3(nA,B,C),AND3(A,nB,C),AND3(A,B,nC),AND3(A,B,C))
!PRINT BitPTN$(N, f); ":A'BC+AB'C+ABC'+ABC"
!ステップ1 論理式を最小項で記述する(主加法標準展開)
DIM Term$(2^N) !最小項のビットパターン
LET CntOfTerm=0 !最小項の数
FOR i=0 TO 2^N-1 !真理値表を2進法の数とみなして小さい順に
IF Bit(f,i)=1 THEN !最小項なら
LET CntOfTerm=CntOfTerm+1
LET Term$(CntOfTerm)=right$(REPEAT$("0",N-1)&BSTR$(i,2),N) !ビットパターンは、…DCBA順
END IF
NEXT i
!FOR i=1 TO CntOfTerm !debug
! PRINT Term$(i)
!NEXT i
IF CntOfTerm=0 THEN !すべて0なら、終了!
PRINT "0"
STOP
ELSEIF CntOfTerm=2^N THEN !すべての1なら、終了!
PRINT "1"
STOP
END IF
!ステップ2 AB+AB'=Aを使って、最小項の変数を減らす
DIM wTerm$(100) !作業用にコピーする
FOR i=1 TO CntOfTerm
LET wTerm$(i)=Term$(i)
NEXT i
LET wCntOfTerm=CntOfTerm
DIM Term9$(2^N) !主項のビットパターン
LET CntOfTerm9=0 !主項の数
DO
DIM CHK(100) !圧縮の有無
MAT CHK=ZER
LET CntOfCompTRM=0 !圧縮された項の数
FOR i=1 TO wCntOfTerm-1 !すべての組合せで考慮する
FOR j=i+1 TO wCntOfTerm
LET CntOf1=0 !「1」の数
FOR k=1 TO N !ビット単位の排他的論理和を求める
LET t1$=wTerm$(i)(k:k)
LET t2$=wTerm$(j)(k:k)
IF (t1$="1" AND t2$="0") OR (t1$="0" AND t2$="1") THEN !「1」とする
LET CntOf1=CntOf1+1
LET PosOf1=k !消去される変数の位置
ELSEIF (t1$="0" AND t2$="0") OR (t1$="1" AND t2$="1") THEN !「0」とする
!skip it
ELSEIF (t1$="-" AND t2$="-") THEN !マスク・ビットなら
!skip it
ELSE !片方がマスク・ビットなら、候補ではない!
LET CntOf1=N
EXIT FOR
END IF
NEXT k
IF CntOf1=1 THEN !AB+AB'=A(ハミング距離が1)より、消去する
LET t$=wTerm$(i) !ビットパターン
LET t$(PosOf1:PosOf1)="-" !その変数を消去する
LET CHK(i)=1 !圧縮あり
LET CHK(j)=1
DIM CompTRM$(100)
FOR k=1 TO CntOfCompTRM !同じ項があるか確認する
IF t$=CompTRM$(k) THEN EXIT FOR
NEXT k
IF k>CntOfCompTRM THEN !なけらば、新規に登録する
LET CntOfCompTRM=CntOfCompTRM+1
LET CompTRM$(CntOfCompTRM)=t$
!PRINT i;j; t$ !debug
END IF
END IF
NEXT j
NEXT i
LET Cnt=0 !今回圧縮できなかった項の数
FOR i=1 TO wCntOfTerm !圧縮されないものは、主項となる
IF CHK(i)=0 THEN
LET Cnt=Cnt+1
LET CntOfTerm9=CntOfTerm9+1 !主項として記録する
LET Term9$(CntOfTerm9)=wTerm$(i)
END IF
NEXT i
IF Cnt=wCntOfTerm THEN EXIT DO !すべて圧縮できなければ、終了!
FOR i=1 TO CntOfCompTRM !次へ
LET wTerm$(i)=CompTRM$(i) !copy it
NEXT i
LET wCntOfTerm=CntOfCompTRM
LOOP
!ステップ3 主項表を使って冗長な主項を削除する
!ステップ3-1 主項表をつくる
DIM TT(CntOfTerm9,CntOfTerm) !主項表(図) ※TT(主項,最小項)
MAT TT=ZER
FOR i=1 TO CntOfTerm9 !最小項を包含する主項にチェックを入れる
FOR j=1 TO CntOfTerm
FOR k=1 TO N
LET t$=Term9$(i)(k:k)
IF t$<>"-" THEN !マスク・ビット以外が不一致なら、終了!
IF t$<>Term$(j)(k:k) THEN EXIT FOR
END IF
NEXT k
IF k>N THEN LET TT(i,j)=1 !すべてのビットが一致すれば、包含する
NEXT j
NEXT i
!MAT PRINT TT; !debug
!ステップ3-2 主項表から必須項を探す
DIM CHK2(CntOfTerm9) !必須項としてチェックする
MAT CHK2=ZER
MAT CHK=ZER
FOR j=1 TO CntOfTerm !主項表から必須項を探す
LET Cnt=0
FOR i=1 TO CntOfTerm9 !列で走査して、「1」が1つの列を見つける
IF TT(i,j)=1 THEN
LET Cnt=Cnt+1
LET PosOf1=i !行位置
END IF
NEXT i
IF Cnt=1 THEN !1つのものは、必須項とする
LET CHK2(PosOf1)=1
FOR k=1 TO CntOfTerm !必須項だけで最小項を包含するか(冗長性)
LET CHK(k)=OR(CHK(k),TT(PosOf1,k))
NEXT k
END IF
NEXT j
!MAT PRINT CHK; !debug
!MAT PRINT CHK2;
つづく