PowerPoint プレゼンテーション

システム開発実験No.7
解 説
“論理式の簡略化方法”
【0】 簡略化で用いる基本的な規則
A B
+
A B
A ( B
+ B )
A
(例)
A: 高速である
B: 大容量である
高速で大容量であるか
または 高速で大容量でない
高速でかつ(大容量か または大容量でない)
高速である
真 or 偽 =>
常に真 =>
結果に影響を与えないので省略
【1】 簡略化アルゴリズムの考え方
論理式の各項を座標空間内に配置されたトークンとして捉える
《例1》
入力論理式:
座標値:
A B + A B + A B
(0 0) (1 0) (1 1)
B
1
1,1
座標空間に配置する
簡略化可能なので移動
変数が異なるので
もはや簡略化できない
1,0 1, -1A
0,0 0
-1,
0
B
1
+
A
-1は,この変数に
関して簡略化したこ
とを意味する
《例2》
入力論理式:
ABC
+ ABC +ABC
+ ABC +
ABC
+ ABC
0,0,1
1,1,1
座標値に変換する
座標値 :
1,0,0
0,1,1
0,1,0
1,1,0
3次元空間の各座標番号で示される位置にトークンを配置する
C
1
座標番号とは,空間の各点の
座標値を2進数のビット列と解釈し
10進数に変換したものである
0,0,
1
5
(1,0,1)
7
1,1,1
0,1,
0 2
4
A
1,0,
0
0,1,
1 3
1,1,
0 6
B
C
移動可能な方向へすべて動いたら移動元のトークンを消す
例2の簡略化動作
1
簡略結果へ変換
第2回目の移動
第1回目の移動
3
0,-1,
0,0,1
1
5
0,1,1
7
(1,0,1)
-1,1,1
1,1,1
0, 1, -1
-1,1,-1
0,1,0
A
1,0,0
1,-1,
0
4
2
1,1,
0
6
AC
-1,1,-1
-1, 1, 0
AC
1,1,-1
B
B
【2】データ構造の設計
アルゴリズムを実現するにはどんなデータ構造が必要か!
① 簡略化されたトークンを含め
どんなトークンが存在するかを
識別するためのデータ
(テーブルCoord)
p.126参照
C
1
0,0,
1
5
(1,0,1)
A
② 存在するトークンの
移動可能な軸方向を示すデータ
(テーブル pair_tbl) p.127参照
7
1,1,1
0,1,
0
2
4
1,0,
0
1,1,1
0,1,
3
1
1,1,
0
1,1,6
1
B
③ 各座標点にどんなトークンが
あるかを記録しておくデータ
(テーブル reduce_tbl) p.128参照
(1) 各トークンは,001や010のような値を識別子としてもつ.
配列coordは,どのようなトークンが存在するかを格納しておく配列である.
簡略化された結果,変数値がー1になったトークンも,この配列に格納される.
座標番号位置(=配置された
トークンの識別番号でもあ
る)
nPoint
初期配置されたトークンの数
<
0
1
2
3
4
5
6
7
8
9
10
11
12
13
配列coord
0
0
0
1
0
1
1
0
1
0
1
0
1
1
1
-1
1
-1
0
0
1
1
1
1
-1
1
1
-1
0
1
-1
1
0
0
-1
1
>
初期配置されたトークンの識別子
新たに生成された(簡略化された)
トークンの識別子
nCoord
簡略化されたトークンも含めた
トークンの最大数
図3-17
座標番号に置かれたトークンと識別子を管理するテーブル
(2) 存在するトークンの移動可能な軸方向を示す配列
< 配列pair_tbl >
始端座標番号(from) 終端座標番号(to)
1
1
1
2
2
2
3
4
4
6
nPair
(辺の数 + 1)
3
6
7
3
6
7
7
6
7
7
1
2
0
0
1
2
移動可能な軸(axis)方向 を示した
もの.例えば,0ならば変数 A の軸
方向, 1なら変数 B の軸方向,2なら
変数Cの軸方向へ移動可能である.
fromとtoの差が2のべき乗でないもの
は移動可能な軸方向を示す配列から
削除する.
なぜなら,座標点は2進点の値と解釈
している{例えば座標(110)や座標
(010)等}. そこでトークンが進める
方向を2つの座標点の差で表すと,
その間には上記の例で言うと(100)(
=23)の差がある.
したがって,トークンが移動可能な
軸方向は,始端座標番号(2進数を
10進数に置き換えたもの)と終端座
標番号の間には,2のべき乗の差が
なくてはいけない.
(3) 各座標点にどんなトークンが存在しているかを記録しておく配列
p.132参照
各座標番号に存在しているトークン数
座標番号
0
1
2
3
4
5
6
7
⑥もはやトークンが動けなるなるまでこの操作を繰り返す
reduce_tbl
1
1
1
1
1
2
3
4
1
1
6
7
reduce_tbl
②2つのノードを接続する
辺の両端にトークンが存
在するときのみ調べる
0
1
2
3
4
5
6
7
2
3
2
2
1
2
3
4
2
1
6
7
13
11
9
10
12
8
reduce_tbl
0
1
2
3
4
5
6
7
1
2
1
1
13
11
9
10
1
8
12
③簡略化の結果,生成したトー
クンの識別番号を置く
① 初期配置として各座標位置に
座標番号をもったトークンを置く
④ 簡略化に使用されたトークン
であることを示す丸印を付ける
⑤ すべてのトークンを移動
したら簡略化に使用された
トークンを消す
《 簡略化の基本的なアルゴリズム 》
関数 do_reduce ( )
各座標点に入力された項に対応するトークンを初期配置する
移動可能な軸方向にもはやトークンが移動できなくなる(簡略化できなくなる)まで繰り返す
移動可能な軸の数だけ繰り返す
移動可能な辺の両端にトークンが存在するか
Yes
Yes
No
両端にあるトークンは簡略化が可能か matchToken(… )
No
簡略化した結果を示す新たなトークンを簡略化の移動先に置く
moveToken(トークンID,到着ノード,軸方向)
両端のトークンに簡略化されたことを示す印を付ける
簡略化に使用したトークンを座標点から消去する
欠損論理変数の個所を補い,あたかも標準形が
入力されたかのようにデータを生成せよ
【課
題】
(例1)
A
C
Bが何であっても必ず真なので,
このように変形しても結果には影響ない.
A ( B + B ) C
A B C + A B C
(例2)
A
このような標準形式の論理式が入力さ
れたかのように変数データを生成する
D
A ( B + B ) ( C + C ) D
このような標準形式の論理式が入力さ
A B C D + A B C D
+ A B C D
れたかのように変数データを生成する
+ A B C D
(1)欠損変数を補う方法について
生成する変数のパターンを見てみると…
A B C D + A B C D
+ A B C D
1
1
1
0
0
+ A B C D
1
0
2進数のビットパターンになっている
欠損変数の数nが2なら,
nの2乗(=4)個のビットパターンを
あたかも入力されたかのように生成すればよ
い!!
0
(2) 具体的なプログラミングに必要なデータ
① 論理式の中の各項を格納しておくterm_tblとは!
(例)入力された論理式
B C D
+
minBit(Bより前の変数はない)
配列 term_tbl
0
1
nTerm
A
B
C
O
1
2
-1
1
1
-1
B E
maxBitSize(Eより後の変数はない)
D
E
F
3
4
5
1
1
-1
-1
第1項目
-1
-1
1
-1
第2項目
2
3
この変数が入力されなかった欠損変数であることを示し
ている.これらの変数をあたかも入力されたかのように
生成する
配列
exist
False
True
True
True
True
項の中で出現した変数=True
False
例えば,Term_tblの2行目を取り出したとき
配列
False
exist
True
A
配列 term_tbl [ 1 ]
True
True
C
D
B
-1
1
-1
True
E
-1
F
1
-1
-1は欠損変数;
欠損変数の個数=2
●このようなビットパターンを欠損個所に
埋め込んだ入力変数データを作成する
欠損変数の個数
False
1=
0 0 00 0 1
-1
1
0
0
1
-1
j= bit_pat = 0
-1
1
0
1
1
-1
j= bit_pat = 1
-1
1
1
0
1
-1
j= bit_pat = 2
-1
1
1
1
1
-1
j= bit_pat = 3
22
欠損変数を生成する手順の概要
【 関数translate_to_point 】
カウンタを i として, 入力された項の数nTermだけ繰返す
すべての項に現れた変数が配列existに記録されている. それらを参照しながら
term_tblの i行目に格納された i番目の項に含めれる欠損変数の個数を見出す
欠損変数の個数 > 0
No
term_tblのi行目の
データを,一旦一次
元配列termにコ
ピーする.
関数
store_to_coord(term
)を呼出し,termを座
標空間に配置する
Yes
生成する変数のビットパターン数nGenTerm =
pow (2, 欠損変数の個数)
カウンタを n として, 生成する変数のビットパターン数nGenTerm
だけ繰返す
欠損変数以外の変数は,そのまま用いるので,term_tblの
i行目のデータを,一次元配列termにコピーする.
// ビットパターンはtermに埋め込むものとする
カウンタ n を 生成用のビットパターン(bit_pat)として用いる
termの中の欠損変数の位置を探し出し, ビットパターンの
1ビットをtermの欠損変数位置に次々と埋め込む
この部分を作成する
関数store_to_coord(term)を呼出し,termを座標空間に配
置する
ビットパターンのそれぞれの1ビットを
変数位置に次々に埋め込むには
【ヒント】 ビットパターンの最下位1ビットを取り出し,その値を埋め込む.
ビットパターン(bit_pat)
0 0 0 0 0 0 1 0
& 演算
マスク(=1)
bit_pat >> = 1;
0 0 0 0 0 0 0 1
1ビット右シフト演算
ビットをシフトする
演算
0 0 0 0 0 0 0 1
& 演算
マスク(=1)
0 0 0 0 0 0 0 1
演算結果
演算結果
0 0 0 0 0 0 0 0
X = bit_pat & 1;
1ビットシフト後のビットパターン
(bit_pat)
0 0 0 0 0 0 0 1
Xには0が
入る
X = bit_pat & 1;
Xには1が
入る