假设我有以下类型系统:
Type :=
A ; type of A
B ; type of B
C ; type of C
Int ; type of int
Real ; type of real
v :=
abc ; value of abc
real ; value of real
int ; value of int
t :=
v ; values can be mapped to terms
<abc_0, abc_1,... abc_n> = break abc' into int ; this will break abc' into real parts (think of this as a generic partitioning or division operation.
abc = op abc' for int ;
+ ; math plus operator, assume this "works" for types A|B|C, and works as expected for Int|Real
假设op
和break
的正文如此:
; op return type could, maximally, be the union of x, y, z, or minimally be the union types of x, y or x, z
op(x, y): ; recall, x:{A|B|C} and y:{A|B|C}
A z;
while([some condition]):
if ([another condition]):
x += y
else:
x += z
return x
break(x, y):
; For simplicity, this can just return an array of y-size, whose type is that of x
; in implementation this is much more complicated than this, but for simplicity this suffices to articulate the concept.
return array[y];
现在我给了这个程序,动态输入:
a = ... ; this is of {A|B|C}
x = 5 ; typeof Int
b = op a for x
c = break b into x
我需要使用Z3来证明这个程序的可满足性。
我真的不确定如何在z3中表示这个程序。联合打字,我认为可以通过下面的自定义数据类型来处理。但我不清楚如何处理循环/条件。就像在句子逻辑中一样,它们是否会转换为forall
或there exists at least one
量词?
(declare-datatypes () ((Type A B C)))
(define-sort Set (T) (Array T Type))
(declare-fun break_func (Type Real) (Set Type))
; not sure if this is correct or not...
(declare-fun op_func (Type Real) (Set Type))
(declare-const a Type)
(declare-const x Int)
; not quite sure what to put my for asserts....
; should I assert that the size of the break_func matches the input? If so, how
; I don't understand how to type check the output for op_func
(check-sat)
(get-model)
除了“这是正确的”之外,我的主要问题是: