使用 SMTLIB2 查找 z3 中的最大值
finding max of the numbers in z3 using SMTLIB2
我有 7 个杯子,其中装有一些水。我需要对这些杯子进行编程,使其盛放不同量的水。完成此操作后,我需要测量水量最多的杯子,然后取出一些水(比如 2 个单位的水)。
c 实现:
float c1=2.0, c2= 2.6, c3 = 2.8, c4=4.4 , c5 = 2.4, c6 = 2.1, c7 = 5.8;
if((c1 > c2) && (c1 > c3) && (c1 > c4) && (c1 > c5) && (c1 > c6) && (c1 > c7)); c1=c1-2;
if((c2 > c1) && (c2 > c3) && (c2 > c4) && (c2 > c5) && (c2 > c6) && (c2 > c7)); c2=c2-2;
if((c3 > c2) && (c3 > c1) && (c3 > c4) && (c3 > c5) && (c3 > c6) && (c3 > c7)); c3=c3-2;
if((c4 > c2) && (c4 > c3) && (c4 > c1) && (c4 > c5) && (c4 > c6) && (c4 > c7)); c4=c4-2;
if((c5 > c2) && (c5 > c3) && (c5 > c4) && (c5 > c1) && (c5 > c6) && (c5 > c7)); c5=c5-2;
if((c6 > c2) && (c6 > c3) && (c6 > c4) && (c6 > c5) && (c6 > c1) && (c6 > c7)); c6=c6-2;
if((c7 > c2) && (c7 > c3) && (c7 > c4) && (c7 > c5) && (c7 > c6) && (c7 > c1)); c7=c7-2;
这将给出一个答案 c7 = 3.8
我试图在 z3 中实现它,并将值分配给 c1....c7
ite( (and((> c1 c2) (> c1 c3) (> c1 c4) (> c1 c5) (> c1 c6) (> c1 c7))) (= c1_1 (- c1 2) (= c1_1 c1))
.
.
.repeated till c7_1
当我得到模型值时,它应该给 c7_1 作为 3.8
是否可以在 z3 中定义它?当我在 if 条件(在 ite)中使用不同条件的 and 时,它给我一个错误。不能这样定义吗?有办法解决这个问题吗?
提前致谢
[问题描述][1]
我正在尝试使用 Z3 工具,第一部分很容易获得,但是第二部分有点困难。
当然可以。在 SMTLib 中:
; declare the cups
(declare-const c1 Real)
(declare-const c2 Real)
(declare-const c3 Real)
(declare-const c4 Real)
(declare-const c5 Real)
(declare-const c6 Real)
(declare-const c7 Real)
; each cup has a non-negative units of water
(assert (>= c1 0))
(assert (>= c2 0))
(assert (>= c3 0))
(assert (>= c4 0))
(assert (>= c5 0))
(assert (>= c6 0))
(assert (>= c7 0))
; each amount is different
(assert (distinct c1 c2 c3 c4 c5 c6 c7))
; find maximum, helper function
(define-fun max ((a Real) (b Real)) Real (ite (> a b) a b))
; find the cup with maximum water in it
(define-fun maxC () Real (max c1 (max c2 (max c3 (max c4 (max c5 (max c6 c7)))))))
; make sure there's at least 2 units in the max, per the problem
(assert (>= maxC 2))
; final value
(define-fun finalRes () Real (- maxC 2))
; solve
(check-sat)
(get-value (c1 c2 c3 c4 c5 c6 c7 maxC finalRes))
z3 说:
sat
((c1 2.0)
(c2 (/ 11.0 6.0))
(c3 (/ 19.0 12.0))
(c4 (/ 7.0 4.0))
(c5 (/ 3.0 2.0))
(c6 (/ 23.0 12.0))
(c7 (/ 5.0 3.0))
(maxC 2.0)
(finalRes 0.0))
因此,看起来它在 c1
中放置了 2
个单位,而其他所有单位都少于 2
,因此您最终得到了 0
的最终值离开了。
你的问题很模糊,其他限制可能在这里起作用,但希望这能帮助你开始。
这是查找 max
的另一种方法,它不使用 ITE
。
; declare the cups
(declare-const c1 Real)
(declare-const c2 Real)
(declare-const c3 Real)
(declare-const c4 Real)
(declare-const c5 Real)
(declare-const c6 Real)
(declare-const c7 Real)
; each cup has a non-negative units of water
(assert (>= c1 0))
(assert (>= c2 0))
(assert (>= c3 0))
(assert (>= c4 0))
(assert (>= c5 0))
(assert (>= c6 0))
(assert (>= c7 0))
; each amount is different
(assert (distinct c1 c2 c3 c4 c5 c6 c7))
(declare-fun max () Real)
(assert (and (<= c1 max) (<= c2 max) (<= c3 max) (<= c4 max) (<= c5 max) (<= c6 max) (<= c7 max)))
(assert (or (<= max c1) (<= max c2) (<= max c3) (<= max c4) (<= max c5) (<= max c6) (<= max c7) ))
; make sure there's at least 2 units in the max, per the problem
(assert (<= 2 max))
; final value
(define-fun finalRes () Real (- max 2))
; solve
(check-sat)
(get-value (c1 c2 c3 c4 c5 c6 c7 maxC finalRes))
结果:
sat
((c1 2.0)
(c2 (/ 4.0 3.0))
(c3 0.0)
(c4 (/ 1.0 3.0))
(c5 1.0)
(c6 (/ 2.0 3.0))
(c7 (/ 5.0 3.0))
(max 2.0)
(finalRes 0.0))
我有 7 个杯子,其中装有一些水。我需要对这些杯子进行编程,使其盛放不同量的水。完成此操作后,我需要测量水量最多的杯子,然后取出一些水(比如 2 个单位的水)。
c 实现:
float c1=2.0, c2= 2.6, c3 = 2.8, c4=4.4 , c5 = 2.4, c6 = 2.1, c7 = 5.8;
if((c1 > c2) && (c1 > c3) && (c1 > c4) && (c1 > c5) && (c1 > c6) && (c1 > c7)); c1=c1-2;
if((c2 > c1) && (c2 > c3) && (c2 > c4) && (c2 > c5) && (c2 > c6) && (c2 > c7)); c2=c2-2;
if((c3 > c2) && (c3 > c1) && (c3 > c4) && (c3 > c5) && (c3 > c6) && (c3 > c7)); c3=c3-2;
if((c4 > c2) && (c4 > c3) && (c4 > c1) && (c4 > c5) && (c4 > c6) && (c4 > c7)); c4=c4-2;
if((c5 > c2) && (c5 > c3) && (c5 > c4) && (c5 > c1) && (c5 > c6) && (c5 > c7)); c5=c5-2;
if((c6 > c2) && (c6 > c3) && (c6 > c4) && (c6 > c5) && (c6 > c1) && (c6 > c7)); c6=c6-2;
if((c7 > c2) && (c7 > c3) && (c7 > c4) && (c7 > c5) && (c7 > c6) && (c7 > c1)); c7=c7-2;
这将给出一个答案 c7 = 3.8
我试图在 z3 中实现它,并将值分配给 c1....c7
ite( (and((> c1 c2) (> c1 c3) (> c1 c4) (> c1 c5) (> c1 c6) (> c1 c7))) (= c1_1 (- c1 2) (= c1_1 c1))
.
.
.repeated till c7_1
当我得到模型值时,它应该给 c7_1 作为 3.8
是否可以在 z3 中定义它?当我在 if 条件(在 ite)中使用不同条件的 and 时,它给我一个错误。不能这样定义吗?有办法解决这个问题吗?
提前致谢
[问题描述][1]
我正在尝试使用 Z3 工具,第一部分很容易获得,但是第二部分有点困难。
当然可以。在 SMTLib 中:
; declare the cups
(declare-const c1 Real)
(declare-const c2 Real)
(declare-const c3 Real)
(declare-const c4 Real)
(declare-const c5 Real)
(declare-const c6 Real)
(declare-const c7 Real)
; each cup has a non-negative units of water
(assert (>= c1 0))
(assert (>= c2 0))
(assert (>= c3 0))
(assert (>= c4 0))
(assert (>= c5 0))
(assert (>= c6 0))
(assert (>= c7 0))
; each amount is different
(assert (distinct c1 c2 c3 c4 c5 c6 c7))
; find maximum, helper function
(define-fun max ((a Real) (b Real)) Real (ite (> a b) a b))
; find the cup with maximum water in it
(define-fun maxC () Real (max c1 (max c2 (max c3 (max c4 (max c5 (max c6 c7)))))))
; make sure there's at least 2 units in the max, per the problem
(assert (>= maxC 2))
; final value
(define-fun finalRes () Real (- maxC 2))
; solve
(check-sat)
(get-value (c1 c2 c3 c4 c5 c6 c7 maxC finalRes))
z3 说:
sat
((c1 2.0)
(c2 (/ 11.0 6.0))
(c3 (/ 19.0 12.0))
(c4 (/ 7.0 4.0))
(c5 (/ 3.0 2.0))
(c6 (/ 23.0 12.0))
(c7 (/ 5.0 3.0))
(maxC 2.0)
(finalRes 0.0))
因此,看起来它在 c1
中放置了 2
个单位,而其他所有单位都少于 2
,因此您最终得到了 0
的最终值离开了。
你的问题很模糊,其他限制可能在这里起作用,但希望这能帮助你开始。
这是查找 max
的另一种方法,它不使用 ITE
。
; declare the cups
(declare-const c1 Real)
(declare-const c2 Real)
(declare-const c3 Real)
(declare-const c4 Real)
(declare-const c5 Real)
(declare-const c6 Real)
(declare-const c7 Real)
; each cup has a non-negative units of water
(assert (>= c1 0))
(assert (>= c2 0))
(assert (>= c3 0))
(assert (>= c4 0))
(assert (>= c5 0))
(assert (>= c6 0))
(assert (>= c7 0))
; each amount is different
(assert (distinct c1 c2 c3 c4 c5 c6 c7))
(declare-fun max () Real)
(assert (and (<= c1 max) (<= c2 max) (<= c3 max) (<= c4 max) (<= c5 max) (<= c6 max) (<= c7 max)))
(assert (or (<= max c1) (<= max c2) (<= max c3) (<= max c4) (<= max c5) (<= max c6) (<= max c7) ))
; make sure there's at least 2 units in the max, per the problem
(assert (<= 2 max))
; final value
(define-fun finalRes () Real (- max 2))
; solve
(check-sat)
(get-value (c1 c2 c3 c4 c5 c6 c7 maxC finalRes))
结果:
sat
((c1 2.0)
(c2 (/ 4.0 3.0))
(c3 0.0)
(c4 (/ 1.0 3.0))
(c5 1.0)
(c6 (/ 2.0 3.0))
(c7 (/ 5.0 3.0))
(max 2.0)
(finalRes 0.0))