SAT和SMT介绍及求解器使用

news2024/11/16 7:47:12

一、SAT

1、介绍

(1)定义

SAT即命题逻辑公式的可满足性问题/布尔可满足性问题。即给定一个与或非和变量组成的命题公式,判断是否存在一些结果使得这个公式成立

它是第一个被确认为NP完全的问题。

  • 输入:析取范式(CNF)
  • 输出:布尔值,代表是否可满足(SAT/UNSAT)

以演讲是否需要打领带的例子,说明它有几个组成部分:

  • 布尔变量/文字(literal):tie(领带),shirt(衬衫)
  • 符号:~(非)、∧(与)、 ∨(或)
  • 子句(clause)-析取式
    • 演讲不能只打领带,不穿衬衫: (tie∧shirt) → ~ tie ∨ shirt
    • 演讲不能既不打领带,也不穿衬衫: ( tie∧~shirt) → tie ∨ shirt
    • 自己不喜欢既打领带,又穿衬衫: ~(tie∧shirt) → ~ tie ∨ ~ shirt
  • 约束/公式-合取式: (~ tie ∨ shirt) ∧ (tie ∨ shirt) ∧ (~ tie ∨ ~ shirt)

由文字和符号组成子句。经过变换,子句构成完整约束。则SAT求解器的输入是3个子句。

(2)求解思路

SAT的求解过程可以划分成两个阶段:第一阶段是布尔约束传播/子句传播,第二阶段是冲突分析,可以采用递归回溯(DPLL算法)或冲突子句学习(CDCL算法)。

求解过程及两个算法的差异可以在网站 https://cse442-17f.github.io/Conflict-Driven-Clause-Learning/ 上看到可视化效果。

a)布尔约束传播

子句传播就类似在做数独游戏时,在某个空格填入某一个数字之后,就会排除掉一些其它空格内数字的选项,从而减少尝试赋值的次数。如果这个过程推出一个值为假的子句,我们称为『发生冲突』。如果发生冲突,就像是走迷宫,要退回上一个岔路口,选择一条不同的路再继续走。它的运行思路如下:

  • 对一个文字赋值后,以此为条件进一步给其他文字赋值(BCP)
    • 未发生冲突,尝试为下一个赋值。
    • 直到所有变量均赋值且没有冲突 → SAT
  • 发生冲突,回溯

但这个过程也有可能在退到上一个路口后又来到同一个死胡同,我们希望找到可以避开死胡同的岔路。这就来到冲突分析环节。

b)冲突分析
  • 递归回溯(DPLL算法)

    冲突回溯也会产生两个结果:回溯到了首次赋值,这意味着这个问题横竖都是无法满足的,那么就可以宣告“UNSAT”;反之,则回溯到之前的某次赋值,撤销这次赋值之后的所有赋值,类似一个undo操作。这个就是比较经典的DPLL算法,但这样存在一些问题。一方面是,它遇到冲突的时候,只知道当前的部分赋值会导致冲突,除此之外学不到任何东西。另一方面,它每次只会回溯一层,因此可能会把大量时间浪费在一片必定会失败的搜索空间中。DPLL的运行思路如下:

    • 回溯到首次赋值 → UNSAT

    • 回溯到之前某次赋值

      • 撤销这次之后的所有赋值
      • 换一条没走过的路
  • 冲突子句学习(CDCL算法)

    CDCL的不同之处在于,我们是如何从这一步走入之前的冲突的信息,现在作为一个新的子句被加入到子句列表中,为要使这个新子句满足,我们一定不会再进入到之前的冲突了。它比DPLL多了一步操作,运行思路如下:

    • 回溯到首次赋值 → UNSAT
    • 回溯到之前某次赋值
      • 撤销这次之后的所有赋值
      • 这次冲突作为新的子句加入到条件中
      • 换一条没走过没冲突的路

在这里插入图片描述

2、Minisat求解器

官网:http://minisat.se/

Github:https://github.com/niklasso/minisat

Minisat的基本使用方法:https://blog.csdn.net/nbu_dahe/article/details/115518719

(1)安装

sudo apt install minisat
  • 使用说明:minisat --help
    • 使用格式:minisat [options] <input-file> <result-output-file>
      请添加图片描述
      请添加图片描述

(2)使用

  • 创建CNF.txt文件如下,c代表注释行
【CNF.txt】
c An example DIMACS CNF
p cnf 2 3 
-1 2 0 
1 2 0
-1 -2 0
  • 示例一

minisat调用刚才创建的CNF.txt,结果输出到answer.txt

.txt的后缀名也可以改成.cnf

minisat CNF.txt answer.txt

运行完成后会在当前目录得到一个answer.txt

【answer.txt】
SAT
-1 2 0

请添加图片描述

  • 示例二
【CNF.txt】
p cnf 2 4
-1 2 0 
1 2 0
-1 -2 0
1 -2 0
【answer.txt】
UNSAT

请添加图片描述

3、EasySAT求解器

Github: https://github.com/shaowei-cai-group/EasySAT

安装:在目录下make

4、其他求解器

CaDiCaL求解器:github

其他:GRASP、Chaff、SATO、BerkMin

二、SMT

1、介绍

这个SMT是在SAT的基础上实现的,目的是求出指定约束下的可行解。如果说SAT把注意力放在命题公式判定上,SMT就在SAT的基础上可以分析各种不等式和等式下的约束求解

SMT惰性算法流程如下:

  • 1、对SMT公式进行预处理,把公式中的命题变量替换为布尔变量,再将SMT公式转化为可满足性意义上等价的SAT公式;
  • 2、检查此SAT公式是否可满足,如果不可满足,那么SMT公式也不可满足,算法结束;
  • 3、如果SAT公式可满足,则结合SMT背景理论去判断SMT公式的可满足性,返回判断结果,算法结束。
  • 惰性算法是SAT求解器与对应的背景理论相结合的产物

2、z3-solver求解器

z3-solver是由Microsoft Research(微软)开发的SMT求解器,它用于检查逻辑表达式的可满足性,可以找到一组约束中的其中一个可行解,缺点是无法找出所有的可行解(对于规划求解问题可以是scipy) 。

z3-solver可应用于软/硬件的验证与测试、约束求解、混合系统的分析、安全、生物,以及几何求解等问题。

Z3主要由**C++**开发,提供了.NET、 C、 C++、 Java、 Python 等语言调用接口,下面以python接口展开讲解。

github:https://github.com/Z3Prover/z3

document:https://github.com/Z3Prover/z3/wiki/Documentation

  • API:C、C++、.NET、Java、Python、ML/OCaml
  • Z3 Guide
    • z3介绍
    • Python样例:Z3 API in Python(链接1);Z3 API in Python(链接2)
    • 网页端在线运行-Freeform Editing:应用SMTLIB语言
      • SMT-LIB语言介绍:https://zhuanlan.zhihu.com/p/624758007
  • Slide
  • Publications

(1)安装

pip install z3-solver importlib_resources
  • 变量
    • 整型(Int),实型(Real)、向量(BitVec)和布尔(Bool)
      • Int(name):创建一个整数变量,有名字
      • Ints(names):创建多个整数变量,有名字
      • IntVal (val):创建一个整数常量,有初始值
  • 关键函数
    • x, y = Ints(‘x y’) —设置变量
    • s=solver() —创建解对象
      • s.add(条件):为解增加一个约束
      • s.check():检查解是否存在,存在则返回“SAT”
      • s.model():返回解,即变量x和y的具体数值
      • s.assertions():查看已经添加的约束And(a,b)、Or(a,b)、Not(a)、 Implies(a,b)

(2)使用-解数独问题

请添加图片描述
请添加图片描述

from z3 import *

def solveShuDu(constraint, board: list):
    board_c = [If(board[i][j] == 0,
                  True,
                  X[i][j] == board[i][j])
               for i in range(9) for j in range(9)]

    s = Solver()
    s.add(constraint + board_c)
    if s.check() == sat:
        m = s.model()
        r = [[m[X[i][j]].as_long() for j in range(9)]
             for i in range(9)]
        return r

# 1、变量:9x9 整数变量矩阵
X = [[Int(f"x_{i}_{j}") for j in range(9)] for i in range(9)]

# 2、条件
# 每个单元格只能取1-9
cells_c = [And(1 <= X[i][j], X[i][j] <= 9) for i in range(9) for j in range(9)]

# 每行每个数字最多出现一次
rows_c = [Distinct(X[i]) for i in range(9)]

# 每列每个数字最多出现一次
cols_c = [Distinct([X[i][j] for i in range(9)]) for j in range(9)]

# 每个 3x3 方格每个数字最多出现一次
sq_c = [Distinct([X[3*i0 + i][3*j0 + j]
        for i in range(3) for j in range(3)])
        for i0 in range(3) for j0 in range(3)]
# 数独完整约束条件
constraint = cells_c + rows_c + cols_c + sq_c

# 3、求解
board = [
    [0, 0, 0, 0, 7, 0, 0, 0, 0],
    [0, 0, 0, 5, 0, 0, 0, 2, 8],
    [1, 0, 6, 0, 8, 3, 0, 0, 9],
    [9, 0, 5, 0, 0, 0, 0, 1, 2],
    [0, 0, 0, 1, 0, 0, 0, 5, 0],
    [0, 0, 1, 0, 3, 0, 0, 0, 0],
    [5, 0, 0, 2, 0, 8, 0, 3, 6],
    [7, 0, 8, 0, 5, 0, 0, 0, 0],
    [0, 0, 0, 3, 0, 0, 0, 0, 0]
]
r = solveShuDu(constraint, board)

参考样例:z3求解器(SMT)解各类方程各种逻辑题非常简单直观

3、Yices2求解器(Ubuntu)

(1)安装

  • 官网: https://yices.csl.sri.com/index.html

  • 安装

    sudo add-apt-repository ppa:sri-csl/formal-methods
    sudo apt-get update
    sudo apt-get install yices2
    

(2)使用-解方程

  • 使用格式:yices [option] <filename>

    • 参考样例:https://yices.csl.sri.com/papers/manual.pdf(P34)
  • 创建yices_example.txt

    这是一个解方程问题,对于-y<0和y-10<0、-2x-7y<0

    (define x::real)
    (assert
    (forall (y::real)
    (=> (and (< (* -1 y) 0) (< (+ -10 y) 0))
    (< (+ -7 (* -2 x) y) 0))))
    (ef-solve)
    (show-model)
    
  • 运行 yices

    yices --mode=ef yices_example.txt
    

    请添加图片描述

4、CVC5求解器

(1)安装

  • 官网: https://cvc5.github.io/
  • 在线CVC: https://cvc5.github.io/app/
  • 说明文档:https://cvc5.github.io/docs/cvc5-1.0.8/
  • 安装

请添加图片描述

(2)使用-字符串判断

  • 参考样例:
    • https://cvc5.github.io/docs/cvc5-1.0.8/examples/examples.html
    • https://smtlib.cs.uiowa.edu/examples.shtml (smtlib语言)
  • SMT-LIB语言:https://zhuanlan.zhihu.com/p/624758007

请添加图片描述

5、其他求解器

LiMbS+:SMT求解器LiMbS+基于矛盾体分离的多元协同动态

参考链接

  • SAT

SAT问题及其求解

用JavaScript写的基于CDCL的SAT求解器及学习笔记

【试译】冲突驱动子句学习 (Conflict Driven Clause Learning)

从零开始编写SAT求解器(一)

从零开始编写SAT求解器(二)

从零开始编写SAT求解器(三)

  • SAT-Minisat

知乎:miniSAT求解器(updating)

基于CDCL的SAT求解器MiniSat讲解(布尔约束传播部分)

基于CDCL的SAT求解器MiniSat讲解(冲突子句学习部分)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1518024.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 大页内存 Huge Pages 虚拟内存

Linux 大页内存 Huge Pages 虚拟内存 - 秋来叶黄 - 博客园 (cnblogs.com) Linux为什么要有大页内存&#xff1f;为什么DPDK必须要设置大页内存&#xff1f;这都是由系统架构决定的。一开始为了解决一个问题&#xff0c;设计了对应的方案&#xff0c;随着事物的发展&#xff0c…

【CesiumJS-5】绘制动态路线实现飞行航线、汽车轨迹、路径漫游等

实现效果 前言 Cesium中&#xff0c;动态路线绘制的核心是借助CZML格式&#xff0c;CZML是一种用来描述动态场景的JSON数组,可以用来描述点、线、多边形、体、模型及其他图元,同时定义它们是怎样随时间变化的&#xff1b; CZML主要做三件事&#xff1a; 1.添加模型信息 2.添加…

Hadoop大数据应用:Yarn 节点实现扩容与缩容

目录 一、实验 1.环境 2.Yarn 节点扩容 3.Yarn 节点缩容 二、问题 1.yarn启动服务报错 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构软件版本IP备注hadoop NameNode &#xff08;已部署&#xff09; SecondaryNameNode &#xff08;已部署&…

【vue baidu-map】marker鼠标悬浮点击事件失效

要实现的效果&#xff1a;鼠标悬浮或者点击标注点会出现弹窗 验证过鼠标点击悬浮代码没问题&#xff0c;最后发现是控件样式影响的 ::v-deep #bjmap .BMap_noprint {inset: 10px 90% auto auto !important; } 只要增加上述样式&#xff0c;鼠标悬浮事件就会失效

QT使用dumpcpp为COM生成h及cpp的方式,COM是C#的dll注册的

目录 1.C#的dll注册为COM&#xff0c;采用bat的方式 2.通过qt的dumpcpp来生成h及cpp文件 3.h文件和cpp文件处理。 台达数控系统的C#的dll dumpcpp用的tlb文件 dumpcpp生成的原生h文件 dumpcpp生成的原生cpp dump生成后的的原生cpp文件修改后的cpp文资源 dump生成后的的…

【探索Linux】—— 强大的命令行工具 P.27(网络编程套接字 —— UDP协议介绍 | TCP协议介绍 | UDP 和 TCP 的异同)

阅读导航 引言一、UDP协议1. UDP简介2. UDP的特点3. UDP的使用场景4. UDP的局限性 二、TCP协议1. TCP简介2. TCP的特点3. TCP的应用场景 三、UDP 和 TCP 的异同温馨提示 引言 在上一篇文章中&#xff0c;我们深入探讨了Linux网络编程的基石——套接字&#xff08;Socket&#…

pytorch loss及其梯度

目录 1.loss的种类1.1 MSE1.2 MSE推导1.3 autograd.grad1.4 loss.backward 2. Softmax2.1 softmax推导 1.loss的种类 常见两种一种是均方差&#xff0c;一种是交叉熵 1.1 MSE 1.2 MSE推导 1.3 autograd.grad 1.4 loss.backward 注意&#xff1a;autograd.grad直接返回梯度&a…

守护健康,从营养开始 —— 帕金森患者的饮食秘籍

亲爱的读者朋友们&#xff0c;您是否知道&#xff0c;在对抗帕金森病的道路上&#xff0c;正确的饮食和营养补充可以成为我们的有力盟友&#xff1f;今天&#xff0c;就让我们一起探索那些能够帮助帕金森患者改善症状、提高生活质量的营养素&#xff0c;开启健康生活的新篇章。…

【保姆级】GPT的Oops问题快速解决方案

GPT的"Oops"问题通常指的是GPT在处理请求时突然遇到错误或无法提供预期输出的情况。要快速解决这个问题&#xff0c;可以尝试以下分步策略&#xff1a; 确认问题范围&#xff1a; 首先&#xff0c;确认问题是偶发的还是持续存在的。如果是偶发的&#xff0c;可能是临…

深度学习_GoogLeNet_4

目标 知道GoogLeNet网络结构的特点能够利用GoogLeNet完成图像分类 一、开发背景 GoogLeNet在2014年由Google团队提出&#xff0c; 斩获当年ImageNet(ILSVRC14)竞赛中Classification Task (分类任务) 第一名&#xff0c;VGG获得了第二名&#xff0c;为了向“LeNet”致敬&#x…

不同抓手的码垛机:适配多元应用场景的灵活之选

在现代工业生产中&#xff0c;码垛机作为一种高效、自动化的物料搬运设备&#xff0c;已经广泛应用于各个行业。而抓手作为码垛机的关键部件&#xff0c;其种类的多样性和适用场景的广泛性&#xff0c;使得不同抓手的码垛机能够满足各种复杂、多变的生产需求。 首先&#xff0c…

蓝桥杯单片机快速开发笔记——LED、蜂鸣器和继电器

一、原理分析 二、简单示例 总结&#xff1a;HC138令Y5C等于1后&#xff0c;通过控制P0^4、P0^6置1打开、置0关闭&#xff0c;便可以控制继电器和蜂鸣器,具体看上述的原理分析&#xff0c;LED同理通过给P0置0便可以控制LED点亮&#xff0c;利用本专栏上一节知识即可简单控制 …

vue 引用百度地图

address.vue <template><div><!-- 地图 --><el-drawer:visible.sync"type1"direction"rtl"size"50%"append-to-bodyclass"map-drawer":before-close"beforeClose"><div style"width: 100%…

Linux学习笔记(一)Linux基本指令

文章目录 前言目录常见命令1. pwd 打印当前所在路径2. cd 改变路径、切换路径3. 家目录 回到顶级目录4. 当前路径和上一路径5. 上一次路径6. 绝对路径和相对路径7. ls 列出目录内容8. mkdir 创建目录9. rmdir 删除目录10. touch 创建文件11. mv 修改文件目录、移动路径12. cp 复…

Vue3基础笔记(1)模版语法 属性绑定 渲染

Vue全称Vue.js是一种渐进式的JavaScript框架&#xff0c;采用自底向上增量开发的设计&#xff0c;核心库只关注视图层。性能丰富&#xff0c;完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用&#xff0c;适用于场景丰富的web前端框架。灵活性和可逐步集成…

一周学会Django5 Python Web开发-Jinja3模版引擎-模板语法

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计37条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

Linux系统架构----Tomcat 部署

一.Tomcat概述 Tomcat服务器是一个免费的开放式源代码的web应用服务器&#xff0c;属于轻量级应用级服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP程序的首首选。 一般来说&#xff0c;tomcat虽然和Apache或者Nginx这些…

ThingsBoard 开源物联网平台

文章目录 1.ThingsBoard 介绍2.ThingsBoard 架构2.1.单体架构2.2.微服务架构 3.物联网网关4.边缘计算 ThingsBoard # ThingsBoardhttps://iothub.org.cn/docs/iot/ https://iothub.org.cn/docs/iot/thingsboard-ce/1.ThingsBoard 介绍 ThingsBoard 是一个开源物联网平台&…

MySQL 数据库 下载地址 国内阿里云站点

mysql安装包下载_开源镜像站-阿里云 以 MySQL 5.7 为例 mysql-MySQL-5.7安装包下载_开源镜像站-阿里云

C++ 拷贝构造函数和运算符重载

目录 一. 拷贝构造函数 1. 引入 2. 拷贝构造的概念 3. 浅拷贝 4. 深拷贝 二. C运算符重载 1. 概念 2. 注意事项 3.举例 一. 拷贝构造函数 1. 引入 我们在创建对象时&#xff0c;能不能创建一个与原先对象一模一样的新对象呢&#xff1f;为了解决这个问题&#x…