假设使用了几种内置和用户定义的Z3排序,例如: Int,Bool,S1,S2,...,有没有一种方法可以编写一个通用的排序包装和 - 包装函数,从排序A转换为B类并返回?例如
(declare-const a S1)
(declare-const b S2)
(declare-const c Int)
(WRAP[S1] b) ; Expression is of sort S1
(WRAP[S1] c) ; Expression is of sort S1
(WRAP[Int] (WRAP[S1] c)) ; Expression is of sort Int
我目前手动覆盖每个案例,例如
(declare-fun $boolToInt (Bool) Int)
(declare-fun $intToBool (Int) Bool)
(assert (forall ((x Int))
(= x ($boolToInt($intToBool x)))))
(assert (forall ((x Bool))
(= x ($intToBool($boolToInt x)))))
这样的包装器可以从给定的一组排序中自动创建,但我更喜欢可能的通用解决方案。
答案 0 :(得分:3)
您可以使用数据类型对“联合类型”进行编码。 这是一个例子:
(declare-sort S1)
(declare-sort S2)
(declare-datatypes () ((S1-S2-Int (WRAP-S1 (S1-Value S1))
(WRAP-S2 (S2-Value S2))
(WRAP-Int (Int-Value Int)))))
(declare-const a S1)
(declare-const b S2)
(declare-const c Int)
(simplify (WRAP-S1 a))
(simplify (= (WRAP-S1 a) (WRAP-Int 10)))
(simplify (S1-Value (WRAP-S1 a)))
(simplify (is-WRAP-S2 (WRAP-S1 a)))
(simplify (is-WRAP-S1 (WRAP-S1 a)))
(simplify (is-WRAP-Int (WRAP-Int c)))
(simplify (S1-Value (WRAP-S2 b)))
您可以在Z3 guide中找到有关数据类型的更多信息。数据类型S1-S2-Int
有三个构造函数:WRAP-S1
,WRAP-S2
和WRAP-Int
。 Z3会自动生成识别器谓词:is-WRAP-S1
,is-WRAP-S2
和is-WRAP-Int
。访问者S1-Value
,S2-Value
和Int-Value
用于“解构”S1-S2-Int
值。例如,对于所有a
,(S1-Value (WRAP-S1 a)) = a
。 (S1-Value (WRAP-S2 b))
的值未明确。在这种情况下,Z3将S1-Value
视为未解释的函数。
顺便说一句,公理
(assert (forall ((x Int))
(= x ($boolToInt($intToBool x)))))
相当于false。它本质上是试图将整数注入布尔值。