How I can write sqrt function in smt-libv2 format.
Note: To get a maximum of two values, i found a useful link here: Use Z3 and SMT-LIB to get a maximum of two values.
If you don't actually need a function, then the simplest way to define y as the square-root of x is to assert that y * y = x, i.e.:
; This will cause Z3 to return a decimal answer instead of a root-obj
(set-option :pp.decimal true)
; Option 1: inverse of multiplication. This works fine if you don't actually
; need to define a custom function. This will find y = 1.414... or y = -1.414...
(declare-fun y () Real)
(assert (= 2.0 (* y y)))
; Do this if you want to find the positive root y = 1.414...
(assert (>= y 0.0))
(check-sat)
(get-value (y))
(reset)
Another way I tried using uninterpreted functions is like this:
; Option 2: uninterpreted functions. Unfortunately Z3 seems to always return
; 'unknown' when sqrt is defined this way. Here we ignore the possibility that
; x < 0.0; fixing this doesn't help the situation, though.
(declare-fun sqrt (Real) Real)
(assert (forall ((x Real)) (= x (* (sqrt x) (sqrt x)))))
(declare-fun y () Real)
(assert (= y (sqrt 2.0)))
(check-sat)
(reset)
Finally, by far the easiest if you're using Z3 is to use the built-in power operator as suggested by Nikolaj. You can a function based around that idea:
; Option 3: built-in power operator. This is not standard SMT-LIB, but works
; well with Z3.
(define-fun sqrt ((x Real)) Real (^ x 0.5))
(declare-fun y () Real)
(assert (= y (sqrt 2.0)))
(check-sat)
(get-value (y))
(reset)
Nikolaj's idea of defining a function is_sqrt
is also an interesting idea and has the advantage that it is quantifier-free, so it will work with nlsat (the most powerful nonlinear solver in Z3).