【问题标题】:Z3 unsigned variables - simplifyZ3 无符号变量 - 简化
【发布时间】:2015-06-10 22:30:43
【问题描述】:

我想简化以下约束(constr):

4p+3q

p(和 r 类似)创建如下:

Z3_ast p;
Z3_sort ty = Z3_mk_int_sort(ctx)
Z3_symbol s = Z3_mk_string_symbol(ctx, "p");
p = Z3_mk_const(ctx, s, ty)

如果我愿意

Z3_simplify(ctx, constr)

因为 p 和 r 是整数,所以没有任何变化。

如何编码 p an r 是自然数(无符号)的知识?

简单地添加约束 p >= 0 AND r >= 0 对简化我的约束没有帮助(但在寻求解决方案时当然有帮助)。

为了澄清,

4p+3q

应该简化为:

4p+3q

因为它是最难实现的(暗示另一个)。

更新: 在约束上尝试了 Taylor 的解决方案并且它有效。 当我尝试对以下不同(有点)漂亮的约束使用相同的技术时:

(([(false AND (0=0 AND q>=0 AND p>=0)

通过 Z3_simplify 这被简化为

(q=0 AND q>=0 AND p>=0)

如果我使用 ctx-solver-simplify 和目标一起创建策略并使用 Z3_apply_result_to_string,我会得到以下结果:

(goals
(goal
  (let ((a!1 (+ 5 (* 0 epsilon) (* 0 q) (* 0 p)))
        (a!3 (or false
                 (<= (+ 0 (* 0 epsilon) (* 0 q) p)
                     (+ 7 (* 0 epsilon) (* 0 q) (* 0 p))))))
  (let ((a!2 (<= (+ 0 (* 0 epsilon) q (* 0 p)) a!1)))
    (or (and false (<= 0 a!1) false)
        (and (<= 0 a!1)
             (or (and a!2 a!2 a!3) (and false false) (and false false))))))
  (>= epsilon 0)
  (>= q 0)
  (>= p 0))
)

如何获得像 Z3_simplify 这样的简单表示?

【问题讨论】:

  • 您是否担心4p+3q-10+r 溢出?
  • 这里没有溢出的概念:它们是数学意义上的整数/自然数(即,可能趋于无穷大),并且在 Z3/SMT 中表示为符号数学对象,而不是有限的东西范围(如 32 位 int 等)

标签: c constraints z3 unsigned smt


【解决方案1】:

对于这个例子,这可以使用最强的简化器 ctx-solver-simplify 来完成,但请注意,通常这可能会转换您的方程。这是您的示例(rise4fun 链接:http://rise4fun.com/Z3/tw0t):

(declare-fun p () Int)
(declare-fun q () Int)
(declare-fun r () Int)

(assert (and (<= (+ (* 4 p) (* 3 q)) (- r 10)) (<= (+ (* 4 p) (* 3 q)) (- r 12))))

(apply ctx-solver-simplify)

(apply (then simplify ctx-simplify ctx-solver-simplify))

; (help-tactic)

输出:

(goals
(goal
  (<= (+ (* 4 p) (* 3 q)) (+ r (* (- 1) 12)))
  :precision precise :depth 1)
)
(goals
(goal
  (<= (+ (* 4 p) (* 3 q)) (+ (- 12) r))
  :precision precise :depth 3)
)

您也可以通过 C API 使用这些策略。

您也可以添加自然数约束:

(assert (and (<= (+ (* 4 p) (* 3 q)) (- r 10)) (<= (+ (* 4 p) (* 3 q)) (- r 12))))
(assert (>= p 0))
(assert (>= r 0))
(apply ctx-solver-simplify)
(apply (then simplify ctx-simplify ctx-solver-simplify))

输出:

(goals
(goal
  (<= (+ (* 4 p) (* 3 q)) (+ r (* (- 1) 12)))
  (>= p 0)
  (>= r 0)
  :precision precise :depth 1)
)
(goals
(goal
  (<= (+ (* 4 p) (* 3 q)) (+ (- 12) r))
  (>= p 0)
  (>= r 0)
  :precision precise :depth 3)
)

更新:

如果您需要简化的公式,您可能只需要在应用简化策略后迭代适当的子目标以获取公式,例如,请参阅Z3_apply_result_get_subgoal:

http://z3prover.github.io/api/html/group__capi.html#ga63813eb4cc7865f0cf714e1eff0e0c64

当我对您的新约束尝试此策略时,它还会返回您所说的简化答案(rise4fun 链接:http://rise4fun.com/Z3/T1TZ):

(declare-fun epsilon () Int)
(declare-fun q () Int)
(declare-fun p () Int)

(assert (and  (let ((a!1 (+ 5 (* 0 epsilon) (* 0 q) (* 0 p)))
        (a!3 (or false
                 (<= (+ 0 (* 0 epsilon) (* 0 q) p)
                     (+ 7 (* 0 epsilon) (* 0 q) (* 0 p))))))
  (let ((a!2 (<= (+ 0 (* 0 epsilon) q (* 0 p)) a!1)))
    (or (and false (<= 0 a!1) false)
        (and (<= 0 a!1)
             (or (and a!2 a!2 a!3) (and false false) (and false false))))))
  (>= epsilon 0)
  (>= q 0)
  (>= p 0)))

(apply (then simplify ctx-simplify ctx-solver-simplify))

产生

(goals
(goal
  (<= q 5)
  (>= epsilon 0)
  (>= q 0)
  (>= p 0)
  (<= p 7)
  :precision precise :depth 3)
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    • 2012-08-28
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多