Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does 0 = 0.5?

Tags:

z3

I noticed some strange behavior with Z3 4.3.1 when working with .smt2 files.

If I do (assert (= 0 0.5)) it will be satisfiable. However, if I switch the order and do (assert (= 0.5 0)) it's not satisfiable.

My guess as to what is happening is that if the first parameter is an integer, it casts both of them to integers (rounding 0.5 down to 0), then does the comparison. If I change "0" to "0.0" it works as expected. This is in contrast to most programming languages I've worked with where if either of the parameters is a floating-point number, they are both cast to floating-point numbers and compared. Is this really the expected behavior in Z3?

like image 824
Stanley Bak Avatar asked Jul 16 '14 20:07

Stanley Bak


People also ask

What does a 0 0.5 bet mean?

This means that with a handicap point of 0-0.5 or 0 and ½, half of your stake is on the 0 point handicap and the other half is on the 0.5 handicap. Example: Match: Everton v. Newcastle Line: Everton -1.75. Let's say you bet $100 on Everton -1.75 at odds 2.29.

What is the meaning of +0.5 handicap?

Asian handicap +0.5 indicates that the underdog receives a half goal head start, while -0.5 means that the favourite team starts with a half goal down. The head start or disadvantage will be included in the final score, which determines the result of your bet. Betting on a particular team is not enough for you to win.

What does a 0.0 spread mean in soccer?

A PK or pick'em in soccer betting is essentially a point spread in which neither team is getting any points. It's also sometimes shown as +0 or -0. If the team you bet at a PK wins, you win your bet. If the match ends in a draw, your bet is refunded, because it's considered a push at +0 or -0 on the spread.

What does handicap on a team mean?

Handicap betting, also called “point betting,” or “line betting,” is used to even out the playing field between two teams who are not evenly matched. The bookmaker gives a virtual advantage to the weaker team, and a virtual disadvantage to the stronger side.


2 Answers

I think this is a consequence of lack of type-checking; z3 is being too lenient. It should simply reject such queries as they are simply not well formed.

According to the SMT-Lib standard, v2 (http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.0-r10.12.21.pdf); page 30; the core theory is defined thusly:

(theory Core
:sorts ((Bool 0))
:funs ((true Bool) (false Bool) (not Bool Bool)
      (=> Bool Bool Bool :right-assoc) (and Bool Bool Bool :left-assoc)
      (or Bool Bool Bool :left-assoc) (xor Bool Bool Bool :left-assoc)
      (par (A) (= A A Bool :chainable))
      (par (A) (distinct A A Bool :pairwise))
      (par (A) (ite Bool A A A))
      )
:definition
"For every expanded signature Sigma, the instance of Core with that signature
is the theory consisting of all Sigma-models in which:
  - the sort Bool denotes the set {true, false} of Boolean values;
  - for all sorts s in Sigma,
       - (= s s Bool) denotes the function that
         returns true iff its two arguments are identical;
       - (distinct s s Bool) denotes the function that
         returns true iff its two arguments are not identical;
       - (ite Bool s s) denotes the function that
         returns its second argument or its third depending on whether
         its first argument is true or not;
       - the other function symbols of Core denote the standard Boolean operators
         as expected.
       "
  :values "The set of values for the sort Bool is {true, false}."
)

So, by definition equality requires the input sorts to be the same; and hence the aforementioned query should be rejected as invalid.

There might be a switch to z3 or some other setting that forces more strict type-checking than it does by default; but I would've expected this case to be caught even with the most relaxed of the implementations.

like image 137
alias Avatar answered Oct 13 '22 07:10

alias


Do not rely on the implicit type conversion of any solver. Instead, use to_real and to_int to do explicit type conversions. Only send well-typed formulas to the solver. Then Mohamed Iguernelala's examples become the following.

(set-logic AUFLIRA)
(declare-fun x () Int)
(assert (= (to_real x) 1.5))
(check-sat)
(exit)

(set-logic AUFLIRA)
(declare-fun x () Int)
(assert (= 1.5 (to_real x)))
(check-sat)
(exit)

Both of these return UNSAT in Z3 and CVC4. If instead, you really wanted to find the model where x = 1 you should have instead used one of the following.

(set-option :produce-models true)
(set-logic AUFLIRA)
(declare-fun x () Int)
(assert (= (to_int 1.5) x))
(check-sat)
(get-model)
(exit)

(set-option :produce-models true)
(set-logic AUFLIRA)
(declare-fun x () Int)
(assert (= x (to_int 1.5)))
(check-sat)
(get-model)
(exit)

Both of these return SAT with x = 1 in Z3 and CVC4.

Once you make all the type conversions explicit and deal only in well-typed formulas, the order of arguments to equality no longer matters (for correctness).

like image 4
Andrew Gacek Avatar answered Oct 13 '22 08:10

Andrew Gacek