Calculate the sum of an Int Set - smt

Using the set theory of CVC4 (version 1.8-prerelease [git master a90b9e2b]) I have defined a set of integers with a fixed cardinality
(set-logic ALL_SUPPORTED)
(set-option :produce-models true)
(declare-fun A () (Set Int))
(assert (= 5 (card A)))
;;(assert (= sum (???)))
(check-sat)
(get-model)
CVC4 then gives me one correct model
sat
(model
(define-fun A () (Set Int) (union (union (union (union (singleton 0) (singleton 1)) (singleton (- 1))) (singleton 2)) (singleton (- 2))))
)
Is there a way to ask for the sum of the integers in set A?

As Patrick mentioned, these sorts of operations over arbitrary sets (like summing them up) is just not possible in SMTLib. However, you've more information: You know that the cardinality of the set is 5, so you can encode the summation indirectly.
The trick is to construct a set of the required cardinality explicitly and sum those elements. Obviously this only works well if the set is small enough, but you can "generate" the code automatically from a high-level API if necessary. (Hand coding it would be difficult!)
The below works with z3; Unfortunately CVC4 and Z3 differ in the function names for Sets a bit:
(set-option :produce-models true)
; declare-original set
(declare-fun A () (Set Int))
(assert (= 5 (card A)))
; declare the "elements". We know there are 5 in this case. Declare one for each.
(declare-fun elt1 () Int)
(declare-fun elt2 () Int)
(declare-fun elt3 () Int)
(declare-fun elt4 () Int)
(declare-fun elt5 () Int)
; form the set out of these elements:
(define-fun B () (Set Int) (store (store (store (store (store ((as const (Array Int Bool)) false) elt1 true)
elt2 true)
elt3 true)
elt4 true)
elt5 true))
; make sure our set is equal to the set just constructed:
(assert (= A B))
; now sum-up the elements
(declare-fun sum () Int)
(assert (= sum (+ elt1 elt2 elt3 elt4 elt5)))
(check-sat)
(get-value (elt1 elt2 elt3 elt4 elt5 sum A))
This produces:
$ z3 a.smt2
sat
((elt1 0)
(elt2 1)
(elt3 3)
(elt4 6)
(elt5 7)
(sum 17)
(A (let ((a!1 (store (store (store ((as const (Set Int)) false) 0 true) 1 true)
3
true)))
(store (store a!1 6 true) 7 true))))
For CVC4, the encoding is similar:
(set-option :produce-models true)
(set-logic ALL_SUPPORTED)
; declare-original set
(declare-fun A () (Set Int))
(assert (= 5 (card A)))
; declare the "elements". We know there are 5 in this case. Declare one for each.
(declare-fun elt1 () Int)
(declare-fun elt2 () Int)
(declare-fun elt3 () Int)
(declare-fun elt4 () Int)
(declare-fun elt5 () Int)
; form the set out of these elements:
(define-fun B () (Set Int) (union (singleton elt1)
(union (singleton elt2)
(union (singleton elt3)
(union (singleton elt4) (singleton elt5))))))
; make sure our set is equal to the set just constructed:
(assert (= A B))
; now sum-up the elements
(declare-fun sum () Int)
(assert (= sum (+ elt1 elt2 elt3 elt4 elt5)))
(check-sat)
(get-value (elt1 elt2 elt3 elt4 elt5 sum A))
For which, cvc4 produces:
sat
((elt1 (- 4)) (elt2 (- 3)) (elt3 (- 2)) (elt4 (- 1)) (elt5 0) (sum (- 10)) (A (union (union (union (union (singleton 0) (singleton (- 1))) (singleton (- 2))) (singleton (- 3))) (singleton (- 4)))))
If the cardinality isn't fixed; I don't think you can code this up unless the domain is finite (or drawn from a finite subset of an infinite domain) as Patrick described.
Hope that helps!

If you know all the elements that may possibly be contained in the set A (a.k.a. a finite super-set domain of A), one option is
(declare-fun A () (Set Int))
...
(declare-fun sum () Int)
(assert (= sum
(+
(ite (member 1 A) 1 0)
(ite (member 2 A) 2 0)
...
(ite (member k A) k 0)
)
))
This may not be very efficient.

Related

Create Polynomial function- unbound identifier in module

In my test I was asked to write a function createPolynomial that takes as arguments a list of π‘˜ numbers π‘Ž0, … , π‘Žπ‘˜βˆ’1 and returns as output a function. The returned function takes a number π‘₯0 and return the value of the polynomial π‘Ž0 β‹… π‘₯0 + β‹― + π‘Žπ‘˜βˆ’1 β‹… π‘₯π‘›βˆ’1 at π‘₯0. To this end, I used the built-in pl expt function taking two numbers π‘Ž and 𝑏, and returning π‘Ž^𝑏
i was given a partial code which I will post down below with my answer and wanted to test my answer at home but I can't make it run although my teacher marked my answer as correct. Any help would be appreciated
here is the partial code:
(: createPolynomial : (Listof Number) -> <-fill in->)
(define (createPolynomial coeffs)
(: poly : (Listof Number) Number Integer Number ->
Number)
(define (poly argsL x power accum)
(if <-fill in->
<-fill in->
<-fill in-> )
(: polyX : Number -> Number)
(define (polyX x)
οƒŸfill inοƒ )
οƒŸfill inοƒ )
And here is my answer:
(: createPolynomial : (Listof Number) -> (Number -> Number))
(define (createPolynomial coeffs)
(: poly : (Listof Number) Number Integer Number ->
Number)
(define (poly argsL x power accum)
(if (null? argsL)
accum
(poly (rest argsL) x (+ power 1) (+ accum (* (first argsL) (expt x power))))))
(: polyX : Number -> Number)
(define (polyX x)
(poly coeffs x 0 0))
(polyX x))
and here are some test for the code:
> (createPolynomial '(1 2 4 2))
- : (Number -> Number)
#<procedure:polyX>
(define p2345 (createPolynomial '(2 3 4 5)))
(test (p2345 0) =>
(+ (* 2 (expt 0 0)) (* 3 (expt 0 1)) (* 4 (expt 0 2)) (* 5
(expt 0 3))))
(test (p2345 4) =>
(+ (* 2 (expt 4 0)) (* 3 (expt 4 1)) (* 4 (expt 4 2)) (* 5
(expt 4 3))))
(test (p2345 11) => (+ (* 2 (expt 11 0)) (* 3 (expt 11 1)) (* 4
(expt 11 2)) (* 5 (expt 11 3))))
(define p536 (createPolynomial '(5 3 6)))
(test (p536 11) => (+ (* 5 (expt 11 0)) (* 3 (expt 11 1)) (* 6
(expt 11 2))))
(define p_0 (createPolynomial '()))
(test (p_0 4) => 0)
The error I'm getting is:
x: unbound identifier in module in: x
I'm guessing It has to do something with the brackets but I can't figure out what and where...
createPolynomial is a function that returns a function of type (Number -> Number) - it's curried. You are returning the application (polyX x) where x really is unbound. Convert this into a function by wrapping it in a lambda:
(Ξ» (x) (polyX x))
... and the 5 tests pass.

Create polynomial function

In my test I was asked to write a function createPolynomial that
takes as arguments a list of π‘˜ numbers π‘Ž0, … , π‘Žπ‘˜βˆ’1 and returns as output a
function. The returned function takes a number π‘₯0 and return the value of
the polynomial π‘Ž0 β‹… π‘₯0 + β‹― + π‘Žπ‘˜βˆ’1 β‹… π‘₯π‘›βˆ’1 at π‘₯0. To this end, I used the
built-in pl expt function taking two numbers π‘Ž and 𝑏, and returning π‘Ž^𝑏
i was given a partial code which I will post down below with my answer and wanted to test my answer at home but I can't make it run although my teacher marked my answer as correct. Any help would be appreciated
here is the partial code:
(: createPolynomial : (Listof Number) -> <-fill in->)
(define (createPolynomial coeffs)
(: poly : (Listof Number) Number Integer Number ->
Number)
(define (poly argsL x power accum)
(if <-fill in->
<-fill in->
<-fill in-> )
(: polyX : Number -> Number)
(define (polyX x)
οƒŸfill inοƒ )
οƒŸfill inοƒ )
And here is my answer:
(: createPolynomial : (Listof Number) -> (Number -> Number))
(define (createPolynomial coeffs)
(: poly : (Listof Number) Number Integer Number ->
Number)
(define (poly argsL x power accum)
(if (null? argsL)
accum)
(poly (rest argsL) x (+ power 1) (+ accum (* (first argsL) (expt x power)))))
(: polyX : Number -> Number)
(define (polyX x)
(poly coeffs x 0 0)
polyX x))
and here are some test for the code:
> (createPolynomial '(1 2 4 2))
- : (Number -> Number)
#<procedure:polyX>
(define p2345 (createPolynomial '(2 3 4 5)))
(test (p2345 0) =>
(+ (* 2 (expt 0 0)) (* 3 (expt 0 1)) (* 4 (expt 0 2)) (* 5
(expt 0 3))))
(test (p2345 4) =>
(+ (* 2 (expt 4 0)) (* 3 (expt 4 1)) (* 4 (expt 4 2)) (* 5
(expt 4 3))))
(test (p2345 11) => (+ (* 2 (expt 11 0)) (* 3 (expt 11 1)) (* 4
(expt 11 2)) (* 5 (expt 11 3))))
(define p536 (createPolynomial '(5 3 6)))
(test (p536 11) => (+ (* 5 (expt 11 0)) (* 3 (expt 11 1)) (* 6
(expt 11 2))))
(define p_0 (createPolynomial '()))
(test (p_0 4) => 0)
I'm getting the error -
define: empty body (after defns/decls) in: (define (createPolynomial coeffs) (: poly : (Listof Number) Number Integer Number -> Number) (define (poly argsL x power accum) (if (null? argsL) accum) (poly (rest argsL) x (+ power 1) (+ accum (* (first argsL) (expt x power))))) (: polyX : Number -> Number) (define (polyX x) (poly coeffs x 0 0) polyX x))
>
An empty means that the there are no expressions in the body.
Usually it means a parenthesis is misplaced.
Use indentation!
I am guessing, you meant to write:
(: createPolynomial : (Listof Number) -> (Number -> Number))
(define (createPolynomial coeffs)
(: poly : (Listof Number) Number Integer Number ->
Number)
(define (poly argsL x power accum)
(if (null? argsL)
accum)
(poly (rest argsL) x (+ power 1) (+ accum (* (first argsL) (expt x power)))))
(: polyX : Number -> Number)
(define (polyX x)
(poly coeffs x 0 0))
(polyX x))
The answer above didn't help me (cus I'm writing in pl)
So this is my solution:
(: createPolynomial : (Listof Number) -> (Number -> Number))
(define (createPolynomial coeffs)
(: poly : (Listof Number) Number Integer Number -> Number)
(define (poly argsL x power accum)
(if (null? argsL)
accum
(poly (rest argsL) x (+ power 1) (+ accum (* (first argsL) (expt x power)))) ))
(: polyX : Number -> Number)
(define (polyX x)
(poly coeffs x 0 0))
polyX
)
You call the polyX (that is a Num -> Num) as the return of "createPolynomial".
So when calling (in some define) createPolynomial with a list of numbers then you call again to what you define with a number, that number will go into polyX that will use the list and x to create the poly function.

Surprising behaviour when trying to prove a forall

Consider the following SMT-LIB code:
(set-option :auto_config false)
(set-option :smt.mbqi false)
; (set-option :smt.case_split 3)
(set-option :smt.qi.profile true)
(declare-const x Int)
(declare-fun trigF (Int Int Int) Bool)
(declare-fun trigF$ (Int Int Int) Bool)
(declare-fun trigG (Int) Bool)
(declare-fun trigG$ (Int) Bool)
; Essentially noise
(declare-const y Int)
(assert (!
(not (= x y))
:named foo
))
; Essentially noise
(assert (forall ((x Int) (y Int) (z Int)) (!
(= (trigF$ x y z) (trigF x y z))
:pattern ((trigF x y z))
:qid |limited-F|
)))
; Essentially noise
(assert (forall ((x Int)) (!
(= (trigG$ x) (trigG x))
:pattern ((trigG x))
:qid |limited-G|
)))
; This assumption is relevant
(assert (forall ((a Int) (b Int) (c Int)) (!
(and
(trigG a)
(trigF a b c))
:pattern ((trigF a b c))
:qid |bar|
)))
Trying to assert that axiom bar holds, i.e.,
(push)
(assert (not (forall ((a Int) (b Int) (c Int))
(and
(trigG a)
(trigF a b c)))))
(check-sat)
(pop)
fails (Z3 4.3.2 - build hashcode 47ac5c06333b):
unknown
[quantifier_instances] limited-G : 1 : 0 : 1
Question 1: Why did Z3 only instantiate limited-G but neither limited-F nor bar (which would prove the assertion)?
Question 2: Commenting any of the (useless) assertions foo, limited-F or limited-G allows Z3 to prove the assertion - why is that? (Depending on which are commented, either only bar or bar and limited-F are instantiated.)
In case it is related to the observed behaviour: I would like to set smt.case_split to 3 (my configuration follows the one omitted by MSR's Boogie tool), but Z3 gives me WARNING: auto configuration (option AUTO_CONFIG) must be disabled to use option CASE_SPLIT=3, 4 or 5, despite the fact that (set-option :auto_config false).
The situation is as follows:
when using pattern based instantiation exclusively Z3 takes a somewhat operational approach to finding quantifier instantiations.
by disabling MBQI you rely on the equality matching engine.
case_split = 3 instructs Z3 to use relevancy heuristic when
choosing candidates for equality matching.
The assert (not (forall (a, b, c) (and (trigG a) (trigF a b c)))) expands
into a disjunction (or (not (trigG a!0)) (not (trigF a!0 b!1 c!2))).
only one of the two disjuncts is relevant for satisfying the formula.
The search sets (trigG a!0) to false, so the clause is satisfied. The trigger (trigF a b c) is therefore never activated.
You can bypass this issue by distributing in universal quantifiers over conjunctions, and supplying patterns in each case. Thus, you(r tool) could rewrite the axiom:
(assert (forall ((a Int) (b Int) (c Int)) (!
(and
(trigG a)
(trigF a b c))
:pattern ((trigF a b c))
:qid |bar|
)))
to the two axioms.
(assert (forall ((a Int)) (! (trigG a) :pattern ((trigG a))))
(assert (forall ((a Int) (b Int) (c Int)) (!
(trigF a b c)
:pattern ((trigF a b c))
:qid |bar|
)))
The issue of setting auto-completion seems fixed. I somewhat recently fixed bug in the way that some top-level configurations were reset if multiple top-level configurations were set in the smt-lib input.

Partial function application in Racket

I'm writing a function to partially-apply arguments to functions, such that
(define mapeven (partial-apply map even?))
(mapeven (list 1 2 3 4)) ; '(#f #t #f #t)
To that end, I have
(define (partial-apply* func . args)
(define (apply-one func arg)
(Ξ» args (apply func (cons arg args))))
(foldl (Ξ» (new carry) (apply-one carry new)) func args))
which seems to work fine. However, I'd also like to be able to "skip" args (probably by use of a sentinel value, like 'Ξ»). I.E.:
(define apply-to-four (partial-apply map 'Ξ» (list 1 2 3 4))
(apply-to-four even?) ; '(#f #t #f #t)
That is to say, when partial-apply encounters 'Ξ», it does NOT bind a value to that position, instead leaving it as a free variable. And when a partially applied function is called, first it will fill in arguments skipped by this mechanism of 'Ξ», then it will apply any remaining arguments to the end.
To this end, I have written:
(define (partial-apply func . args)
(define (apply-one func arg)
(if (equal? arg 'Ξ»)
(Ξ» args (Ξ» (x) (apply func (cons x args)))))
(Ξ» args (apply func (cons arg args)))))
(foldl (Ξ» (new carry) (apply-one carry new)) func args))
However, it doesn't work.
> (define apply-to-4 (partial-apply map 'Ξ» (list 1 2 3 4)))
> (apply-to-4 even?)
#<procedure>
It seems like the problem is in the affirmative branch of the if statement, but I'm having trouble nailing it down. Any advice?

Difference between '(()) and (cons null null)

I am confused about the difference between '(()) and (cons null null) in scheme.
The code below show that b and c are completely the same thing.
(define (dup2 x)
(let ((d '(())))
(set-car! d (car x))
(set-cdr! d (cdr x))
d))
(define a '(1 2))
(define b (dup2 a))
(define c (dup2 a))
(set-car! b 2)
> c ;; --> (2 2)
However, when I used dup instead of dup2:
(define (dup x)
(let ((d (cons null null)))
(set-car! d (car x))
(set-cdr! d (cdr x))
d))
(define a '(1 2))
(define b (dup a))
(define c (dup a))
(set-car! b 2)
> c ;; --> (1 2)
Variable b and c are different. I have done some experiments, but I haven't understand yet.
The value of d in the first implementation is literal data, and is modified with undefined consequences. To highlight what's happening, consider the following code:
(define (incorrect-list-null-and-x x)
(let ((l '(()))) ; a list of the form (() . ())
(set-cdr! l (cons x (cdr l))) ; (cdr l) is (), so (cons x (cdr l)) should be (x . ()) == (x), right?
; and now l should be (() . (x . ())) == (() x), right?
l))
The expected result is that (incorrect-list-null-and-x n) should return a list of the form (() n), and it does the first time, but successive calls are still accessing the same data:
(incorrect-list-null-and-x 1) ;=> (() 1)
(incorrect-list-null-and-x 2) ;=> (() 2 1)
(incorrect-list-null-and-x 3) ;=> (() 3 2 1)
(incorrect-list-null-and-x 4) ;=> (() 4 3 2 1)
The same problem manifests itself a bit differently in your dup2. Every value returned from dup2 is actually the same pair:
(let* ((x (dup2 (cons 1 2)))
(y (dup2 (cons 3 4))))
(display x)
(display y))
outputs:
(3 . 4)(3 . 4)
because the call (dup2 (cons 3 4)) modifies the same structure that was previously returned by (dup2 (cons 1 2)).
Data literals, like '(()), are meant to be read-only, and modifying it using set-car! or set-cdr! has undefined behaviour. For predictable behaviour, use the (cons '() '()) version if you want to use set-car! or set-cdr! on it.
In particular, cons creates a new cons cell, whereas a data literal usually won't.
Still, for the purposes of implementing dup, why are you using set-car! and set-cdr! anyway? Just use cons directly:
(define (dup x)
(cons (car x) (cdr x)))
In your first code snippet you use (d '(())) which ends up binding a literal to d. You then modify the literal which is generally undefined. In your second code snippet you use (d (cons null null)) which binds d to a newly created 'cons cell' which you then modify. There is no problem modifying that.
Note: you've not defined null. Perhaps you meant '()?