The SMT program further down encodes the (ill-defined) function definition ∀ s · wild(s) = 1 + wild(s)
in a slightly roundabout way (applying Dafny's "limited functions" encoding of recursive functions) and then attempts to prove that wild(emp) = 1 + wild(emp)
. However, Z3 4.6.0 (and also a recent 4.7.0 nightly) unexpectedly yield unknown
instead of unsat
.
(set-option :auto_config false) ;; true -> no change in behaviour
(set-option :smt.mbqi false) ;; true -> no change in behaviour
(declare-sort Snap) ;; In the full example, this is ...
(declare-const emp Snap) ;; ... declared using declare-datatypes
(declare-fun wild (Snap) Int)
(declare-fun wild%limited (Snap) Int)
(assert (forall ((s Snap)) (! ;; AX-1
(= (wild%limited s) (wild s))
:pattern ((wild s))
)))
(assert (forall ((s Snap)) (! ;; AX-2
(=
(wild s)
(+ 1 (wild%limited emp)))
:pattern ((wild s))
)))
(push) ;; Full examples uses incremental mode
(assert
(not
(=
(wild emp)
(+ 1 (wild emp)))))
(check-sat) ;; UNKNOWN --- but why?
(pop)
Given my understanding of Z3 and triggers, I would expect the following proof steps to happen:
¬(wild(emp) = 1 + wild(emp)) // Source assertion
≡ ¬(1 + wild%limited(emp) = 1 + wild(emp)) // By AX-2
≡ ¬(1 + wild%limited(emp) = 1 + wild%limited(emp)) // By AX-1
≡ ¬(true) // Done: UNSAT
But that doesn't appear to happen. My guess is that the axioms aren't instantiated — and indeed, get-info :all-statistics
reports no quantified instantiation.
Can anybody shed some light on this?