You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySat:在CNF上使用Equals对象后执行Clausify异常如何解决?

PySat中基数约束与原子等价的正确实现方式

你遇到的问题根源是错误使用了Equals类——它无法直接接收CNF对象作为参数。Equals的设计目标是等价两个布尔表达式(如单个原子、逻辑组合表达式),而非已有的CNF子句集合。当你传入cnf2(ITotalizer生成的CNF实例)时,PySat内部会自动生成一个临时变量(比如输出中的12)来指代这个“未解析的CNF”,导致原基数约束的子句被完全忽略,只生成了临时变量与y的等价子句。

正确解决方案

要实现基数约束与原子y=4的真值等价,需先获取基数约束对应的顶层指示器文字(该文字为真当且仅当约束满足),再构造该文字与y的等价子句,最后合并所有子句:

方法1:使用CardEnc封装类(推荐)

from pysat.card import CardEnc
from pysat.formula import CNF

# 生成"lits=[1,2,3]最多1个为真"的基数约束,同时获取顶层指示器文字top_lit
# top_lit为真 ↔ 基数约束满足
cnf_card, top_lit = CardEnc.atmost(lits=[1,2,3], bound=1, top_id=100).encode()
print("基数约束子句:")
print(cnf_card.clauses)

# 构造top_lit与原子4的等价子句:等价于(top_lit ↔ 4)
eq_clauses = [[-top_lit, 4], [-4, top_lit]]

# 合并基数约束和等价子句,得到最终CNF
cnf_final = CNF()
cnf_final.extend(cnf_card.clauses)
cnf_final.extend(eq_clauses)

print("\n最终等价约束子句:")
print(cnf_final.clauses)

方法2:直接使用ITotalizer类

如果需要直接使用ITotalizer,可以通过get_top()方法获取顶层指示器文字:

from pysat.card import ITotalizer
from pysat.formula import CNF

# 用ITotalizer构造最多1个为真的约束
totalizer = ITotalizer(lits=[1,2,3], ubound=1, top_id=100)
cnf_card = totalizer.cnf
top_lit = totalizer.get_top()  # 获取顶层指示器文字

# 构造等价子句并合并
eq_clauses = [[-top_lit, 4], [-4, top_lit]]
cnf_final = CNF()
cnf_final.extend(cnf_card.clauses)
cnf_final.extend(eq_clauses)

print(cnf_final.clauses)

输出说明

运行后,最终的CNF会包含基数约束的所有原始子句,再加上[-top_lit,4]和[-4,top_lit]两个子句,确保基数约束与原子4的真值完全等价。

内容的提问来源于stack exchange,提问作者samarendra chandan bindu Dash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:59:53