图谱连接

草稿

从 Circuit-SAT 到 SAT 的归约

通过为每个门设置辅助变量,并加入局部门约束,把电路可满足性实例翻译为 SAT 实例。

concept intermediate complexityalgorithmsnp-hardnesssatisfiabilityreductionscircuitslogic

这是从电路视图到公式视图的第一座桥:

  • 源问题:Circuit-SAT
  • 目标问题:SAT
  • 承诺:构造后保持 Yes/No 回答不变,且是多项式时间构造
归约桥对这个固定电路实例构造一个 SAT 公式。
源实例 C

4 个输入,6 个门,1 个输出

n1 = NOT x2 ; g1 = x1 AND n1 ; g2 = x3 OR x4 ; g3 = g1 AND g2 ; g4 = x2 AND x4 ; z = g3 OR g4
f局部门约束 + 最终 z
目标公式 Φ_C

可满足当且仅当 z 能取 1

Φ_C = z ∧ (∧_{g in Gates(C)} emit(g)),每个 emit(g) 仅由 AND/OR/NOT 构成。
答案保持桥复用共享示例赋值,对比电路输出和归约后公式输出。
赋值C(a)去 z 的合取最终 Φ_C(â)注解
1010111该赋值下电路输出与归约后的公式输出一致。
0101111该赋值下电路输出与归约后的公式输出一致。
0000010所有局部门约束为真,但 AND z 会继续拒绝。

共享的源电路与 circuit-sat 页面一致:

电路问题问:是否有某个开关设置能点亮灯输入是开关,逻辑门执行布尔规则,导线把 bit 向前传,z=1 表示输出灯亮。
开关 = 输入 bit1 AND 0 = 01 OR 0 = 1NOT 0 = 1灯亮表示输出 1
x11x20x31x40NOTn1=1ANDg1=1ORg2=1ANDg3=1ANDg4=0ORz=11

赋值字符串按 x1 x2 x3 x4 排列。例如 1010 表示:

x1=1,  x2=0,  x3=1,  x4=0.x1=1,\; x2=0,\; x3=1,\; x4=0.

引子问题:同样的“存在”问题,不同对象

Circuit-SAT 问是否存在输入让 z=1,SAT 问是否存在赋值让某个公式为真。 两者都在问“是否有满足的赋值”,但目标对象不同:一个是门电路,一个是公式。

所以需要一个显式翻译,保证答案保真,而不是靠直觉猜测。

朴素尝试:展开成一个大公式

一个直接想法是把每个门表达式一直替换,直到只剩输入。

朴素内联展开读 `z` 并反复替换右端表达式。
门级替换

n1 = NOT x2

g1 = (x1 AND NOT x2)

g2 = (x3 OR x4)

g3 = ((x1 AND NOT x2) AND (x3 OR x4))

g4 = (x2 AND x4)

z = (((x1 AND NOT x2) AND (x3 OR x4)) OR (x2 AND x4))

完全内联后的 zz = (((x1 AND NOT x2) AND (x3 OR x4)) OR (x2 AND x4))

该方法保持语义,但会反复复制共享子表达式。

语义上是对的,但这会复制共享子电路,难以控制规模。

为什么展开不是正确的一般解

Fan-out 本来是电路复用的优势;全量展开会把共享逻辑复制多份。

扇出复制快照对 fan-out 全部展开会重复共享子电路。
共享子表达式h=(a OR b); p=h AND c; q=h AND d; z=p OR q共享子表达式 h 只使用一次
=>
展开公式z=((a OR b) AND c) OR ((a OR b) AND d)内联后 h 被使用两次

因此我们不直接生成完整展开公式。

核心发明:门变量 + 局部门约束

给每个非输入节点加一个辅助变量,用它原来的门名命名:

  • n1g1g2g3g4z

每个门发出一条局部约束,强制该辅助变量等于门表达式值。 页面里我们把两个层次分开:

blueprint(阅读用)用 <-> 写法;
emit(真正 SAT 实例)只使用 AND/OR/NOT

局部门模板每个门有一个辅助变量,两个常量规模的发射约束。
AND 门模板

蓝图: g <-> (u AND v)

实际输出: (NOT g OR (u AND v)) AND (NOT (u AND v) OR g)

两个输入、一个辅助变量、常数规模约束。

输入输出
000
010
100
111
OR 门模板

蓝图: g <-> (u OR v)

实际输出: (NOT g OR (u OR v)) AND (NOT (u OR v) OR g)

结构同 AND,只是 RHS 运算符改为 OR。

输入输出
000
011
101
111
NOT 门模板

蓝图: g <-> NOT u

实际输出: (NOT g OR NOT u) AND (u OR g)

一元形式只用一个输入,编码风格一致。

输入输出
01
10
变量角色输入保持不变。每个非输入节点都得到一个辅助变量。
输入变量

输入变量 x1..x4 是问题变量(与 Circuit-SAT 输入同名)。

辅助变量

辅助变量 n1, g1, g2, g3, g4, z 对应电路的门输出。

形式化构造

对每个门 g

emit(g)=(¬grhs)(¬rhsg),\text{emit}(g) = (\neg g \lor \text{rhs}) \land (\neg \text{rhs} \lor g),

其中 rhs 是该门局部右侧表达式(AND/OR/NOT)。

归约公式的构造顺序依赖电路无环性:每个门只依赖输入节点或更早已定义的门。

归约后的公式是:

ΦC=zgGates(C)emit(g).\Phi_C = z \land \bigwedge_{g \in Gates(C)} \text{emit}(g).
形式化构造发出的约束才是实际 SAT 公式,仅包含 AND/OR/NOT。
可读蓝图

Φ_C = z ∧ (∧_{g in Gates(C)} emit(g)),每个 emit(g) 仅由 AND/OR/NOT 构成。

实际 emit

emit(n1) = ((NOT n1 OR NOT x2)) AND ((NOT (NOT x2) OR n1))

emit(g1) = ((NOT g1 OR (x1 AND n1))) AND ((NOT ((x1 AND n1)) OR g1))

emit(g2) = ((NOT g2 OR (x3 OR x4))) AND ((NOT ((x3 OR x4)) OR g2))

emit(g3) = ((NOT g3 OR (g1 AND g2))) AND ((NOT ((g1 AND g2)) OR g3))

emit(g4) = ((NOT g4 OR (x2 AND x4))) AND ((NOT ((x2 AND x4)) OR g4))

emit(z) = ((NOT z OR (g3 OR g4))) AND ((NOT ((g3 OR g4)) OR z))

再乘上 z

真正输出到 SAT 的是 Φ_C,它只含 AND/OR/NOT

赋值扩展与限制

归约后的赋值域比电路多了辅助变量;反向方向会先把 SAT 赋值限制回 x1..x4

赋值扩展与限制把 x1..x4 扩展到所有辅助变量;限制操作只保留输入。
1010

输入行: x1=1, x2=0, x3=1, x4=0

扩展后: x1=1, x2=0, x3=1, x4=0, n1=1, g1=1, g2=1, g3=1, g4=0, z=1

限制后: x1=1, x2=0, x3=1, x4=0

0101

输入行: x1=0, x2=1, x3=0, x4=1

扩展后: x1=0, x2=1, x3=0, x4=1, n1=0, g1=0, g2=1, g3=0, g4=1, z=1

限制后: x1=0, x2=1, x3=0, x4=1

正确性方向 1:Circuit-SAT ⇒ SAT

若某个电路赋值 aC(a)=1,我们把门输出一起扩展到 (x1..x4, n1,g1,g2,g3,g4,z)。 每条局部约束都被满足,并且 z=1,所以归约后公式 Φ_C 也满足。

正确性方向 2:SAT ⇒ Circuit-SAT

若某个 SAT 赋值 b 满足 Φ_C,每条约束都迫使辅助变量等于对应门的真实结果。 把它限制到 b|inputs| 后即可按拓扑顺序重算电路,得到 z=1,于是 C(b|inputs|)=1

这是为什么双向都要写清楚。

正确性支撑(正向与反向)

正确性方向等价性要求双向都成立。
正向:C(a)=1 => Φ_C(â)=1

1010: C(a)=1 -> Φ_C(â)=1

反向:Φ_C(b)=1 => C(b|inputs|)=1

b=1010: Φ_C(b)=1 => C(b|inputs|)=1

正向见证 C(a)=1 的赋值可扩展为满足 Φ_C 的赋值。
赋值C(a)去 z 的合取最终 Φ_C(â)
1010111
0101111
反向重建 从满足公式的赋值 b 出发,把它限制到 b|inputs|,再按拓扑顺序重算门值。
满足赋值 b = 1010

b|inputs| 中的输入: x1=1, x2=0, x3=1, x4=0

扩展后的辅助变量值: x1=1, x2=0, x3=1, x4=0, n1=1, g1=1, g2=1, g3=1, g4=0, z=1

限制后的 b|inputs|: x1=1, x2=0, x3=1, x4=0

满足赋值 b = 0101

b|inputs| 中的输入: x1=0, x2=1, x3=0, x4=1

扩展后的辅助变量值: x1=0, x2=1, x3=0, x4=1, n1=0, g1=0, g2=1, g3=0, g4=1, z=1

限制后的 b|inputs|: x1=0, x2=1, x3=0, x4=1

作弊赋值检查

若某些辅助变量与门式冲突,局部约束会拒绝该赋值。

以 0000 为底的作弊示例:

x1=0, x2=0, x3=0, x4=0, n1=1, g1=1, g2=0, g3=0, g4=0, z=0

NOT g1 OR (x1 AND n1) 为假,因为 x1=0,n1=1 但 g1=1。

专门的 AND z 对照

没有最后的 AND z 时,局部门约束可能都真,但输出端是 0,会被错误接受。

独立 AND z 对照局部门约束可能为真,z 可能为 0。AND z 用作接受过滤器。
赋值门约束合取zΦ_C说明
0000100只满足一致性的赋值会让所有门约束成立,但 AND z 会拒绝它。

主归约追踪(主演示)

这个追踪显示按拓扑顺序发射局部约束、累计前缀以及最终 AND z

主归约追踪

归约对某个固定赋值逐门处理,按拓扑顺序逐步发射约束。

截至当前的累计约束
当前步骤

发射 n1: n1 <-> (NOT x2) -> ((NOT n1 OR NOT x2)) AND ((NOT (NOT x2) OR n1))

该步约束真值 = 1

赋值先验必须合法,每一步只使用已存储的前置值。

赋值视图

输入 x1=1, x2=0, x3=1, x4=0

辅助变量 n1=1

累计 emitted 公式前缀

((NOT n1 OR NOT x2)) AND ((NOT (NOT x2) OR n1))

1 / 7
x11x20x31x40NOTn1=1ANDg1=?ORg2=?ANDg3=?ANDg4=?ORz=??
蓝图(局部)

n1 <-> (NOT x2)

已发射公式前缀

((NOT n1 OR NOT x2)) AND ((NOT (NOT x2) OR n1))

追踪序列
步骤工作发射值
1发射 n1((NOT n1 OR NOT x2)) AND ((NOT (NOT x2) OR n1))
2发射 g1((NOT g1 OR (x1 AND n1))) AND ((NOT ((x1 AND n1)) OR g1))
3发射 g2((NOT g2 OR (x3 OR x4))) AND ((NOT ((x3 OR x4)) OR g2))
4发射 g3((NOT g3 OR (g1 AND g2))) AND ((NOT ((g1 AND g2)) OR g3))
5发射 g4((NOT g4 OR (x2 AND x4))) AND ((NOT ((x2 AND x4)) OR g4))
6发射 z((NOT z OR (g3 OR g4))) AND ((NOT ((g3 OR g4)) OR z))
7断言 output 约束z

实现与不变量

实现上是:每个门输出一个常数规模约束,按拓扑顺序写下,再加最终输出约束。

构建表按拓扑顺序逐门输出约束。
步骤门 / 辅助变量蓝图局部约束
1n1n1 <-> (NOT x2)((NOT n1 OR NOT x2)) AND ((NOT (NOT x2) OR n1))
2g1g1 <-> (x1 AND n1)((NOT g1 OR (x1 AND n1))) AND ((NOT ((x1 AND n1)) OR g1))
3g2g2 <-> (x3 OR x4)((NOT g2 OR (x3 OR x4))) AND ((NOT ((x3 OR x4)) OR g2))
4g3g3 <-> (g1 AND g2)((NOT g3 OR (g1 AND g2))) AND ((NOT ((g1 AND g2)) OR g3))
5g4g4 <-> (x2 AND x4)((NOT g4 OR (x2 AND x4))) AND ((NOT ((x2 AND x4)) OR g4))
6zz <-> (g3 OR g4)((NOT z OR (g3 OR g4))) AND ((NOT ((g3 OR g4)) OR z))
一致性轨道每个辅助变量都由已处理过的更早节点值决定。
n1n1 由已处理过的更早节点值决定:x2。
g1g1 由已处理过的更早节点值决定:x1, n1。
g2g2 由已处理过的更早节点值决定:x3, x4。
g3g3 由已处理过的更早节点值决定:g1, g2。
g4g4 由已处理过的更早节点值决定:x2, x4。
zz 由已处理过的更早节点值决定:g3, g4。

这样就能做到机械化的、一致的构造。

复杂度

|C| 表示该固定电路编码规模。每个非输入节点贡献一个辅助变量和一条常数规模约束,再加最终 z

规模栈每个非输入节点贡献一个辅助变量和一个常数规模门模板;加上最终 z,故 |Φ_C| = O(|C|)。
类型数量
输入变量4
辅助变量6
门约束6
最终输出约束1

所以 |Φ_C| = O(|C|),是线性规模;这里依赖固定门扇入假设:AND/OR 为双输入,NOT 为单输入。 该线性规模结论依赖固定扇入的假设(AND/OR 是 2 输入,NOT 是 1 输入)。

常见混淆

常见混淆

始终把蓝图、顺序、辅助变量角色讲清。

写 `g <-> expr` 很简洁,直接当作输出公式可以吗?

修正: 不行。`<->` 只是本地可读写法,累积的 SAT 输出必须只用 AND/OR/NOT。

每个门一致即可,不需要额外约束输出。

约束顺序随意写即可,拓扑顺序只是实现细节。

不需要辅助变量,只出现 x1..x4 即可。

图谱连接

polynomial-time-reductions 提供模板,circuit-sat 提供源实例,sat 提供目标对象。

局部图上下文该归约把已知的源问题与目标问题连接成一条可执行的桥。
polynomial-time-reductions

答案保持翻译器

circuit-sat

源问题

sat

目标语言

circuit-sat-to-sat

本节点

练习

练习归约

按归约语义分类固定示例与格式错误处理。

电路赋值 1010 满足时,归约后的 SAT 实例在对应扩展上应如何?

选择答案以检验。

对 0000,门约束都为真,最终合取还要什么?

选择答案以检验。

反向方向先做限制到输入,应该保留什么?

选择答案以检验。

对 `101`,正确行为是什么?

选择答案以检验。

  1. 在共享赋值中,哪些行可作为归约保留答案的例子?
  2. 为什么 0000 会被门约束接受却被 AND z 拒绝?
  3. 为什么 <-> 只能当蓝图,不应直接作为最终 SAT 输出语言?
  4. 输入变量和辅助变量分别是哪一类?

图谱连接 : 从 Circuit-SAT 到 SAT 的归约