Utilisez Z3 et smtlib pour calculer la configuration / le modèle avec des valeurs mixtes

StackOverflow https://stackoverflow.com/questions/8387807

  •  28-10-2019
  •  | 
  •  

Question

Comment calculer les valeurs attribuées? Voici un exemple:

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

Avec cela, j'aurais 2 modèles:

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

Maintenant, ce que je veux, c'est quelque chose comme ça:

(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))

Je voudrais donc obtenir le modèle où la somme des attributs est supérieure à 6:

x=true and z=true

Peut-être que travailler avec des tableaux est un moyen d'y parvenir ...

Était-ce utile?

La solution

Je ne sais pas si j'ai bien compris votre question. Il semble que vous souhaitiez associer un attribut (entier) à chaque variable booléenne. Ainsi, chaque variable est une paire: une valeur booléenne et un attribut entier. Je suppose que par sum, vous entendez la somme des attributs des variables affectées à true. Si tel est le cas, vous pouvez le modéliser en Z3 de la manière suivante:

;; 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)

Autres conseils

Avec trois variables, j'imagine que ce serait quelque chose comme:

(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))

Ici, je définis une macro cond_add pour ajouter une variable à un accumulateur lorsqu'une condition correspondante se vérifie.Et sum est défini pour tenir compte de la somme conditionnelle de x.val, y.val et z.val en fonction des valeurs de vérité de x, y et z.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top