4564 字
23 分钟
实验2:命题逻辑与 SAT 求解
2026-10-25 23:00
无标签

任务 1:DIMACS 读写与结果解释#

  1. 规则编号逻辑公式DIMACS 子句
    1S∨LS \vee L1 2 0
    2S→DS \rightarrow D-1 3 0
    3L→FL \rightarrow F-2 4 0
    4D→PD \rightarrow P-3 5 0
    5F→PF \rightarrow P-4 5 0
    6P→(D∨F)P \rightarrow (D \vee F)-5 3 4 0
    7¬(D∧F)\lnot (D \land F)-3 -4 0
    8PP5 0
  2. base.cnf 文件内容如下:

    c S=1, L=2, D=3, F=4, P=5
    p cnf 5 8
    1 2 0
    -1 3 0
    -2 4 0
    -3 5 0
    -4 5 0
    -5 3 4 0
    -3 -4 0
    5 0

    MiniSAT 终端输出如下:

    Terminal window
    ❯ minisat base.cnf base_result.txt
    WARNING: for repeatability, setting FPU to use double precision
    ============================[ Problem Statistics ]=============================
    | |
    | Number of variables: 5 |
    | Number of clauses: 7 |
    | Parse time: 0.00 s |
    | Eliminated vars: 4 |
    | Vars set : 1 |
    | Eliminated clauses: 0.00 Mb |
    | Simplification time: 0.00 s |
    | |
    ============================[ Search Statistics ]==============================
    | Conflicts | ORIGINAL | LEARNT | Progress |
    | | Vars Clauses Literals | Limit Clauses Lit/Cl | |
    ===============================================================================
    ===============================================================================
    restarts : 1
    conflicts : 0 (-nan /sec)
    decisions : 1 (0.00 % random) (inf /sec)
    propagations : 1 (inf /sec)
    conflict literals : 0 (-nan % deleted)
    Memory used : 11.75 MB
    CPU time : 0 s
    SATISFIABLE

    结果文件如下:

    SAT
    1 -2 3 -4 5 0

    求解状态表示 SAT 可满足,其中一种可满足的模型为:S, D, P 为真;L, F 为假。

    模型中正变量编号代表该变量为真,负变量编号代表该变量为假。

    对应的软件配置为:启用服务器模式、数据库后端、持久化功能,不启用本地模式、文件储存后端。

    检查八条业务规则:

    1. 满足:服务器模式已启用
    2. 满足:服务器模式已启用且数据库后端已启用
    3. 满足:本地模式未启用
    4. 满足:数据库后端已启用且持久化功能已启用
    5. 满足:文件存储后端未启用
    6. 满足:持久化功能已启用且数据库后端已启用
    7. 满足:数据库后端已启用且文件存储后端未启用
    8. 满足:持久化功能已启用
  3. server_only.cnf 文件内容如下:

    c S=1, L=2, D=3, F=4, P=5
    p cnf 5 9
    1 2 0
    -1 3 0
    -2 4 0
    -3 5 0
    -4 5 0
    -5 3 4 0
    -3 -4 0
    5 0
    1 0

    MiniSAT 终端输出如下:

    Terminal window
    ❯ minisat server_only.cnf server_only_result.txt
    WARNING: for repeatability, setting FPU to use double precision
    ============================[ Problem Statistics ]=============================
    | |
    | Number of variables: 5 |
    | Number of clauses: 7 |
    | Parse time: 0.00 s |
    | Simplification time: 0.00 s |
    | |
    ============================[ Search Statistics ]==============================
    | Conflicts | ORIGINAL | LEARNT | Progress |
    | | Vars Clauses Literals | Limit Clauses Lit/Cl | |
    ===============================================================================
    ===============================================================================
    restarts : 1
    conflicts : 0 (-nan /sec)
    decisions : 1 (0.00 % random) (inf /sec)
    propagations : 5 (inf /sec)
    conflict literals : 0 (-nan % deleted)
    Memory used : 11.75 MB
    CPU time : 0 s
    SATISFIABLE

    结果文件如下:

    SAT
    1 -2 3 -4 5 0

    no_persistence.cnf 文件内容如下:

    c S=1, L=2, D=3, F=4, P=5
    p cnf 5 8
    1 2 0
    -1 3 0
    -2 4 0
    -3 5 0
    -4 5 0
    -5 3 4 0
    -3 -4 0
    -5 0

    MiniSAT 终端输出如下:

    Terminal window
    ❯ minisat no_persistence.cnf no_persistence_result.txt
    WARNING: for repeatability, setting FPU to use double precision
    ============================[ Problem Statistics ]=============================
    | |
    | Number of variables: 5 |
    | Number of clauses: 7 |
    | Parse time: 0.00 s |
    | Simplification time: 0.00 s |
    | |
    ===============================================================================
    Solved by simplification
    restarts : 0
    conflicts : 0 (0 /sec)
    decisions : 0 (-nan % random) (0 /sec)
    propagations : 4 (4635 /sec)
    conflict literals : 0 (-nan % deleted)
    Memory used : 11.75 MB
    CPU time : 0.000863 s
    UNSATISFIABLE

    结果文件如下:

    UNSAT
    版本求解状态模型
    base.cnfSAT1 -2 3 -4 5 0
    server_only.cnfSAT1 -2 3 -4 5 0
    no_persistence.cnfUNSAT/
  4. ¬P,D→P⊢¬D¬P,F→P⊢¬F¬D,S→D⊢¬S¬F,L→F⊢¬L¬S,¬L,S∨L⊢False \lnot P, D \rightarrow P \vdash \lnot D \\ \lnot P, F \rightarrow P \vdash \lnot F \\ \lnot D, S \rightarrow D \vdash \lnot S \\ \lnot F, L \rightarrow F \vdash \lnot L \\ \lnot S, \lnot L, S \vee L \vdash False \\

    实际使用的规则包括修改后的规则 8 (¬P\lnot P), 规则 4 (D→PD \rightarrow P), 规则 5 (F→PF \rightarrow P), 规则 2 (S→DS \rightarrow D), 规则 3 (L→FL \rightarrow F), 规则 1 (S∨LS \vee L)

  5. 在解决实际软件工程问题中,我们将具体问题建模为对应的 SAT 问题求解,故求解结果需要结合变量语义和约束关系解释,还原为原有的实际问题并加以分析。

任务 2:诚实者与说谎者建模#

  1. 变量表:

    变量编号为真时的含义
    A1Alice 是诚实者
    B2Bob 是诚实者
    C3Carol 是诚实者
    D4David 是诚实者
    E5Eve 是诚实者
    陈述人陈述内容逻辑公式
    AliceBob 与 David 身份不同A↔(B⊕D)A \leftrightarrow (B \oplus D)
    BobAlice 或 David 中至少一人诚实B↔(A∨D)B \leftrightarrow (A \vee D)
    CarolAlice 是说谎者C↔¬AC \leftrightarrow \lnot A
    DavidAlice 或 Bob 中至少一人诚实D↔(A∨B)D \leftrightarrow (A \vee B)
    EveCarol 是诚实者E↔CE \leftrightarrow C
    /至少两名诚实者(A∨B∨C∨D)∧(A∨B∨C∨E)∧(A∨B∨D∨E)∧(A∨C∨D∨E)∧(B∨C∨D∨E)(A \vee B \vee C \vee D) \land \\ (A \vee B \vee C \vee E) \land \\ (A \vee B \vee D \vee E) \land \\ (A \vee C \vee D \vee E) \land \\ (B \vee C \vee D \vee E)
    /至少两名说谎者(¬A∨¬B∨¬C∨¬D)∧(¬A∨¬B∨¬C∨¬E)∧(¬A∨¬B∨¬D∨¬E)∧(¬A∨¬C∨¬D∨¬E)∧(¬B∨¬C∨¬D∨¬E)(\lnot A \vee \lnot B \vee \lnot C \vee \lnot D) \land \\ (\lnot A \vee \lnot B \vee \lnot C \vee \lnot E) \land \\ (\lnot A \vee \lnot B \vee \lnot D \vee \lnot E) \land \\ (\lnot A \vee \lnot C \vee \lnot D \vee \lnot E) \land \\ (\lnot B \vee \lnot C \vee \lnot D \vee \lnot E)

    对应的 CNF 为:

    c A=1, B=2, C=3, D=4, E=5
    p cnf 5 24
    c Alice
    -1 2 4 0
    -1 -2 -4 0
    1 -2 4 0
    33 collapsed lines
    1 2 -4 0
    c Bob
    -2 1 4 0
    2 -1 0
    2 -4 0
    c Carol
    -3 -1 0
    1 3 0
    c David
    -4 1 2 0
    4 -1 0
    4 -2 0
    c Eve
    -5 3 0
    -3 5 0
    c 2True
    1 2 3 4 0
    1 2 3 5 0
    1 2 4 5 0
    1 3 4 5 0
    2 3 4 5 0
    c 2False
    -1 -2 -3 -4 0
    -1 -2 -3 -5 0
    -1 -2 -4 -5 0
    -1 -3 -4 -5 0
    -2 -3 -4 -5 0

    输出为

    Terminal window
    ❯ minisat task2.cnf task2_result.txt
    WARNING: for repeatability, setting FPU to use double precision
    ============================[ Problem Statistics ]=============================
    | |
    | Number of variables: 5 |
    | Number of clauses: 24 |
    | Parse time: 0.00 s |
    | Simplification time: 0.00 s |
    | |
    ============================[ Search Statistics ]==============================
    | Conflicts | ORIGINAL | LEARNT | Progress |
    | | Vars Clauses Literals | Limit Clauses Lit/Cl | |
    ===============================================================================
    ===============================================================================
    restarts : 1
    conflicts : 0 (0 /sec)
    decisions : 1 (0.00 % random) (788 /sec)
    propagations : 5 (3940 /sec)
    conflict literals : 0 (-nan % deleted)
    Memory used : 11.75 MB
    CPU time : 0.001269 s
    SATISFIABLE

    运行结果为

    SAT
    -1 -2 3 -4 5 0

    说明“Carol 与 Eve 是诚实者”为满足要求的一组解。

  2. 添加阻塞语句 1 2 -3 4 -5 0 ,再次运行,输出为

    Terminal window
    ❯ minisat task2.cnf task2_result.txt
    WARNING: for repeatability, setting FPU to use double precision
    ============================[ Problem Statistics ]=============================
    | |
    | Number of variables: 5 |
    | Number of clauses: 25 |
    | Parse time: 0.00 s |
    | Simplification time: 0.00 s |
    | |
    ===============================================================================
    Solved by simplification
    restarts : 0
    conflicts : 0 (0 /sec)
    decisions : 0 (-nan % random) (0 /sec)
    propagations : 4 (4813 /sec)
    conflict literals : 0 (-nan % deleted)
    Memory used : 11.75 MB
    CPU time : 0.000831 s
    UNSATISFIABLE

    结果为 UNSAT ,说明解唯一,该问题仅存在一组解。

任务 3:自选场景的 SAT 建模#

以下为 LLM 生成的候选模型与候选方案,尚未由本人独立核验,也未运行 MiniSAT。

1. 本次 LLM 使用记录#

本次实际提供给 LLM 的请求原文为:

完成任务3中需要LLM参与的部分,不要进行需要我完成的部分

同时提供了现有报告 2.md 和任务书 实验2_命题逻辑与SAT求解_实验任务.pdf 作为上下文。任务书中任务 3 的生成要求为:从软件配置、测试用例选择、课程冲突或资源分配中选择一个场景;不少于 10 个有业务含义的布尔变量和 15 个 CNF 子句;至少包含依赖、互斥、至少一个、至多一个和条件组合中的三类关系;需求至少允许一个合法方案;生成场景说明、变量含义、编号需求、对应 CNF 和一份候选方案。

以上记录区分了实际提问和附件中的要求,没有将另拟的提示词记为已实际发送的提示词。

2. LLM 生成的场景说明#

选择场景:团队协作平台的软件部署配置。

某团队协作平台支持云端托管和本地部署两种模式,数据库可以选择 PostgreSQL 或 SQLite,并可选配账号认证、单点登录、HTTPS、自动备份、附件上传、病毒扫描、Redis 缓存和后台任务。本模型只考虑这些功能是否启用;数据库选型、功能依赖和安全策略均按下述产品规则约束。

产品约定:内置自动备份仅支持 PostgreSQL,并通过后台任务执行;附件上传必须启用异步病毒扫描,病毒扫描也通过后台任务执行;后台任务使用 Redis 作为队列与缓存服务,而本产品的 Redis 组件不支持与 SQLite 搭配。云端部署上传附件时,还必须启用自动备份。

3. 候选变量表#

变量编号为真时的业务含义
CC1采用云端托管模式
LL2采用本地部署模式
PP3使用 PostgreSQL 数据库
QQ4使用 SQLite 数据库
AA5启用账号认证
SS6启用单点登录(SSO)
TT7启用 HTTPS
BB8启用内置自动备份
UU9启用附件上传
VV10启用附件病毒扫描
RR11启用 Redis 队列与缓存服务
JJ12启用后台任务

变量为假表示对应模式、数据库或功能未启用。全部 12 个变量均直接具有业务含义,不引入辅助变量。

4. 编号需求与候选 CNF 子句#

用 C1,…,C16C_1,\ldots,C_{16} 标记子句;表中的整数按上述变量编号表示文字,末尾的 0 表示子句结束。

需求编号自然语言需求命题逻辑公式对应 CNF 子句整数编码
R1云端托管与本地部署必须恰好选择一种。(C∨L)∧(¬C∨¬L)(C\vee L)\land(\lnot C\vee\lnot L)C1=C∨LC_1=C\vee L;C2=¬C∨¬LC_2=\lnot C\vee\lnot L1 2 0;-1 -2 0
R2PostgreSQL 与 SQLite 必须恰好选择一种。(P∨Q)∧(¬P∨¬Q)(P\vee Q)\land(\lnot P\vee\lnot Q)C3=P∨QC_3=P\vee Q;C4=¬P∨¬QC_4=\lnot P\vee\lnot Q3 4 0;-3 -4 0
R3云端托管必须使用 PostgreSQL。C→PC\rightarrow PC5=¬C∨PC_5=\lnot C\vee P-1 3 0
R4云端托管必须启用 HTTPS。C→TC\rightarrow TC6=¬C∨TC_6=\lnot C\vee T-1 7 0
R5云端托管必须启用账号认证。C→AC\rightarrow AC7=¬C∨AC_7=\lnot C\vee A-1 5 0
R6单点登录依赖账号认证。S→AS\rightarrow AC8=¬S∨AC_8=\lnot S\vee A-6 5 0
R7单点登录必须通过 HTTPS 使用。S→TS\rightarrow TC9=¬S∨TC_9=\lnot S\vee T-6 7 0
R8内置自动备份要求使用 PostgreSQL。B→PB\rightarrow PC10=¬B∨PC_{10}=\lnot B\vee P-8 3 0
R9内置自动备份要求启用后台任务。B→JB\rightarrow JC11=¬B∨JC_{11}=\lnot B\vee J-8 12 0
R10后台任务要求启用 Redis 队列与缓存服务。J→RJ\rightarrow RC12=¬J∨RC_{12}=\lnot J\vee R-12 11 0
R11Redis 队列与缓存服务和 SQLite 不能同时启用。¬(R∧Q)\lnot(R\land Q)C13=¬R∨¬QC_{13}=\lnot R\vee\lnot Q-11 -4 0
R12附件上传要求启用病毒扫描。U→VU\rightarrow VC14=¬U∨VC_{14}=\lnot U\vee V-9 10 0
R13病毒扫描要求启用后台任务。V→JV\rightarrow JC15=¬V∨JC_{15}=\lnot V\vee J-10 12 0
R14同时采用云端托管并启用附件上传时,必须启用内置自动备份。(C∧U)→B(C\land U)\rightarrow BC16=¬C∨¬U∨BC_{16}=\lnot C\vee\lnot U\vee B-1 -9 8 0

候选 CNF 为 F=⋀i=116CiF=\bigwedge_{i=1}^{16}C_i,共 12 个业务变量、14 条自然语言需求、16 个子句。关系类型包括:R1、R2 中的至少一个与至多一个;R11 中的互斥;R3—R10、R12、R13 中的依赖;R14 中的条件组合。

5. LLM 给出的候选方案#

候选业务方案:采用云端托管和 PostgreSQL,启用账号认证、HTTPS、内置自动备份、附件上传、病毒扫描、Redis 队列与缓存服务及后台任务;不采用本地部署或 SQLite,不启用单点登录。

变量CCLLPPQQAASSTTBBUUVVRRJJ
候选赋值101010111111

按变量编号表示的完整候选赋值为:

1 -2 3 -4 5 -6 7 8 9 10 11 12 0

这份赋值由 LLM 提供,不是 MiniSAT 的运行输出。

本人仍需完成:整理和独立检查候选模型、必要的修正、候选方案对每条需求与 CNF 的代入检查、最终 DIMACS 文件、MiniSAT 求解及模型的业务解释与需求检查、关键截图,以及自行撰写的编码准确性结论。


LLM 生成内容核对无误,以下为人工部分:

DIMACS 文件:

c C=1, L=2, P=3, Q=4, A=5, S=6, T=7, B=8, U=9, V=10, R=11, J=12
p cnf 12 16
1 2 0
-1 -2 0
3 4 0
-3 -4 0
-1 3 0
-1 7 0
-1 5 0
-6 5 0
-6 7 0
-8 3 0
-8 12 0
-12 11 0
-11 -4 0
-9 10 0
-10 12 0
-1 -9 8 0

输出:

Terminal window
❯ minisat task3.cnf task3_result.txt
WARNING: for repeatability, setting FPU to use double precision
============================[ Problem Statistics ]=============================
| |
| Number of variables: 12 |
| Number of clauses: 16 |
| Parse time: 0.00 s |
| Eliminated vars: 12 |
| Vars set : 0 |
| Eliminated clauses: 0.00 Mb |
| Simplification time: 0.00 s |
| |
============================[ Search Statistics ]==============================
| Conflicts | ORIGINAL | LEARNT | Progress |
| | Vars Clauses Literals | Limit Clauses Lit/Cl | |
===============================================================================
===============================================================================
restarts : 1
conflicts : 0 (-nan /sec)
decisions : 1 (0.00 % random) (inf /sec)
propagations : 0 (-nan /sec)
conflict literals : 0 (-nan % deleted)
Memory used : 11.73 MB
CPU time : 0 s
SATISFIABLE

运行结果为:

SAT
-1 2 -3 4 5 -6 7 -8 -9 -10 -11 -12 0

其含义为:采用本地部署模式,使用SQLite数据库,启用账号认证,启用 HTTPS。

CNF 准确表达了需求

任务 4(编程题):实现 CNF 赋值检查器#

代码补全如下:

#include <vector>
bool satisfiesCnf(
int variableCount,
const std::vector<std::vector<int>>& clauses,
const std::vector<int>& assignment) {
for(const std::vector<int>& clause : clauses) {
bool sat = false;
for(int i : clause) {
bool sign = (i < 0);
int index = (sign ? -i : i) - 1;
sat |= (assignment[index] ^ sign);
if(sat) break;
}
if(!sat) return false;
}
return true;
}

测试代码如下:

#include <iostream>
#include <vector>
bool satisfiesCnf(
int variableCount,
const std::vector<std::vector<int>>& clauses,
const std::vector<int>& assignment);
int main() {
int variableCount, clauseCount;
std::cin >> variableCount >> clauseCount;
std::vector<std::vector<int>> clauses(clauseCount);
std::vector<int> assignment(variableCount);
for(int i = 0; i < clauseCount; i++) {
int var;
while(true) {
std :: cin >> var;
if(var == 0) break;
clauses[i].push_back(var);
}
}
for(int i = 0; i < variableCount; i++) {
std::cin >> assignment[i];
}
std::cout << (
satisfiesCnf(variableCount, clauses, assignment) ? "AC" : "WA"
) << std::endl;
return 0;
}

测试用例如下:

测试点编号variableCountclausesassignment预期解返回结果
11{}x1=trueACAC
21{{1}}x1=trueACAC
31{{1}, {-1}}x1=trueWAWA
42{{1, 2}, {-1, -2}}x1=true, x2=trueWAWA
52{{1, 2}, {-1, -2}}x1=true, x2=falseACAC
63{{-1, 2}, {-2, 3}, {-3, 1}}x1=true, x2=true, x3=trueACAC

使用固定CNF {{1, 2}, {-1, 3}, {-2, -3}} 和 赋值 x1=true, x2=false, x3=true 测试结果如下:

Terminal window
❯ ./test_lab2
3 3
1 2 0
-1 3 0
-2 -3 0
1 0 1
AC

故返回值为 true, 将 x3 改为 false 后测试结果如下:

Terminal window
❯ ./test_lab2
3 3
1 2 0
-1 3 0
-2 -3 0
1 0 0
WA

此时cnf子句 -1 3 0 不满足。

CNF中“所有子句均满足”的含义是“对给定的同一组完整赋值,每个子句都至少有一个文字为真时,整个 CNF 才为真;只要有一个子句中的文字全部为假,整个 CNF 就为假。”

任务 5:使用阻塞子句寻找多个解#

方案编号CNF运行结果测试策略加入的阻塞语句satisfiesCnf 检测结果
11 -2 -3 -4 0执行单元测试-1 2 3 4 0AC
2-1 2 -3 -4 0执行集成测试1 -2 3 4 0AC
31 2 -3 -4 0执行单元测试和集成测试-1 -2 3 4 0AC
41 2 3 -4 0执行单元测试,集成测试和静态分析-1 -2 -3 4 0AC
51 -2 3 -4 0执行单元测试和静态分析-1 2 -3 4 0AC
6-1 2 -3 4 0执行集成测试,并收集覆盖率1 -2 3 -4 0AC
71 2 -3 4 0执行单元测试和集成测试,并收集覆盖率-1 -2 3 -4 0AC
/UNSAT无测试策略//

若存在其他完整合法赋值,则该组赋值可通过原始CNF,并不会被任何一条阻塞语句排除,最后输出UNSAT则说明不存在这样的赋值组合。

增加业务规则“必须执行静态分析”后,初始cnf如下:

c U=1, I=2, S=3, C=4
p cnf 4 5
1 2 0
-3 1 0
-4 2 0
-3 -4 0
3 0
原方案编号CNF运行结果测试策略加入的阻塞语句satisfiesCnf 检测结果
51 -2 3 -4 0执行单元测试和静态分析-1 2 -3 4 0AC
41 2 3 -4 0执行单元测试,集成测试和静态分析-1 -2 -3 4 0AC
/UNSAT无测试策略//

方案数由修改前的7降为2,原方案1, 2, 3, 6, 7被排除,即所有包含-3的方案被排除。

单个阻塞语句由被阻塞赋值逐项取反得到,这使得其具有针对性:排除这一种赋值组合并不影响其他赋值组合的判断。

任务 6:检查两份 CNF 是否等价#

需求编号逻辑公式
1A∨WA \vee W
2A↔DA \leftrightarrow D
3W→CW \rightarrow C
4C→DC \rightarrow D
5D→LD \rightarrow L
6M↔LM \leftrightarrow L

运行 encoding_a.cnf 输出如下:

Terminal window
❯ minisat encoding_a.cnf encoding_a.txt
WARNING: for repeatability, setting FPU to use double precision
============================[ Problem Statistics ]=============================
| |
| Number of variables: 6 |
| Number of clauses: 8 |
| Parse time: 0.00 s |
| Eliminated vars: 4 |
| Vars set : 2 |
| Eliminated clauses: 0.00 Mb |
| Simplification time: 0.00 s |
| |
============================[ Search Statistics ]==============================
| Conflicts | ORIGINAL | LEARNT | Progress |
| | Vars Clauses Literals | Limit Clauses Lit/Cl | |
===============================================================================
===============================================================================
restarts : 1
conflicts : 0 (0 /sec)
decisions : 1 (0.00 % random) (740 /sec)
propagations : 2 (1480 /sec)
conflict literals : 0 (-nan % deleted)
Memory used : 11.73 MB
CPU time : 0.001351 s
SATISFIABLE

结果如下:

SAT
1 -2 3 -4 5 6 0

运行 encoding_b.cnf 输出如下:

Terminal window
❯ minisat encoding_b.cnf encoding_b.txt
WARNING: for repeatability, setting FPU to use double precision
============================[ Problem Statistics ]=============================
| |
| Number of variables: 6 |
| Number of clauses: 12 |
| Parse time: 0.00 s |
| Eliminated vars: 4 |
| Vars set : 2 |
| Eliminated clauses: 0.00 Mb |
| Simplification time: 0.00 s |
| |
============================[ Search Statistics ]==============================
| Conflicts | ORIGINAL | LEARNT | Progress |
| | Vars Clauses Literals | Limit Clauses Lit/Cl | |
===============================================================================
===============================================================================
restarts : 1
conflicts : 0 (0 /sec)
decisions : 1 (0.00 % random) (912 /sec)
propagations : 2 (1825 /sec)
conflict literals : 0 (-nan % deleted)
Memory used : 11.73 MB
CPU time : 0.001096 s
SATISFIABLE

结果如下:

SAT
1 -2 3 -4 5 6 0

检查函数如下:

std::vector<int> check() {
int variableCount = 6;
std::vector<std::vector<int>> encoding_a = {
8 collapsed lines
{1, 2},
{-1, 3},
{-3, 1},
{-2, 4},
{-4, 3},
{-3, 5},
{-6, 5},
{-5, 6}
};
std::vector<std::vector<int>> encoding_b = {
12 collapsed lines
{-4, 3},
{-3, 5},
{-6, 5},
{-5, 6},
{1, 2, 4},
{1, 2, -4},
{-1, 3, 6},
{-1, 3, -6},
{-3, 1, 2},
{-3, 1, -2},
{-2, 4, 5},
{-2, 4, -5},
};
std::vector<int> assignment(variableCount), diff;
for(int i = 0; i < 64; i ++) {
for(int j = 0; j < variableCount; j++) {
assignment[j] = (i >> j) & 1;
}
if(
satisfiesCnf(variableCount, encoding_a, assignment) !=
satisfiesCnf(variableCount, encoding_b, assignment)
) diff.push_back(i);
}
return diff;
}

运行后返回的 diff 为空,故 encoding_a 与 encoding_b 等价

(K OR x) AND (K OR NOT x)
≡ K OR (x AND NOT x) (分配律)
≡ K OR FALSE (矛盾律)
≡ K (恒等律)

删除 B 中 1 2 4 0 子句,并删除检查函数中变量 encoding_b 中元素 {1, 2, 4} ,再次运行检查函数,返回 diff 为 {0, 48},得到如下结果:

diff 内的元素赋值组合服务配置encoding_a 中不满足的子句不满足的需求编号
0A=false, W=false, D=false, C=false, L=false, M=false不启用任何业务1 2 01
48A=false, W=false, D=false, C=false, L=true, M=true启用日志与监控1 2 01

语法形式不同的cnf可能在命题逻辑等价性上属于同一等价类,故仍可能表达相同模型集合。

实验2:命题逻辑与 SAT 求解
https://blog.chiyo.uk/posts/2026/10/2523/
作者
千代有希=>
发布于
2026-10-25 23:00
许可协议
CC BY-NC-SA 4.0
千代有希的签名
Comment seems to stuck. Try to refresh?✨