问题
给定两个具有a,b和c布尔值的布尔函数f1(a,b)
和f2(a,b,c)
,我想知道是否存在c的值,使得对于et b f1(a,b)=f2(a,b,c)
的任何组合
例如,如果f1(a,b)=a AND b
和f2(a,b,c)=a AND b AND c
,当f1=f2
时,我们可以看到那个c=1
。但是,如果f1(a,b)=a OR b
和f2(a,b,c)=a AND b AND c
,则f1=f2
的c值不成立。
方法失败
我尝试使用在nuXmv中实现的简单模型进行模型检查,以使用诸如EF ( AG ( (a & b) = (a & b & c)))
之类的CTL规范来回答此问题,但是失败了。
显然,它可以与规范AG ( c=true -> (a & b = a & b & c))
配合使用,但是它必须具有2 ^ n个规范(n是两个函数之间的变量数之差)。
您认为解决该问题的最佳方法/工具/方法是什么?
感谢您指向正确的方向。
答案 0 :(得分:1)
如果我为此任务使用nuXmv
,我将编写以下模型
MODULE main
VAR
a : boolean;
b : boolean;
c : boolean;
CTLSPEC ((a & b) = (a & b & c));
,然后从状态空间中逐步删除该属性被伪造的所有那些状态。例如,鉴于此:
nuXmv > reset; read_model -i test.smv ; go ; check_property
-- specification (a & b) = ((a & b) & c) is false
-- as demonstrated by the following execution sequence
Trace Description: CTL Counterexample
Trace Type: Counterexample
-> State: 1.1 <-
a = TRUE
b = TRUE
c = FALSE
然后我会这样写(因为c
是唯一受监视的变量):
MODULE main
VAR
a : boolean;
b : boolean;
c : boolean;
INVAR
c != FALSE;
CTLSPEC ((a & b) = (a & b & c));
实际上将停止迭代优化搜索,因为现在在a
和b
的所有可能评估下,该属性为true:
nuXmv > reset; read_model -i test.smv ; go ; check_property
-- specification (a & b) = ((a & b) & c) is true
现在,这似乎不是理想的解决方案,因为它需要解析nuXmv
的输出并相应地修改原始文件。与您的方法(该方法检查所有可能的值分配)相比,此方法仅枚举使公式无法满足要求的那些分配。尽管如此,反例仍可能呈指数级增长,因此改进并不多。
一种替代方法是在 EUF 公式(包括f1
和{{1的定义)上对通用量化使用 SMT }},其中唯一的自由变量是f2
:
c
这为您提供了带有 SMT 求解器(define-fun f1 ((a Bool) (b Bool)) Bool
(and a b)
)
(define-fun f2 ((a Bool) (b Bool) (c Bool)) Bool
(and a b c)
)
(declare-fun c () Bool)
(assert (forall
((a Bool) (b Bool))
(=
(f1 a b)
(f2 a b c)
)
))
(check-sat)
(get-model)
的以下模型:
z3
如果您想知道~$ z3 test3.smt2
sat
(model
(define-fun c () Bool
true)
)
的所有{strong>所有可能的c
值,那么最好的办法就是实施增量allsat 在f1 = f2
顶部进行搜索(请参阅:有关该主题的stackoverflow的大量问题,请点击此处。