
z3 本身不直接支持三值逻辑语义,但可通过双重可满足性检查(分别验证命题及其否定是否可满足)准确推断出 true、false 或 unknown 结论。
在形式化推理中,“Unknown” 并非 Z3 求解器的原生返回状态(unknown 表示求解器因超时、理论不支持或内部限制而无法判定),而是用户语义层面的逻辑不确定性:即目标命题既不能被前提必然推出(True),也不能被前提必然否定(False)——换言之,命题与前提相容,其否定也与前提相容。
因此,正确判断 rough(erin) 在给定知识库下属于 True / False / Unknown,需执行以下两步独立检查:
- 检查 rough(erin) 是否与前提一致 → 若 sat,说明“Erin 是 rough”可能成立;
- 检查 ¬rough(erin) 是否与前提一致 → 若 sat,说明“Erin 不是 rough”也可能成立。
仅当两者同时可满足时,结论为 Unknown;若仅前者可满足,则为 True;若仅后者可满足,则为 False;若两者均不可满足,则前提自相矛盾(应提前报错)。
关键在于使用 Z3 的增量求解接口(push() / pop())隔离每次假设,避免污染原始约束集。以下是推荐实现方式:
from z3 import *
# 定义枚举类型与函数符号(同原问题)
ThingsSort, (charlie, erin, fiona, harry) = EnumSort('ThingsSort', ['charlie', 'erin', 'fiona', 'harry'])
green = Function('green', ThingsSort, BoolSort())
kind = Function('kind', ThingsSort, BoolSort())
blue = Function('blue', ThingsSort, BoolSort())
smart = Function('smart', ThingsSort, BoolSort())
rough = Function('rough', ThingsSort, BoolSort())
quiet = Function('quiet', ThingsSort, BoolSort())
nice = Function('nice', ThingsSort, BoolSort())
x = Const('x', ThingsSort)
# 构建知识库(前提)
s = Solver()
s.add(green(charlie))
s.add(kind(charlie))
s.add(nice(charlie))
s.add(rough(charlie))
s.add(kind(erin))
s.add(nice(erin))
s.add(quiet(erin))
s.add(quiet(fiona))
s.add(rough(fiona))
s.add(smart(harry))
s.add(ForAll([x], Implies(And(rough(x), green(x)), quiet(x))))
s.add(ForAll([x], Implies(And(green(x), rough(x)), nice(x))))
s.add(ForAll([x], Implies(And(kind(x), smart(x)), green(x))))
s.add(ForAll([x], Implies(And(green(erin), blue(erin)), quiet(erin))))
s.add(ForAll([x], Implies(quiet(x), smart(x))))
s.add(ForAll([x], Implies(kind(x), green(x))))
s.add(ForAll([x], Implies(smart(x), kind(x))))
s.add(ForAll([x], Implies(And(rough(x), nice(x)), blue(x))))
# 辅助函数:安全检查某命题是否与当前知识库一致
def is_consistent(solver, formula):
solver.push()
solver.add(formula)
result = solver.check()
solver.pop()
if result == sat:
return True
elif result == unsat:
return False
else:
raise RuntimeError(f"Solver returned 'unknown'; cannot determine consistency of {formula}")
# 执行双重检查
can_be_rough = is_consistent(s, rough(erin))
can_be_not_rough = is_consistent(s, Not(rough(erin)))
# 综合判断
if can_be_rough and can_be_not_rough:
print("Unknown") # 命题与前提、其否定均相容 → 逻辑上不可判定
elif can_be_rough:
print("True") # 命题可满足,其否定不可满足 → 必然为真
elif can_be_not_rough:
print("False") # 命题不可满足,其否定可满足 → 必然为假
else:
print("Error: Knowledge base is inconsistent!") # 前提自相矛盾✅ 注意事项:
- 勿复用 check() 多次而不 push/pop:Z3 的 Solver 是累积式状态,直接连续调用 add() + check() 会将前一次断言永久保留在求解器中,导致误判;
- unknown 返回值需显式处理:若 Z3 因复杂性返回 unknown(如含未量化非线性算术),程序应抛出异常或降级处理,不可默认归为 Unknown 语义;
- 性能提示:对大规模知识库,可考虑使用 Solver(use_models=True) 并启用模型生成,便于调试为何某命题可满足;
- 逻辑完备性:该方法依赖 Z3 的可靠性与完备性(在支持片段内)。若知识库含高阶量词或不可判定结构,结果可能受限于求解器能力。
综上,Z3 虽非专为三值推理设计,但凭借其强大的 SMT 求解能力与增量接口,完全可作为高效、可靠的逻辑蕴涵判定工具,精准支撑 True/False/Unknown 三元决策,尤其适合嵌入规则引擎、知识验证系统或教学推理平台。










