Question

Quelle est la meilleure façon d'exprimer une relation de sous-type entre les types d'énumération en Z3?

Plus précisément, je veux faire quelque chose comme ce qui suit:

(declare-datatypes () ((Animal Eagle Snake Scorpion)))

et puis créez un nouveau sous-type:

(declare-datatypes () ((Mammal Cat Rat Bat)))

de sorte qu'une affirmation selon laquelle il y a 4 constantes distinctes d'un animal est de type SAT, mais une affirmation selon laquelle il y a 4 constantes distinctes de type mammifère est UNSAT.

Était-ce utile?

La solution

Z3 n'a pas de soutien direct pour les relations de sous-type (de subsort). Je vois deux façons de les modéliser dans Z3.

Par exemple, vous pouvez avoir une sorte énumération Animal qui contient tous les animaux. Ensuite, vous définissez prédicats tels que:. is-mammal, de is-reptile, etc

Voici le script qui utilise cette approche:

(set-option :produce-models true)
(declare-datatypes () ((Animal Eagle Snake Scorpion Cat Rat Man)))

(define-fun is-mammal ((x Animal)) Bool
        (or (= x Cat) (= x Rat) (= x Man)))

(declare-const a1 Animal)
(declare-const a2 Animal)
(declare-const a3 Animal)
(declare-const a4 Animal)


(assert (distinct a1 a2 a3 a4))
(check-sat)
; sat
(get-model)

; now, we constraint a1, a2, a3 and a4 to be mammals.
(assert (is-mammal a1))
(assert (is-mammal a2))
(assert (is-mammal a3))
(assert (is-mammal a4))
(check-sat)
; unsat

Une autre solution utilise des types de données pour définir sortes d'énumération et les tris syndicaux. Autrement dit, nous déclarons un type de données pour chaque classe d'animaux: MammalType, ReptileType, etc. Chacun d'eux est un type d'énumération. Ensuite, nous déclarons un union type de données: AnimalType. Ce type de données contient un constructeur pour chaque classe d'animaux: Mammal, Reptile, etc. Z3 crée automatiquement un is-[constructor-name] sous-jacente (de reconnaissance) pour chaque constructeur: is-Mammal, is-Reptile, etc. Nous nommons accesseurs comme "Animal2Class": Animal2Mammal, Animal2Reptile, etc. Vous pouvez trouver plus d'informations sur les types de données à http: / /rise4fun.com/z3/tutorial/guide . Voici le script en utilisant cet encodage:

(set-option :produce-models true)

(declare-datatypes () ((AveType Eagle Sparrow)))
(declare-datatypes () ((ReptileType Snake)))
(declare-datatypes () ((ArachnidType Scorpion Spider)))
(declare-datatypes () ((MammalType Cat Rat Man)))

(declare-datatypes () ((AnimalType 
                        (Ave (Animal2Ave AveType))
                        (Reptile (Animal2Reptile ReptileType))
                        (Arachnid (Animal2Arachnid ArachnidType))
                        (Mammal (Animal2Mammal MammalType)))))

(declare-const a1 AnimalType)
(declare-const a2 AnimalType)
(declare-const a3 AnimalType)
(declare-const a4 AnimalType)

(assert (distinct a1 a2 a3 a4))
(check-sat)
; sat
(get-model)

; now, we constraint a1, a2, a3 and a4 to be mammals.
(assert (is-Mammal a1))
(assert (is-Mammal a2))
(assert (is-Mammal a3))
(assert (is-Mammal a4))
(check-sat)
; unsat
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top