Problems with user defined z3 sorts - z3

I'm trying to define a new fraction sort in z3 to gain a better understanding of how z3 works. I'm using this query and define equality between two fractions:
;;;;;;;;;;;;;;;;;;;
;; TEMPLATE CTOR ;;
;;;;;;;;;;;;;;;;;;;
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
;;;;;;;;;;;;;;;;;;;;;;
;; SORT DEFINITIONS ;;
;;;;;;;;;;;;;;;;;;;;;;
(define-sort Fraction () (Pair Int Int))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FUNCTION DEFINITIONS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-fun Fraction_Eq ((f1 Fraction) (f2 Fraction)) Bool
(if (= (* (first f1) (second f2))
(* (first f2) (second f1)))
true
false
)
)
(declare-const x1 Fraction)
(declare-const x2 Fraction)
(declare-const x3 Fraction)
(assert (Fraction_Eq x1 (mk-pair 3 5)))
(assert (Fraction_Eq x2 (mk-pair 4 7)))
(assert (Fraction_Eq x3 (mk-pair 8 9)))
(check-sat)
(get-value (x1 x2 x3))
I expect that x1 will be equal to 3/5 but it isn't. Here is the answer I get:
sat
((x1 (mk-pair 0 0))
(x2 (mk-pair 1304 2282))
(x3 (mk-pair 0 0)))
Can anyone please help? Thanks!

The equation
n * 5 = d * 3
is perfectly satisfied by n = d = 0.
Since division by zero has no meaning in ordinary arithmetic, you should enrich your statement and require d being different from 0.
Note that this does not guarantee n, d to be equal to 3, 5, since there are an infinite number of solutions to that equation. The normalised value of x1, however, should correspond to 3/5.
Here is the way to fix it:
;;;;;;;;;;;;;;;;;;;
;; TEMPLATE CTOR ;;
;;;;;;;;;;;;;;;;;;;
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
;;;;;;;;;;;;;;;;;;;;;;
;; SORT DEFINITIONS ;;
;;;;;;;;;;;;;;;;;;;;;;
(define-sort Fraction () (Pair Int Int))
;;;;;;;;;;;;;;;;;;;;;;;;;;
;; FUNCTION DEFINITIONS ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-fun Fraction_Eq ((f1 Fraction) (f2 Fraction)) Bool
(if (= (* (first f1) (second f2))
(* (first f2) (second f1)))
true
false
)
)
(define-fun Fraction_Valid ((f1 Fraction)) Bool
(not (= 0 (second f1)))
)
(declare-const x1 Fraction)
(declare-const x2 Fraction)
(declare-const x3 Fraction)
(assert (Fraction_Valid x1))
(assert (Fraction_Valid x2))
(assert (Fraction_Valid x3))
(assert (Fraction_Eq x1 (mk-pair 3 5)))
(assert (Fraction_Eq x2 (mk-pair 4 7)))
(assert (Fraction_Eq x3 (mk-pair 8 9)))
(check-sat)
(get-value (x1 x2 x3))
With the result:
sat
((x1 (mk-pair 3 5))
(x2 (mk-pair 4 7))
(x3 (mk-pair (- 8) (- 9))))
The newly-introduced Fraction_Valid SmtLibv2 predicate should prevent any fraction, on which it is applied, from having a denominator equal to zero.

Related

Having assertions inside definitions in SMT

I want to capture the assertion inside fac.
int f( x )
{
if( x == 1) return 1;
else{
assert( x > 0 );
return 2;
}
}
int g (x)
{ assert( x > 5 );
return f(x-1) + f(x-2);
}
I want an smt2 code for this.
I can do this by striping the argument and making it global with unique name (also rename inside f), then do this 3 times each with a different name for function. Like below :
( declare-const x1 Int )
(define-fun f1 () Int
( ite ( x1 > 0) 1 2 )
)
(assert (> x1 0))
( declare-const x2 Int )
(define-fun f2 () Int
( ite ( x2 > 0) 1 2 )
)
(assert (> x2 0))
( declare-const x3 Int )
(define-fun g1 () Int
( + f1 f2 )
)
(assert (> x3 5))
I don't want to this. Is there any other way to do this without repeating ?
EDIT
My purpose is to find values violating the asserts.
As far as I know, it is not possible to embed assertions within function definitions.
What I would try to do is to separate the expected behavior, the input assumptions and the output guarantees (if any).
Example:
(define-fun f ((x Int)) Int
(ite (= x 1) 1 2)
)
(define-fun f-helper ((x Int)) Bool
(< 0 x)
)
(define-fun g ((x Int)) Int
(+ (f (- x 1)) (f (- x 2)))
)
(define-fun g-helper ((x Int)) Bool
(and (< 5 x)
(f-helper (- x 1))
(f-helper (- x 2))
)
)
(declare-const x Int)
(declare-const y Int)
(assert (and (= y (g x))
(g-helper x)
))
(check-sat)
(get-model)
In this example we use f to model the behavior of the original function f, and f-helper to model the assumptions of f. The output, using the online Z3 tool, is as follows:
sat
(model
(define-fun x () Int
6)
(define-fun y () Int
4)
)
I would conclude saying that this approach could become tricky as soon as f and g are used inside both positive and negative contexts.. in this case one should pay extra attention that the polarity of the assertions is correct wrt. the expected result.

trying an example from rise4fun / z3 / tutorial / strategies

some example from the rise4fun-site:
(declare-const x Int)
(declare-const y Int)
(declare-const z Int)
(declare-const a Int) ; this is added
(assert (= a 3 )) ; this is added: a := 3
(assert (< 0 x 10)) ; rewritten, but same constraint
(assert (< 0 y 10))
(assert (< 0 z 10))
(assert (= (+ (* 3 y) (* 2 x)) z)) ; plain function from rise4fun
;(assert (= (+ (* a y) (* 2 x)) z)) ; here literal 3 is replaced by a
(check-sat-using (then (using-params simplify :arith-lhs true :som true)
normalize-bounds
lia2pb
pb2bv
bit-blast
sat))
(get-model)
(get-info :version)
when i comment the plain function from rise4fun and uncomment my function, the solver will fail to produce a result and respond with 'unknown' (tried with 4.8.0). Isn't the solver or some preprocessor smart enough to see that 'a' is just a constant with fixed value 3?
That's right, the simplify tactic is not smart enough to propagate values because it would be too expensive in general. However, ctx-simplify or propagate-values do the job. For instance:
(check-sat-using (then (using-params simplify :arith-lhs true :som true)
propagate-values
normalize-bounds
lia2pb
pb2bv
bit-blast
sat))

z3 times out in case of a formula with quantifiers

I am getting timeout on the following example.
http://rise4fun.com/Z3/zbOcW
Is there any trick to make this work (eg.by reformulating the problem or using triggers)?
For this example, the macro finder will be useful (I think often with forall quantifiers with implications), you can enable it with:
(set-option :macro-finder true)
Here's your updated example that gets sat quickly (rise4fun link: http://rise4fun.com/Z3/Ux7gN ):
(set-option :macro-finder true)
(declare-const a (Array Int Bool))
(declare-const sz Int)
(declare-const n Int)
(declare-const d Int)
(declare-const r Bool)
(declare-const x Int)
(declare-const y Int)
;;ttff
(declare-fun ttff (Int Int Int) Bool)
(assert
(forall ((x1 Int) (y1 Int) (n1 Int))
(= (ttff x1 y1 n1)
(and
(forall ((i Int))
(=> (and (<= x1 i) (< i y1))
(= (select a i) true)))
(forall ((i Int))
(=> (and (<= y1 i) (< i n1))
(= (select a i) false)))))))
;; A1
(assert (and (<= 0 n) (<= n sz)))
;; A2
(assert (< 0 d))
;; A3
(assert (and (and (<= 0 x) (<= x y)) (<= y n)))
;; A4
(assert (ttff x y n))
;; A6
(assert
(=> (< 0 y)
(= (select a (- y 1)) true)))
;; A7
(assert
(=> (< 0 x)
(= (select a (- x 1)) false)))
;;G
(assert
(not
(iff
(and (<= (* 2 d) (+ n 1)) (ttff (- (+ n 1) (* 2 d)) (- (+ n 1) d) (+ n 1)))
(and (= (- (+ n 1) y) d) (<= d (- y x))))))
(check-sat)
(get-model)

Possible bug with Z3: Z3 is not able to prove a theorem in Topology

I am trying to prove with Z3 the theorem in general topology given at
TPTP-Topology
I am translating the code given there using the following Z3-SMT-LIB code
;; File : TOP001-2 : TPTP v6.0.0. Released v1.0.0.
;; Domain : Topology
;; Problem : Topology generated by a basis forms a topological space, part 1
(declare-sort S)
(declare-sort Q)
(declare-sort P)
(declare-fun elemcoll (S Q) Bool)
(declare-fun elemset (P S) Bool)
(declare-fun unionmemb (Q) S)
(declare-fun f1 (Q P) S)
(declare-fun f11 (Q S) P)
(declare-fun basis (S Q) Bool)
(declare-fun Subset (S S) Bool)
(declare-fun topbasis (Q) Q)
;; union of members axiom 1.
(assert (forall ((U P) (Vf Q)) (or (not (elemset U (unionmemb Vf)))
(elemset U (f1 Vf U) ) ) ))
;; union of members axiom 2.
(assert (forall ((U P) (Vf Q)) (or (not (elemset U (unionmemb Vf)))
(elemcoll (f1 Vf U) Vf ) ) ))
;; basis for topology, axiom 28
(assert (forall ((X S) (Vf Q)) (or (not (basis X Vf)) (= (unionmemb Vf) X ) ) ))
;; Topology generated by a basis, axiom 40.
(assert (forall ((Vf Q) (U S)) (or (elemcoll U (topbasis Vf))
(elemset (f11 Vf U) U)) ))
;; Set theory, axiom 7.
(assert (forall ((X S) (Y Q)) (or (not (elemcoll X Y)) (Subset X (unionmemb Y) ) ) ))
;; Set theory, axiom 8.
(assert (forall ((X S) (Y S) (U P)) (or (not (Subset X Y)) (not (elemset U X))
(elemset U Y) )))
;; Set theory, axiom 9.
(assert (forall ((X S)) (Subset X X ) ))
;; Set theory, axiom 10.
(assert (forall ((X S) (Y S) (Z S)) (or (not (= X Y)) (not (Subset Z X)) (Subset Z Y) ) ))
;; Set theory, axiom 11.
(assert (forall ((X S) (Y S) (Z S)) (or (not (= X Y)) (not (Subset X Z)) (Subset Y Z) ) ))
(check-sat)
(push)
(declare-fun cx () S)
(declare-fun f () Q)
(assert (basis cx f))
(assert (not (elemcoll cx (topbasis f))))
(check-sat)
(pop)
(push)
(assert (basis cx f))
(assert (elemcoll cx (topbasis f)))
(check-sat)
(pop)
The corresponding output is
sat
sat
sat
Please run this example online here
The first sat is correct; but the second sat is wrong, it must be unsat. In other words, Z3 is saying that the theorem and its negation are true simultaneously.
Please let me know what happens in this case. Many thanks. All the best.
It is possible that both a formula and the negation of the formula is consistent with respect to a background theory T. In particular, when T is not complete, then there are sentences that are neither consequences of T nor inconsistent with T. In your case the theory T is the set of topology axioms.
You can use the command (get-model) to obtain a model that satisfies the axioms and the sentence.

How to compute with Inductive datatypes using Yices and Z3-SMT-LIB

A simple example of computation with inductive datatypes using Yices is:
(define-type T (datatype c1
c2
(c3 val::bool)))
(define x1::T)
(define x2::T)
(assert (/= x1 x2))
(check)
and the corresponding output is:
sat
(= x1 c1)
(= (c3 false) x2)
This example is solved using Z3-SMT-LIB using the following code
(declare-datatypes () ((T c1 ( c3 (T Bool)))))
(declare-fun x1 () T)
(declare-fun x2 () T)
(assert (not (= x2 x1)))
(check-sat)
(get-model)
and the corresponding output is
sat
(model
(define-fun x2 () T (c3 false))
(define-fun x1 () T c1)
)
Run this example online here
As it is observed Yices and Z3 produce the same results.
Other example:
Yices:
(define-type T (datatype c1
c2
(c3 val::bool)))
(define x1::T)
(define x2::T)
(define x3::T)
(define x4::T)
(assert (/= x1 x2))
(assert (/= x1 x3))
(assert (/= x1 x4))
(assert (/= x2 x3))
(assert (/= x2 x4))
(assert (/= x3 x4))
(check)
sat
(= x1 c1)
(= x3 c2)
(= (c3 false) x4)
(= (c3 true) x2)
Z3:
(declare-datatypes () ((T c1 c2 ( c3 (T Bool)))))
(declare-fun x1 () T)
(declare-fun x2 () T)
(declare-fun x3 () T)
(declare-fun x4 () T)
(assert (not (= x4 x3)))
(assert (not (= x4 x2)))
(assert (not (= x4 x1)))
(assert (not (= x3 x2)))
(assert (not (= x3 x1)))
(assert (not (= x2 x1)))
(check-sat)
(get-model)
sat
(model
(define-fun x3 () T c2)
(define-fun x2 () T (c3 false))
(define-fun x1 () T c1)
(define-fun x4 () T (c3 true))
)
Run this example online here
As it is observed in this example Yices and Z3 produce different results.
Other example: Natural numbers as an inductive type:
Yices
(define-type Nat (datatype zero
(succ val::Nat)))
(define x1::Nat)
(define x2::Nat)
(define x3::Nat)
(assert (/= x1 x2))
(assert (/= x1 x3))
(assert (/= x2 x3))
(check)
sat
(= zero x1)
(= (succ x2) x3)
(= (succ x1) x2)
Z3
(declare-datatypes () ((Nat zero (succ (Nat Nat)))))
(declare-fun x1 () Nat)
(declare-fun x2 () Nat)
(declare-fun x3 () Nat)
(assert (not (= x1 x2)))
(assert (not (= x1 x3)))
(assert (not (= x2 x3)))
(check-sat)
(get-model)
sat
(model
(define-fun x3 () Nat (succ (succ (succ zero))))
(define-fun x2 () Nat (succ zero))
(define-fun x1 () Nat zero)
)
Run this example online here
As it is observed in this example Yices and Z3 produce different results.
The questions are;
How to write the Z3 code with the aim to obtain the same results that are obtained with Yices.
How to obtain all possible models using both Z3 and Yices.
Your example has an infinite number of models.
Z3 and Yices produce different models, but the solutions produced by both of them are correct.
Z3 and Yices use slightly different decision procedures for inductive datatypes. This is why they produce different models. There is no way to force them to always produce the same solution for an input set of assertions that has more than one model.
Regarding enumerating all possible models, we can use the Z3 API. See this post:
Z3: finding all satisfying models

Resources