Z3 OCaml API Recursive Function - api

Let's say I want to check if the formula x+y=z (x,y,z integers) is satisfiable. Using Z3 i could input something like:
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (= z (+ x y)))
(check-sat)
I could equivalently use the OCaml api and write the following code:
let ctx=Z3.mk_context [("model", "true"); ("proof", "false")] in
let v1=(Z3.Arithmetic.Integer.mk_const_s ctx "x") in
let v2=(Z3.Arithmetic.Integer.mk_const_s ctx "y") in
let res=(Z3.Arithmetic.Integer.mk_const_s ctx "z") in
let sum=Z3.Arithmetic.mk_add ctx [ v1 ; v2] in
let phi=Z3.Boolean.mk_eq ctx sum res in
let solver = (Z3.Solver.mk_solver ctx None) in
let _= Z3.Solver.add solver [phi] in
let is_sat=Z3.Solver.check solver [] in
match is_sat with
| UNSATISFIABLE -> Printf.printf "unsat";
| SATISFIABLE -> Printf.printf "sat";
| UNKNOWN -> Printf.printf "unknown";
I would like to use the ocaml api of z3 to check the satisfiability of
the following factorial implementation, so that I get a value for x (if it exists).
(declare-fun x () Int)
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(* (f (- x 1))
x)
1))
(assert (= x (f 10)))
(check-sat)
(get-model)
Unfortunately, I can't find an example of recursive definitions using the ml api of z3.

Related

Not able to call function with two return variables

Code snippet
I'm new to Kotlin, I have successfully called a function returning two variables else where in my code but it give an error when used as shown. Everything worked until I decided I wanted to return two variables. I can get it to work if I use if then statements but that isn't as clean. Is there a way to do this using a lambda? It tells me the first value is expression unused and the second that a boolean is expected.
fun block (puzzle: Array<IntArray>, x:Int, y:Int): Pair<MutableList<Int>, MutableSet<Int>> {
var blockNums: MutableList<Int> = mutableListOf()
var blockNumsFinal: MutableSet<Int> = mutableSetOf()
when {
((x in 0..2) and (y in 0..2)) -> (blockNums, blockNumsFinal) = getBlock1(puzzle, x, y)
((x in 3..5) and (y in 0..2)) -> blockNums = getBlock2(puzzle, x, y)
((x in 6..8) and (y in 0..2)) -> blockNums = getBlock3(puzzle, x, y)
((x in 0..2) and (y in 3..5)) -> blockNums = getBlock4(puzzle, x, y)
((x in 3..5) and (y in 3..5)) -> blockNums = getBlock5(puzzle, x, y)
((x in 6..8) and (y in 3..5)) -> blockNums = getBlock6(puzzle, x, y)
((x in 0..2) and (y in 6..8)) -> blockNums = getBlock7(puzzle, x, y)
((x in 3..5) and (y in 6..8)) -> blockNums = getBlock8(puzzle, x, y)
((x in 6..8) and (y in 6..8)) -> blockNums = getBlock9(puzzle, x, y)
}
return Pair(blockNums, blockNumsFinal)
}
I have found no answers in my google searches.
This:
(blockNums, blockNumsFinal) =
looks like you're trying to use a destructuring declaration syntax for variables that are already declared. This is not allowed. You can only use it for declarations (hence the name).
Since your other function evidently already returns a pair, this should work, but I'm guessing because I'm not sure of the return types of your other functions.
You're also misusing the and infix function. It is intended for bitwise comparisons. When used with Boolean expressions, it prevents early-exiting of the total expression, which means if the first expression is false, it still redundantly calculates the second expression. Not what you want here. You should use && here.
fun block (puzzle: Array<IntArray>, x:Int, y:Int): Pair<MutableList<Int>, MutableSet<Int>> {
return when {
((x in 0..2) && (y in 0..2)) -> getBlock1(puzzle, x, y)
((x in 3..5) && (y in 0..2)) -> getBlock2(puzzle, x, y)
((x in 6..8) && (y in 0..2)) -> getBlock3(puzzle, x, y)
((x in 0..2) && (y in 3..5)) -> getBlock4(puzzle, x, y)
((x in 3..5) && (y in 3..5)) -> getBlock5(puzzle, x, y)
((x in 6..8) && (y in 3..5)) -> getBlock6(puzzle, x, y)
((x in 0..2) && (y in 6..8)) -> getBlock7(puzzle, x, y)
((x in 3..5) && (y in 6..8)) -> getBlock8(puzzle, x, y)
((x in 6..8) && (y in 6..8)) -> getBlock9(puzzle, x, y)
else -> Pair(mutableListOf(), mutableSetOf())
}
}
About the syntax you were trying to use, that would be called "destructuring assignment" if it existed. There's a feature request on the Kotlin YouTrack page for it.

How can I use a proof I've made in Idris to inform the compiler that my type signature is correct?

I have a function count in idris, defined as :
count : Eq a => a -> Vect n a -> Nat
count x [] = Z
count x (y::ys) = with (x == y)
| True = S (count x ys)
| False = count x ys
And a proof of the maximum value count can return:
countLTELen : Eq a => (x : a) -> (l : Vect n a) -> LTE (count x l) n
countLTELen x [] = lteRefl
countLteLen x (y::ys) with (x == y)
| True = LTESucc (countLTELen x ys)
| False = lteSuccRight (countLTELen x ys)
which is all well and good. I now want to write a function which removes all of an element from a list, removeAll :
removeAll : Eq a => (x : a) -> (l : Vect n a) -> Vect (n - (count x l)) a
removeAll x [] = []
removeAll x (y::ys) with (x == y)
| True = removeAll x ys
| False = x :: removeAll x ys
But this definition gives an error:
|
56 | removeAll : Eq a => (x : a) -> (l : Vect n a) -> Vect (n - (count x l)) a
| ^
When checking type of Proof.removeAll:
When checking argument smaller to function Prelude.Nat.-:
Can't find a value of type
LTE (count a n constraint x l) n
How can I use my proof to inform Idris that this type signature is correct?
Right now, Idris can't find the proof {auto smaller : LTE n m} for (-).
So either you need to be explicit:
removeAll : Eq a => (x : a) -> (l : Vect n a) ->
Vect ((-) {smaller=countLTELen x l} n (count x l) ) a
Or, because smaller is an auto-argument, you can hint the compiler to your proof function. Then this function will be tried when auto-finding a value for LTE (count x l) n.
%hint
countLTELen : Eq a => (x : a) -> (l : Vect n a) -> LTE (count x l) n

Proving theorems about functions with cases

Let's say we have a function merge that, well, just merges two lists:
Order : Type -> Type
Order a = a -> a -> Bool
merge : (f : Order a) -> (xs : List a) -> (ys : List a) -> List a
merge f xs [] = xs
merge f [] ys = ys
merge f (x :: xs) (y :: ys) = case x `f` y of
True => x :: merge f xs (y :: ys)
False => y :: merge f (x :: xs) ys
and we'd like to prove something clever about it, for instance, that merging two non-empty lists produces a non-empty list:
mergePreservesNonEmpty : (f : Order a) ->
(xs : List a) -> (ys : List a) ->
{auto xsok : NonEmpty xs} -> {auto ysok : NonEmpty ys} ->
NonEmpty (merge f xs ys)
mergePreservesNonEmpty f (x :: xs) (y :: ys) = ?wut
Inspecting the type of the hole wut gives us
wut : NonEmpty (case f x y of True => x :: merge f xs (y :: ys) False => y :: merge f (x :: xs) ys)
Makes sense so far! So let's proceed and case-split as this type suggests:
mergePreservesNonEmpty f (x :: xs) (y :: ys) = case x `f` y of
True => ?wut_1
False => ?wut_2
It seems reasonable to hope that the types of wut_1 and wut_2 would match the corresponding branches of merge's case expression (so wut_1 would be something like NonEmpty (x :: merge f xs (y :: ys)), which can be instantly satisfied), but our hopes fail: the types are the same as for the original wut.
Indeed, the only way seems to be to use a with-clause:
mergePreservesNonEmpty f (x :: xs) (y :: ys) with (x `f` y)
mergePreservesNonEmpty f (x :: xs) (y :: ys) | True = ?wut_1
mergePreservesNonEmpty f (x :: xs) (y :: ys) | False = ?wut_2
In this case the types would be as expected, but this leads to repeating the function arguments for every with branch (and things get worse once with gets nested), plus with doesn't seem to play nice with implicit arguments (but that's probably worth a question on its own).
So, why doesn't case help here, are there any reasons besides purely implementation-wise behind not matching its behaviour with that of with, and are there any other ways to write this proof?
The stuff to the left of the | is only necessary if the new information somehow propagates backwards to the arguments.
mergePreservesNonEmpty : (f : Order a) ->
(xs : List a) -> (ys : List a) ->
{auto xsok : NonEmpty xs} -> {auto ysok : NonEmpty ys} ->
NonEmpty (merge f xs ys)
mergePreservesNonEmpty f (x :: xs) (y :: ys) with (x `f` y)
| True = IsNonEmpty
| False = IsNonEmpty
-- for contrast
sym' : (() -> x = y) -> y = x
sym' {x} {y} prf with (prf ())
-- matching against Refl needs x and y to be the same
-- now we need to write out the full form
sym' {x} {y=x} prf | Refl = Refl
As for why this is the case, I do believe it's just the implementation, but someone who knows better may dispute that.
There's an issue about proving things with case: https://github.com/idris-lang/Idris-dev/issues/4001
Because of this, in idris-bi we ultimately had to remove all cases in such functions and define separate top-level helpers that match on the case condition, e.g., like here.

How to solve maximum/minimum problems using Z3 SMT-LIB online

I am trying to solve some maximum/minimum problems using Z3 SMT-LIB online.
One example is:
Find two nonnegative numbers whose sum is 9 and so that the product of one number and the square of the other number is a maximum.
After many attempts the following code was constructed
(define-fun f ((x Real) (y Real)) Real
(if (not (= y 0.0))
(* y (^ x (- y 1)))
0.0))
(declare-const x Real)
(declare-const y Real)
(declare-const z Real)
(declare-const v Real)
(simplify (* x (^ (- 9 x) 2)) :som true)
(assert (= y (* 81.0 (f x 1))))
(assert (= z (* 18.0 (f x 2))))
(assert (= v (f x 3)))
(assert (= z (+ y v )))
(assert (not (= x 0)))
(assert (not (= x 9)))
(set-option :pp-decimal true)
(apply (then simplify solve-eqs))
(check-sat)
(get-model)
The output is:
(+ (* 81.0 x) (* (- 18.0) x x) (* x x x))
(goals
(goal (= (* 36.0 x) (+ (* 81.0 (^ x 0.0)) (* 3.0 (^ x 2.0))))
(not (= x 0.0))
(not (= x 9.0))
:precision precise :depth 2) )
sat
(model
(define-fun x () Real 3.0)
(define-fun v () Real 27.0)
(define-fun z () Real 108.0)
(define-fun y () Real 81.0) )
Run this example online here
Please let me know if you have a more efficient code for this problem. Many thanks.

Assigning variables (variable mutation) in racket

I have the following function that given an expression, executes it :
(define (foo exp0) exp0)
If I do the following:
(define x 5)
(foo (+ x 4))
(foo (* x 2))
display(x)
I would like for display(x) to display 18. Basically, how can I assign the value of the given expression back to the given variable?
First, the foo procedure is simply returning the parameter, it's not "executing" it. Answering your question, here's how you can reassign a value in Scheme:
(define x 5)
(set! x (+ x 4))
(set! x (* x 2))
(display x)
But to tell the truth, that style of programming (mutating variables) is frowned upon in Scheme. I believe this is more idiomatic:
(let* ((x 5)
(y (+ x 4))
(z (* y 2)))
(display z))
You can indeed write such a macro, if you can guarantee that the variable you're updating is always the first operand:
(define-syntax foo
(syntax-rules ()
((foo (op var arg ...))
(set! var (op var arg ...)))))