表示 SMT-LIB 中的时间约束

2023-12-13

我试图在 SMT-LIB 中表示时间约束,以检查它们的可满足性。我正在寻找有关我所采取的方向的反馈。我对 SMT-LIB 比较陌生,非常感谢您的意见。

我所面临的限制是事件的时间和持续时间。例如,考虑以自然语言给出的以下约束:

  1. 约翰在 13:03:41 开始写一篇文章,他花了 20 分钟才完成。

  2. 写完后,他查看了电子邮件,花了 40 多分钟。

  3. 检查完电子邮件后,他给妻子打了电话。

  4. 14:00:00后他给妻子打电话。

很容易看出这组约束是可稳定的,我正在尝试使用 SMT 求解器来推断这一点。

为了对时间和持续时间的概念进行一些封装,我定义了新的排序来在数组中表示它们。一些宏被定义为充当结构:

(define-sort Time () (Array Int Int))
(define-fun new_time_ns ((hours Int) (minutes Int) (seconds Int) (nanos Int)) Time
    (store (store (store (store ((as const (Array Int Int)) 0) 1 hours) 2 minutes) 3 seconds) 4 nanos)
)
(define-sort Duration () (Array Int Int))
(define-fun new_duration_ns ((seconds Int) (nanos Int)) Duration
    (store (store ((as const (Array Int Int)) 0) 1 seconds) 2 nanos)
)

Getter 是使用宏定义的,允许我们检索特定的度量,例如:

(define-fun getDurationSecond ((d Duration)) Int
  (select d 1)
)

(define-fun getDurationNano ((d Duration)) Int
  (select d 2)
)

一些实用宏被定义用于时间和持续时间算术以及表达关系。例如,使用我们定义的一些辅助宏长于, 比短 and 持续时间相等如下:

(define-fun cmpInt ((i1 Int) (i2 Int)) Int
  (ite (< i1 i2) -1 (ite(> i1 i2) 1 0))
) 

(define-fun cmpDuration ((d1 Duration) (d2 Duration)) Int
  (ite (= (cmpInt (getDurationSecond d1) (getDurationSecond d2)) 0) 
    (ite (= (cmpInt (getDurationNano d1) (getDurationNano d2)) 0)
    0
    (cmpInt (getDurationNano d1) (getDurationNano d2)))
  (cmpInt (getDurationSecond d1) (getDurationSecond d2)))
)  

(define-fun isLongerThan ((d1 Duration) (d2 Duration)) Bool
  (> (cmpDuration d1 d2) 0)
)

(define-fun isShorterThan ((d1 Duration) (d2 Duration)) Bool
  (< (cmpDuration d1 d2) 0)
)

(define-fun isEqualDuration ((d1 Duration) (d2 Duration)) Bool
  (= (cmpDuration d1 d2) 0)
)

其余的定义可以在中找到这个文件.

基于此我可以通过一组断言来表达约束:

(declare-const write_start Time)
(declare-const write_end Time)
(declare-const write_duration Duration)

(declare-const check_start Time)
(declare-const check_end Time)
(declare-const check_duration Duration)

(declare-const phone_start Time)

(assert (= write_start (new_time_ns 13 03 41 0)))  ; the writing started at 13:03:41
(assert (= write_duration (new_duration 1200)))    ; the writing took 20 min (1200 sec).
(assert (= write_end (plusDuration write_start write_duration)))

(assert (isAfter check_start write_end))                   ; the check started after the writing
(assert (isLongerThan check_duration (new_duration 2400))) ; the check took more than 40 min
(assert (= check_end (plusDuration check_start check_duration)))

(assert (isAfter phone_start check_end))                   ; he phoned after the check
(assert (isAfter phone_start (new_time_ns 14 00 00 0)))    ; it was after 14:00:00

(check-sat)

一些疑问和问题:

  1. 从设计角度来看,我很想知道这是否是 SMT-LIB 中问题的合理建模。

  2. 此处要添加的一些注释:(A) 我决定使用数组来表示时间和持续时间对象,因为它们有助于对这些概念的内部字段(小时、分钟、秒、纳秒)进行分组。也可以使用单独的整数。 (B) 我非常依赖宏 (define-fun ...),这可能会使约束有点复杂,但我不知道还可以使用什么来达到所需的表达性和清晰度水平当前代码有。 (C) 目前没有限制时间字段的约束,因此分钟字段的值可以是 78。应添加断言,将秒限制为 59,将分钟限制为 59,将小时限制为 23 ,但我没有找到一种优雅的方法来做到这一点。

  3. 我假设我处于 FOL - QF_LIA 的可判定片段中 - 因为所有约束都是使用整数常量上的线性函数声明的。但是,我尝试运行所附代码通过 Z3,即使在普通计算机上本地运行 40 分钟后,它仍然没有返回分辨率(sat/unsat)。我实际上不知道它是否可以解决问题。我对 QF-LIA 的假设可能是错误的,而且 Z3 也可能在此类限制中挣扎。我可以补充一点,当我尝试更简单的约束时,Z3 设法达到了解决方案,但我注意到它生成的模型非常复杂,有很多内部结构。有人可以给我一些想法来调查这里吗? Z3的在线证明和我的代码可以找到here。我还没有尝试过其他 SMT 求解器。

  4. 我不知道尝试在 SMT-LIB 中定义这种类型的时间约束的并行工作。我真的很感激对现有作品的参考。

Thanks!


我喜欢你的方法,但我认为你通过定义自己的排序,特别是使用数组理论,使情况变得过于复杂。

Also, mathematically, the integer theories are harder than their real counterparts. For example "n = pq, solve for p" is trivial if n, p, and q are reals, but if they're integers then it's integer factoring, which is hard. Similarly xn + yn = zn, n > 2 is easy to solve in the reals, but in the integers, that's Fermat's last theorem. These examples are nonlinear, but I claim you're better-off to be in QF_LRA than QF_LIA, if you consider that the techniques used to solve QF_LRA are taught to middle-school and high-school students. Time is closer to a real number than it is to a bunch of integers, anyway.

根据我对 SMT 求解器(特别是 Z3)的经验,您最好使用更简单的理论。它将允许 Z3 使用其最强大的内部求解器。如果您使用更复杂的理论(例如数组),您可能会得到惊人的结果,或者您可能会发现求解器超时并且您不知道原因,就像您提出的解决方案的情况一样。

从软件工程的角度来看,这并不那么好,但从数学上来说,我建议对您提出的问题使用以下简单的解决方案,其中所有时间都表示为实数,以感兴趣的日期午夜以来的秒数表示:

; Output all real-valued numbers in decimal-format.
(set-option :pp.decimal true)

; Convenience function for converting hh:mm:ss formatted times to seconds since midnight.
(define-fun time_hms ((hour Real) (minute Real) (second Real)) Real
    (+ (+ (* 3600.0 hour) (* 60.0 minute)) second)
)

; Convenience function for converting durations in minutes to seconds.
(define-fun duration_m ((minute Real)) Real
    (* 60.0 minute)
)

; Variable declarations. Durations are in seconds. Times are in seconds since midnight.
(declare-fun write_start () Real)
(declare-fun write_end () Real)
(declare-fun write_duration () Real)
(declare-fun check_start () Real)
(declare-fun check_end () Real)
(declare-fun check_duration () Real)
(declare-fun phone_start () Real)

; Constraints.

; 1. John started writing an essay at 13:03:41, and it took him 20 min to complete it.
(assert (= write_start (time_hms 13 03 41)))
(assert (= write_duration (duration_m 20)))
(assert (= write_end (+ write_start write_duration)))

; 2. After writing, he checked his emails, which took him more than 40 min.
(assert (> check_start write_end))
(assert (> check_duration (duration_m 40)))
(assert (= check_end (+ check_start check_duration)))

; 3. After checking his emails, he phoned his wife.
(assert (> phone_start check_end))

; 4. He phoned his wife after 14:00:00.
(assert (> phone_start (time_hms 14 00 00)))

(check-sat)
(get-value (write_start write_duration write_end check_start check_end check_duration phone_start))
(exit)

Z3和CVC4都很快找到了解决方案:

sat
((write_start 47021.0)
 (write_duration 1200.0)
 (write_end 48221.0)
 (check_start 48222.0)
 (check_end 50623.0)
 (check_duration 2401.0)
 (phone_start 50624.0))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

表示 SMT-LIB 中的时间约束 的相关文章

  • 输入字符时无限循环[重复]

    这个问题在这里已经有答案了 我试图限制用户仅输入 1 或 2 int ch do cout lt lt Enter n cin gt gt ch switch ch case 1 cout lt lt 1 break case 2 cout
  • 计算进行时显示进度条

    我正在编写代码来计算 Pi 的值 有时可能需要很长时间才能计算 我添加了一个进度条来显示进度 但代码完全按照我的指示执行 它在计算后打开进度条 然后立即关闭它 当值达到 100 时它会关闭 我试图将进度条的代码粘贴到循环中 但很快我意识到这
  • 在Android中使用EditText上的TextWatcher实时计算总计和总和?

    在这里 我想采用来自我的数据库的默认值 并将 Text 设置为该值并计算净费率和总计 否则如果用户编辑费率或收取费用 我想根据该值计算净费率和总计即时的 这是我用于计算和显示值的代码 private void showItem String
  • 所有可能的词

    我想使用 a z 创建所有可能的 5 个字母单词 请建议任何好的且快速的算法 我尝试过创建一个 它看起来像这样 byte allchar new byte a b c d e f g h i j k l m n o p q r s t u
  • 逻辑表达式解析器

    我正在尝试为以下表达式创建一个逻辑表达式解析器 变量A gt 变量B 而不是变量C 对于给定的变量值 解析器应该能够返回结果是 true 还是 false 基本上 表达式仅包含变量 逻辑运算符 或 与 蕴涵 等价 否定和括号 我想问实现这种
  • 如何从 Z3 中的 Seq 类型中提取元素作为基本类型?

    如何将序列中的元素提取到基本类型 以便以下内容正常工作 define sort ISeq Seq Int define const x ISeq seq unit 5 define const y ISeq seq unit 6 asser
  • 使用 Z3 SMT 解决谓词演算问题

    我想使用 Z3 来解决最自然地用原子 符号 集合 谓词和一阶逻辑表达的问题 例如 伪代码 A a1 a2 a3 A is a set B b1 b2 b3 C c1 c2 c3 def p a A b B c C gt Bool p is
  • C++:检查括号和方括号在字符串中是否平衡(逻辑问题)[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 检查字符串中的每个 是否都满足 或 检查字符串中的每个 是否与 或 匹配 例如 您永远不能拥有像这样的字符串 a a a a a 但是
  • 给定输入生成真值表?

    是否有一种智能算法可以获取多个概率并在多维数组或容器内生成相应的真值表 Ex n 3 N 0 0 0 0 0 1 0 1 0 1 1 1 我可以使用 for 循环和 If 来完成此操作 但我知道我的方法会很慢且耗时 因此 我想问是否有一种高
  • 将理论插件与求解器结合使用

    最新版本Z3 http z3 codeplex com解耦了以下概念Z3 context and Z3 solver The API http research microsoft com en us um redmond projects
  • Z3 求解器中 MAxSMT 和用户定义成本函数的组合

    我正在使用 Z3 来优化带有一些软约束 带有加权 MaxSMT 的成本函数 我很好奇 MaxSMT 和用户定义的成本函数如何交互 求解器是否最小化 MaxSMT 成本和目标函数两者 是否有优先级机制 我找不到这方面的任何文档 如果我遗漏了什
  • 目标没有战术支持

    我有一些代码 我想在一些策略的帮助下检查它们 因为我有很多if then else声明 我要申请elim term ite tactic 我使用了以下策略 check sat using then simplify arith lhs tr
  • Verilog 中的 If 语句和分配连线

    我试图弄清楚基于组合逻辑分配电线的基础知识 I have wire val wire x wire a wire b always begin if val 00 I want to assign x a if val 01 I want
  • Z3 SMT 求解器中的常数相等

    我正在使用 Microsoft 的 Z3 SMT 求解器 并且我正在尝试定义自定义类型的常量 默认情况下 这些常量似乎并不不平等 假设您有以下程序 declare sort S 0 declare const x S declare con
  • 按位运算的替代方法

    设想 我说有 4 个复选框 用户可以以任意组合选择这些复选框 他们也有权不选择任何一个复选框 我必须将这 4 个选项存储到一列中 我认为最好的选择是使用二进制表示形式存储 option1 has the constant value 1 o
  • 需要开发数据库逻辑方面的帮助

    这是我的一个小型项目 航空公司预订系统 让我们称这个航空公司为 FlyMi 我有一个数据库 尚未决定使用哪个数据库 我的朋友想要使用 MongoDB 无论如何 这是我的要求 我有一张表 其中包含航班详细信息 航班号 时刻表等 我将使用这张表
  • 非成员规则在 Prolog 中无法按预期工作

    我正在尝试在 Prolog 中创建一个迷宫程序 其目的是找到一条从迷宫起点到迷宫中心点 m 的路线 迷宫由使用四种颜色之一连接的正方形组成 蓝色 绿色 紫色或橙色 从起点到中心的路线遵循四种颜色的重复图案 我创建了以下代码 link2 A
  • 如何解决 Z3 中的最小化约束?

    谁能告诉我如何通过 Z3py 实现最小化整数问题 如下所示 我如何定义所有语句 这里所有的变量都是int排序的 Z3中有没有专门的求解器可以解决此类问题 如果有的话 我该如何设置该解算器的配置 Thanks 以下是一些相关 类似的问题和答案
  • 是否可以将一位的位向量转换为 SMTLib2 中的布尔变量?

    我想要一个布尔变量来测试 例如 位向量的第三位是否为 0 位向量的理论允许提取 1 位作为位向量 但不是布尔类型 我想知道我是否可以出演这个角色 谢谢 更新 如果我的问题不清楚 我很抱歉 但 Nikolaj Bjorner 的答案是如何测试
  • 如何将分支逻辑持久化到数据库中?

    我们正在构建一个供内部使用的调查引擎 我想知道如何将问题分支逻辑持久化到数据库中 任何机构之前做过这件事或者对数据库模式有什么想法吗 如果用户给出答案 我们需要根据添加到问题的逻辑跳到下一个问题 每个问题可以添加多个逻辑 For eg Qu

随机推荐