4

Wherefore?

The usecase context in which my problem occures

I define 3 random item of a triangle. Microsoft Z3 should output:

  • Are the constraints satisfiabe or are there invalid input values?
  • A model for all the other triangle items where all the variables are assigned to concrete values.

In order to constrain the items i need to assert triangle equalities - i wanted to start out with the Pythagorean Theorem ((h_c² + p² = b²) ^ (h_c² + q² = a²)).

The Problem

I know that Microsoft Z3 has only limited capabilities to solve non-linear arithematic problems. But even some hand calculators are able to solve a very simplified version like this:

(set-option :print-success true)
(set-option :produce-proofs true)
(declare-const a Real)
(declare-const b Real)
(assert (= a 1.0))
(assert (= b 1.0))
(assert
    (exists
        ((c Real))
        (=
            (+
                (* a a)
                (* b b)
            )
            (* c c)
        )
    )
)
(check-sat)
(get-model)

The Question

  • Is there a way to get Microsoft Z3 to solve the Pythagorean Theorem if two values are given?
  • Or: Is there another theorem prover which is able to handle these case of non-linear arithmetic?

Thanks for your help concerning that - If anything is unclear, please comment.

fdj815
  • 569
  • 1
  • 7
  • 15
  • The [duplicate](http://stackoverflow.com/questions/15115183) was created because a moderator migrated that question to StackOverflow, even if I already recreated it on StackOverflow - I never wanted that to happen. – fdj815 Feb 27 '13 at 20:22

1 Answers1

4

Z3 has a new solver (nlsat) for nonlinear arithmetic. It is more efficient than other solvers (see this article). The new solver is complete for quantifier-free problems. However, the new solver does not support proof generation. If we disable proof generation, then Z3 will use nlsat and easily solve the problem. Based on your question, it seems you are really looking for solutions, thus disabling proof generation does not seem to be an issue.

Moreover, Z3 does not produce approximate solutions (like hand calculators). It uses a precise representation for real algebraic numbers. We can also ask Z3 to display the result in decimal notation (option :pp-decimal). Here is your example online.

In this example, when precise representation is used, Z3 will display the following result for c.

(root-obj (+ (^ x 2) (- 2)) 1)

It is saying that c is the first root of the polynomial x^2 - 2. When we use (set-option :pp-decimal true), it will display

(- 1.4142135623?)

The question mark is used to indicate the result is truncated. Note that, the result is negative. However, it is indeed a solution for the problem you posted. Since, you are looking for triangles, you should assert that the constants are all > 0.

BTW, you do not need the existential quantifier. We can simply use a constant c. Here is an example (also available online at rise4fun):

(set-option :pp-decimal true)
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)
(assert (= a 1.0))
(assert (= b 1.0))
(assert (> c 0))
(assert (= (+ (* a a) (* b b)) (* c c)))
(check-sat)
(get-model)

Here is another example that does not have a solution (also available online at rise4fun):

(set-option :pp-decimal true)
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)
(assert (> c 0))
(assert (> a c))
(assert (= (+ (* a a) (* b b)) (* c c)))
(check-sat)

BTW, you should consider the Python interface for Z3. It is much more user friendly. The tutorial that I linked has examples in Kinematics. They also use nonlinear arithmetic to encode simple high-school physics problems.

Leonardo de Moura
  • 21,065
  • 2
  • 47
  • 53
  • I never wanted to express that hand calculators are able to do more things than Z3. I just wanted to reveal that it's a very simple usecase and that there just has to be a way to do that. – fdj815 Feb 27 '13 at 20:27
  • 2
    I understand. No problem. In my post, I tried to make the point that your example is not as simple as you think. Most SMT solvers cannot handle this problem, since they cannot even represent the solution precisely. Z3 without nlsat can't solve it. The hand calculator also does not really solve the problem, it just computes an approximated "solution". Suppose we also assert `(assert (= c 1.4142135623))`, is the problem still satisfiable? No, it is not. However, if we use approximations, we may incorrectly say it is. http://rise4fun.com/Z3/JWYC – Leonardo de Moura Feb 28 '13 at 00:26
  • 1
    When my script's ready it should support more `assert`s than just the Pythagorean Theorem. I can do without a real proof, but I really need to know which formulas are used. For example: `Right triangle`: `a`, `b` are given, `c` is in demand - the script should output that the formula `(= (+ (* a a) (* b b)) (* c c))` was used in order to compute `c`. Is something like that possible using `nlsat`? – fdj815 Feb 28 '13 at 08:46
  • 3
    Suppose we have `N` assertions. When nlsat returns `sat`, it means it managed to find a solution that makes *all* these assertions true. The solution contains a value for `c` and for all other constants in the problem. So, in principle, it used *all* constraints to find a solution for `c` and any other constant in the problem. If we have assertions such as `(or C1 C2)`, we can ask whether it is true because nlsat made `C1` or `C2` true. – Leonardo de Moura Feb 28 '13 at 15:52
  • Thanks for your help concerning this question. - I'll accept your answer here and I hope that there'll be also a fine solution for my [formula problem](http://stackoverflow.com/q/15145189) (which I migrated to a new thread). – fdj815 Feb 28 '13 at 20:42
  • Of course every sensible constrain constrains the set of solutions. - In the new thread I tried to describe more exactly which formulas I am interested in. – fdj815 Feb 28 '13 at 20:45