我有(t>=0 or t>=1)
和(t<=2 or t>=2)
这样的约束,实际上约束可以简化为“t>=0
”,如何使用z3通过使用获得CNF形式的简化结果Z3?
(declare-const t Int)
(assert (and
(or
(>= t 0)
(>= t 1)
)
(or
(>= t 2)
(<= t 2)
)
(>= t 0)
(<= t 1)
)
)
(apply (par-then (! simplify :elim-and true) tseitin-cnf))
但是,脚本不起作用。
答案 0 :(得分:3)
simplify
策略只执行“本地简化”。也就是说,在简化表达式t
时,它将忽略t
的上下文。例如,它可以将a + 1 - a
简化为1
,但不会将a != 0 or b = a + 1
简化为a != 0 or b = 1
。
上下文简化是昂贵的,simplify
策略意味着高效和简单。其他策略可用于实现您的目标。
战术propagate-ineqs
将传播不平等。但是,它不会处理嵌套在公式中的术语。策略split-clause
可用于打破案例\目标中的公式。策略propagate-values
将传播断言的值,例如:a = 0 and b >= a
简化为a = 0 and b >= 0
。
命令(help-tactic)
将显示所有可用的策略。
以下是将您的示例简化为t >= 0 and t <= 1
的策略。
(apply (then simplify propagate-values split-clause propagate-ineqs))
请注意,组合子par-then
仅用于组合产生许多子目标的策略。
(par-then t1 t2)
将t1
应用于输入目标,并将t2
(并行)应用于t1
生成的每个子目标。 split-clause
战术产生不止一个子目标。然后(对于更大的例子)使用它可能更有效:
(apply (then simplify propagate-values (par-then split-clause propagate-ineqs)))