当选择量化假设的实例化(没有mbqi)时,Z3搜索其可能匹配的地面项(模数均衡)的电子图。我知道这个电子图包含原始问题中存在的基础术语,以及在证明搜索期间形成的术语。然而,似乎在量词之下提到的基础术语不被用作匹配的候选者,直到周围的量词本身被实例化。
例如,如果我写:
(assert
(forall ((n Int) ) (!
(and (f 0) (g n))
:pattern ((g n))
)))
(assert (forall ((n Int) ) (!
(not (= (h n) n))
:pattern ((f n))
)))
(assert (= (h 0) 0))
(check-sat)
然后Z3报告未知。然而,如果我将(f 0)的连接拉出forall(如下面的完整示例所示),那么Z3报告不满(如果我跟踪统计数据,我可以看到第二个量词被实例化。
我发现这种行为有点令人困惑,我想知道它是否有意?如果是这样,这个选择背后的理由是什么?我认为这可能会影响我们的一些公理化(但需要进一步调试细节)。
顺便说一句,我们尝试使用let表达式从量词中拉出基础术语,但是(可能是因为让表达式再次被替换回来?)我们没有看到差异。
示例的完整版本在这里:
(set-option :print-success true) ; Boogie: false
(set-option :global-decls true) ; Boogie: default
(set-option :auto_config false) ; Usually a good idea
(set-option :smt.mbqi false)
(set-option :model.v2 true)
(set-option :smt.phase_selection 0)
(set-option :smt.restart_strategy 0)
(set-option :smt.restart_factor |1.5|)
(set-option :smt.arith.random_initial_value true)
(set-option :smt.case_split 5)
(set-option :smt.delay_units true)
(set-option :smt.delay_units_threshold 16)
(set-option :nnf.sk_hack true)
(set-option :smt.qi.eager_threshold 100)
(set-option :smt.qi.cost "(+ weight generation)")
(set-option :type_check true)
(set-option :smt.bv.reflect true)
(set-option :smt.qi.profile true)
(declare-fun f (Int) Bool)
(declare-fun g (Int) Bool)
(declare-fun h (Int) Int)
(assert
(forall ((n Int) ) (!
(and (f 0) (g n))
:pattern ((g n))
)))
; this version of the above axiom lets us get "unsat"
;(assert
; (and (f 0) (forall ((n Int) ) (!
; (g n)
; :pattern ((g n)))
; )))
(assert (forall ((n Int) ) (!
(not (= (h n) n))
:pattern ((f n))
)))
(assert (= (h 0) 0))
(check-sat)
(get-info :all-statistics)