BDD 演習問題と回答

基礎、簡約、Apply、量化、変数順序、実装、応用まで、理解確認用の問題と詳細解答をまとめた演習レポート。

practice

0. 使い方

まず問題だけを読み、紙に BDD や式を書いてから解答を開く。検索と難易度フィルタで弱点分野だけを復習できる。

問題数: 58。一部の問題は DOT + d3-graphviz の図を含む。
practice

A. 基礎・意味論

問 1 基本

BDD の非終端節点 \(v=(x_i,low,high)\) が表す関数を Shannon 展開で書け。

解答を表示

\(F_v=(\lnot x_i\land F_{low})\lor(x_i\land F_{high})\)。low は \(x_i=0\)、high は \(x_i=1\) の余因子を表す。

問 2 基本

終端 0 と終端 1 は何を表すか。

解答を表示

終端 0 は恒偽関数 \(\bot\)、終端 1 は恒真関数 \(\top\)。どちらも変数に依存しない。

問 3 基本

low 枝と high 枝の違いを、余因子という言葉を使って説明せよ。

解答を表示

low 枝は \(F|_{x_i=0}\)、high 枝は \(F|_{x_i=1}\) への遷移である。

問 4 基本

順序付き BDD で、根から終端への経路に同じ変数が 2 回現れてよいか。

解答を表示

現れてはいけない。OBDD では各経路で変数 index が狭義単調増加する。

問 5 基本

ROBDD における R は何を意味するか。

解答を表示

Reduced の R。同型節点の統合と冗長節点の削除が完全に適用されていることを意味する。

問 6 基本

変数順序 \(x_0

解答を表示

その枝が指す部分関数では \(x_1\) は don’t care。\(x_1=0\) と \(x_1=1\) の余因子が同じなので節点が削除され、index が飛ぶ。

問 7 基本

関数 \(f=x_0\land x_1\) の順序 \(x_0

解答を表示

\(x_0=0\) なら関数は常に 0 なので、root の low 枝は終端 0 へ行く。

問 8 基本

関数 \(f=x_0\lor x_1\) の順序 \(x_0

解答を表示

\(x_0=1\) なら関数は常に 1 なので、root の high 枝は終端 1 へ行く。

問 9 標準

図の BDD が表す関数を求めよ。

問題 9 の図
この図を読み取って解答する。
DOT + d3-graphviz
DOT ソースを表示
digraph ExRead { graph [rankdir=TB, bgcolor="transparent", margin=0.04]; node [fontname="Helvetica", fontsize=12, style=filled, fillcolor="white", color="#334155"]; edge [fontname="Helvetica", fontsize=10, arrowsize=.65, color="#475569"]; x0 [label="x0", shape=circle, fillcolor="#eaf0ff", color="#1d4ed8"]; x1 [label="x1", shape=circle]; x2 [label="x2", shape=circle]; T0 [label="0", shape=box, fillcolor="#fff1f2", color="#fb7185"]; T1 [label="1", shape=box, fillcolor="#ecfdf5", color="#34d399"]; x0 -> x1 [label="0", style=dashed]; x0 -> x2 [label="1", penwidth=1.6]; x1 -> T0 [label="0", style=dashed]; x1 -> T1 [label="1", penwidth=1.6]; x2 -> T1 [label="0", style=dashed]; x2 -> T0 [label="1", penwidth=1.6]; }
解答を表示

root で \(x_0=0\) なら \(x_1\)、\(x_0=1\) なら \(\lnot x_2\)。したがって \(f=(\lnot x_0\land x_1)\lor(x_0\land\lnot x_2)\)。

問 10 標準

同じ変数順序を使う 2 つの ROBDD で root ID が同じなら何が言えるか。

解答を表示

同じ BDD マネージャ内なら同じ Boolean 関数を表す。標準性により関数同値が ID 比較で判定できる。

practice

B. 簡約・標準形

問 11 基本

low と high が同じ節点を指す非終端節点は、なぜ削除できるか。

解答を表示

その変数の値に関係なく同じ部分関数へ進むため、節点が表す関数は子の関数そのものになる。

問 12 基本

2 つの節点 \((x_i,l,h)\) と \((x_i,l,h)\) はなぜ統合できるか。

解答を表示

変数、low 子、high 子がすべて等しいので Shannon 展開が同一であり、表す関数が同じだから。

問 13 標準

図の未簡約 BDD を簡約せよ。

問題 13 の図
この図を読み取って解答する。
DOT + d3-graphviz
DOT ソースを表示
digraph ExReduce { graph [rankdir=LR, bgcolor="transparent", margin=0.04]; node [fontname="Helvetica", fontsize=12, style=filled, fillcolor="white", color="#334155"]; edge [fontname="Helvetica", fontsize=10, arrowsize=.65, color="#475569"]; p [label="x0", shape=circle]; a [label="x1", shape=circle]; b [label="x1", shape=circle]; T0 [label="0", shape=box, fillcolor="#fff1f2", color="#fb7185"]; T1 [label="1", shape=box, fillcolor="#ecfdf5", color="#34d399"]; p -> a [label="0", style=dashed]; p -> b [label="1", penwidth=1.6]; a -> T0 [label="0", style=dashed]; a -> T1 [label="1", penwidth=1.6]; b -> T0 [label="0", style=dashed]; b -> T1 [label="1", penwidth=1.6]; }
解答を表示

2 つの \(x_1\) 節点は同じ \((x_1,0,1)\) なので統合される。その後 root \(x_0\) は low も high も同じ \(x_1\) を指すため削除される。結果は \(x_1\) だけの BDD。

問 14 標準

固定順序で ROBDD が一意になることの実用上の利点を 2 つ挙げよ。

解答を表示

同値判定が root ID 比較で済むこと、同じ部分関数が自動的に共有されてメモ化とキャッシュが効くこと。

問 15 標準

\(f=x_0\land x_1\) と \(g=x_1\land x_0\) は、同じ変数順序の ROBDD ではどうなるか。

解答を表示

構文は違うが関数は同じなので、同じ順序で構築し簡約すれば同じ root を持つ。

問 16 応用

unique table のキーに \((var,low,high)\) を使う理由を説明せよ。

解答を表示

節点の意味は変数と 2 つの子で完全に決まる。同じキーは同じ Shannon 展開を意味するため、正準共有に必要十分な局所情報である。

問 17 応用

low=high の検査は unique table 検索の前と後のどちらで行うべきか。

解答を表示

通常は前。low=high の場合は節点を作らず子を返すだけで、冗長節点を unique table に登録してはいけない。

問 18 応用

補辺を使う実装で unique table キーを扱うときの注意点は何か。

解答を表示

同じ関数が複数の補辺表現を持たないよう正規化規約が必要。節点本体と edge の補フラグの扱いを一貫させる。

practice

C. 操作・Apply

問 19 基本

Apply(AND, u, v) で u と v がともに終端なら何を返すか。

解答を表示

終端値に AND を適用し、偽なら終端 0、真なら終端 1 を返す。

問 20 標準

Apply の次の変数を \(\min(level(u),level(v))\) で選ぶ理由を説明せよ。

解答を表示

出力 BDD でも変数順序を守るため、2 入力のうち次に現れる最小 index の変数を読む。

問 21 標準

片方の節点が level \(k\) の変数を持たない場合、Apply の low/high 再帰ではその節点をどう扱うか。

解答を表示

両方の分岐で同じ節点として使う。つまり \(u_0=u_1=u\)。その節点は現在変数に依存しない。

問 22 標準

computed table は何をメモ化するか。

解答を表示

\((op,u,v)\) から結果 root への対応をメモ化する。単項操作では \((op,u,parameter)\) などを使う。

問 23 標準

\(f=x_0\), \(g=x_1\) として \(f\land g\) の ROBDD はどうなるか。順序は \(x_0

解答を表示

root は \(x_0\)。low は 0、high は \(x_1\)。\(x_1\) の low は 0、high は 1。

問 24 標準

\(f=x_0\), \(g=\lnot x_0\) として \(f\land g\) の結果は何か。

解答を表示

恒偽なので終端 0 になる。

問 25 応用

NOT を単純再帰で実装するとき、非終端節点では何をするか。

解答を表示

low と high に NOT を再帰適用し、同じ変数で \(mk(var,not(low),not(high))\) を呼ぶ。終端では 0 と 1 を入れ替える。

問 26 応用

ITE\((c,t,e)\) を AND/OR/NOT で表せ。

解答を表示

\(ITE(c,t,e)=(c\land t)\lor(\lnot c\land e)\)。専用三項 Apply として実装するとキャッシュ効率がよい。

問 27 応用

restrict\((F,x,0)\) は BDD 上でどのように実装できるか。

解答を表示

対象変数 \(x\) の節点に到達したら low 子を採用する。対象変数より index が大きい節点に来たら、その部分 BDD には \(x\) がないのでそのまま返す。

問 28 応用

なぜ Apply の最後に必ず mk を呼ぶ必要があるか。

解答を表示

low/high が同じなら削除し、既存の同型節点があれば共有するため。mk を通さないと ROBDD の簡約性が壊れる。

practice

D. 量化・数え上げ

問 29 基本

\(\exists x.F\) を restrict で表せ。

解答を表示

\(\exists x.F=F|_{x=0}\lor F|_{x=1}\)。

問 30 基本

\(\forall x.F\) を restrict で表せ。

解答を表示

\(\forall x.F=F|_{x=0}\land F|_{x=1}\)。

問 31 標準

\(F=x\land y\) について \(\exists x.F\) を求めよ。

解答を表示

\((0\land y)\lor(1\land y)=0\lor y=y\)。

問 32 標準

\(F=x\oplus y\) について \(\exists x.F\) を求めよ。

解答を表示

\((0\oplus y)\lor(1\oplus y)=y\lor\lnot y=1\)。

問 33 標準

\(F=x\oplus y\) について \(\forall x.F\) を求めよ。

解答を表示

\((0\oplus y)\land(1\oplus y)=y\land\lnot y=0\)。

問 34 標準

sat count で枝が 2 変数を飛ばして終端 1 に到達した場合、寄与はいくつか。

解答を表示

飛ばされた 2 変数は任意なので \(2^2=4\) 個の割当を表す。

問 35 応用

BDD の sat count が真理値表列挙より速い場合がある理由を説明せよ。

解答を表示

同じ部分関数を共有し、スキップ変数を \(2^k\) の係数としてまとめて数えるため。

問 36 応用

モデル列挙で、終端 1 に到達する前に index が飛んでいる場合はどう出力するか。

解答を表示

飛ばされた変数を don’t care として扱う。展開するなら全組合せ、圧縮表示なら * を使う。

practice

E. 変数順序・index

問 37 基本

変数順序とは何か。

解答を表示

BDD の全経路で変数を読む順番を定める全順序。実装では各変数に整数 index を割り当てる。

問 38 基本

index が小さい変数は図の上と下のどちらに現れやすいか。

解答を表示

rankdir=TB の図では通常、index が小さい変数ほど上に現れる。

問 39 標準

\(EQ_n=\bigwedge_i(a_i\leftrightarrow b_i)\) に良い順序の例を挙げよ。

解答を表示

\(a_0

問 40 標準

同じ \(EQ_n\) に悪い順序の例を挙げよ。

解答を表示

\(a_0

問 41 標準

multiplexer でセレクタ変数を先に読む順序が有利な理由を説明せよ。

解答を表示

セレクタを読めば必要なデータ入力が 1 本に絞られ、他のデータ変数が don’t care になる。

問 42 応用

Apply 中に \(level(u)

解答を表示

\(v\) の部分関数は現在の変数に依存していないから。

問 43 応用

動的変数順序変更 dynamic reordering が必要になる理由を説明せよ。

解答を表示

良い順序は問題依存で、悪い順序では節点数が指数的に増えるため。sifting などで実行中に改善する。

問 44 応用

変数 index を変更すると既存節点の意味はどうなるか。

解答を表示

単にラベルを変えると順序制約と標準性が壊れる。reordering は BDD を構造的に作り直しながら行う。

問 45 応用

枝が終端に飛ぶとき、sat count では終端の level を何と考えるか。

解答を表示

変数数 \(n\)。現在 level から \(n\) までの未読変数が自由なので \(2^k\) を掛ける。

問 46 応用

BDD で「変数が図に出てこない」ことは、その変数が関数全体に不要であることを必ず意味するか。

解答を表示

root から到達可能な全 BDD に出てこないなら不要。特定枝で出てこないだけなら、その分岐で不要という意味。

practice

F. 実装

問 47 標準

BDD マネージャが管理すべき主要データを 4 つ挙げよ。

解答を表示

節点配列、unique table、computed table、変数順序表。実装によって参照カウントや GC 情報も持つ。

問 48 標準

節点 ID 0 と 1 を終端に固定する利点は何か。

解答を表示

終端判定が高速になり、false/true の表現が一貫する。

問 49 標準

ガベージコレクションが必要な理由を説明せよ。

解答を表示

中間操作で一時節点が多く作られるため、参照されなくなった節点を回収しないとメモリが増え続ける。

問 50 応用

computed table を無限に保持すると何が問題になるか。

解答を表示

古い節点 ID や回収済み節点を指すエントリが残り、メモリを圧迫する。GC 時の無効化やサイズ制限が必要。

問 51 応用

再帰実装でスタックが深くなる条件は何か。

解答を表示

変数数が多く、経路が長い場合。Apply では 2 つの BDD の depth に依存する。

問 52 応用

BDD のノード数を数えるとき、マネージャ内の全節点数ではなく root からの到達節点数を見るべき理由は何か。

解答を表示

マネージャには他の関数や過去の中間節点が残る。対象関数のサイズは root から到達できる節点だけで測る。

practice

G. 応用・発展

問 53 標準

BDD が SAT 判定に使える理由を説明せよ。

解答を表示

制約全体の BDD を構築し、root が終端 0 なら充足不能、そうでなければ充足可能。

問 54 標準

BDD がモデル検査で使われる場面を 1 つ説明せよ。

解答を表示

状態集合や遷移関係を Boolean 関数として表し、到達可能状態計算や像計算を BDD 操作で行う。

問 55 応用

関係積 \(\exists x.(R(x,y)\land S(y,z))\) で BDD が有効な理由を述べよ。

解答を表示

AND と存在量化を BDD 上で行うことで、巨大な真理値表を明示せずに関係合成を計算できる。

問 56 応用

BDD が苦手な関数の例を挙げよ。

解答を表示

整数乗算の中央ビットなどは任意の変数順序で指数的な BDD サイズを持つ典型例。

問 57 応用

ZDD と BDD の違いを簡潔に説明せよ。

解答を表示

BDD は Boolean 関数一般の標準表現。ZDD は疎な集合族に特化し、high が 0 の節点を削除するゼロ抑制規則を使う。

問 58 応用

AIG や SAT solver と比べた BDD の強みを 1 つ挙げよ。

解答を表示

固定順序の ROBDD は標準形なので、同値判定、モデル数え上げ、量化が構造的に扱いやすい。