使用 Z3 和 smtlib 计算具有混合值的配置/模型

发布于 2024-12-19 09:36:20 字数 642 浏览 5 评论 0原文

如何计算属性值? 这是一个例子:

(declare-fun x () bool)
(declare-fun y () bool)
(declare-fun z () bool)
(assert (AND x (OR y z)))

这样我会得到 2 个模型:

x=true and y=true
x=true and z=true

现在,我想要的是这样的:

(declare-fun x () bool)
(declare-fun y () bool)
(declare-fun z () bool)
(declare-fun x.val () Int)
(declare-fun y.val () Int)
(declare-fun z.val () Int)
(assert (= x.val 2))
(assert (= y.val 3))
(assert (= z.val 5))
(assert (AND x (OR y z)))
(assert (> sum 6))

所以,我想得到属性总和大于 6 的模型:

x=true and z=true

也许使用数组是一种方法达到这个...

How do I calculate attributed values?
Here's an example:

(declare-fun x () bool)
(declare-fun y () bool)
(declare-fun z () bool)
(assert (AND x (OR y z)))

With this I would get 2 models:

x=true and y=true
x=true and z=true

Now, what I want is something like this:

(declare-fun x () bool)
(declare-fun y () bool)
(declare-fun z () bool)
(declare-fun x.val () Int)
(declare-fun y.val () Int)
(declare-fun z.val () Int)
(assert (= x.val 2))
(assert (= y.val 3))
(assert (= z.val 5))
(assert (AND x (OR y z)))
(assert (> sum 6))

So, I would like to get the model where the sum of the attributes is larger than 6:

x=true and z=true

Maybe working with arrays is a way to achieve this...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别再吹冷风 2024-12-26 09:36:21

我不确定我是否正确理解了你的问题。
您似乎想将一个(整数)属性关联到每个布尔变量。
因此,每个变量都是一对:一个布尔值和一个整数属性。
我假设 sum 是指分配给 true 的变量属性的总和。
如果是这种情况,您可以按以下方式在 Z3 中对其进行建模:

;; Enable model construction
(set-option :produce-models true)

;; Declare a new type (sort) that is a pair (Bool, Int).
;; Given a variable x of type/sort WBool, we can write
;;  - (value x) for getting its Boolean value
;;  - (attr x)  for getting the integer "attribute" value
(declare-datatypes () ((WBool (mk-wbool (value Bool) (attr Int)))))

;; Now, we declare a macro int-value that returns (attr x) if
;; (value x) is true, and 0 otherwise
(define-fun int-value ((x WBool)) Int
  (ite (value x) (attr x) 0))

(declare-fun x () WBool)
(declare-fun y () WBool)
(declare-fun z () WBool)

;; Set the attribute values for x, y and z
(assert (= (attr x) 2))
(assert (= (attr y) 3))
(assert (= (attr z) 5))

;; Assert Boolean constraint on x, y and z.
(assert (and (value x) (or (value y) (value z))))

;; Assert that the sum of the attributes of the variables assigned to true is greater than 6.
(assert (> (+ (int-value x) (int-value y) (int-value z)) 6))
(check-sat)
(get-model)

(assert (not (value z)))
(check-sat)

I’m not sure if I understood your question correctly.
It seems you want to associate an (integer) attribute to each Boolean variable.
So, each variable is a pair: a Boolean value, and an integer attribute.
I’m assuming that by sum , you meant the sum of the attributes of the variables assigned to true.
If that is the case, you can model it in Z3 in the following way:

;; Enable model construction
(set-option :produce-models true)

;; Declare a new type (sort) that is a pair (Bool, Int).
;; Given a variable x of type/sort WBool, we can write
;;  - (value x) for getting its Boolean value
;;  - (attr x)  for getting the integer "attribute" value
(declare-datatypes () ((WBool (mk-wbool (value Bool) (attr Int)))))

;; Now, we declare a macro int-value that returns (attr x) if
;; (value x) is true, and 0 otherwise
(define-fun int-value ((x WBool)) Int
  (ite (value x) (attr x) 0))

(declare-fun x () WBool)
(declare-fun y () WBool)
(declare-fun z () WBool)

;; Set the attribute values for x, y and z
(assert (= (attr x) 2))
(assert (= (attr y) 3))
(assert (= (attr z) 5))

;; Assert Boolean constraint on x, y and z.
(assert (and (value x) (or (value y) (value z))))

;; Assert that the sum of the attributes of the variables assigned to true is greater than 6.
(assert (> (+ (int-value x) (int-value y) (int-value z)) 6))
(check-sat)
(get-model)

(assert (not (value z)))
(check-sat)
动听の歌 2024-12-26 09:36:21

对于三个变量,我想它会是这样的:

(define-fun cond_add ((cond Bool) (x Int) (sum Int)) Int
  (ite cond (+ sum x) sum))
(declare-fun sum () Int)
(assert (= sum (cond_add x x.val (cond_add y y.val (cond_add z z.val 0)))))
(assert (> sum 6))

这里我定义了一个宏 cond_add 来在相应的条件成立时将变量添加到累加器中。 sum 被定义为考虑基于 x.valy.valz.val 的条件总和关于xyz 的真值。

With three variables, I imagine it would be something like:

(define-fun cond_add ((cond Bool) (x Int) (sum Int)) Int
  (ite cond (+ sum x) sum))
(declare-fun sum () Int)
(assert (= sum (cond_add x x.val (cond_add y y.val (cond_add z z.val 0)))))
(assert (> sum 6))

Here I define a macro cond_add to add a variable to an accumulator when a corresponding condition holds. And sum is defined to account for conditional sum of x.val, y.val and z.val based on truth values of x, y and z.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文