2

I have 7 cups which contains some water. I need to program these cups to have different amounts of water. Once this is done I need to measure the cup which has the highest amount of water and then remove some quantity (say 2 units of water).

c implementations:

float c1=2.0, c2= 2.6, c3 = 2.8, c4=4.4 , c5 = 2.4, c6 = 2.1, c7 = 5.8;

if((c1 > c2) && (c1 > c3) && (c1 > c4) && (c1 > c5) && (c1 > c6) && (c1 > c7)); c1=c1-2;

if((c2 > c1) && (c2 > c3) && (c2 > c4) && (c2 > c5) && (c2 > c6) && (c2 > c7)); c2=c2-2;

if((c3 > c2) && (c3 > c1) && (c3 > c4) && (c3 > c5) && (c3 > c6) && (c3 > c7)); c3=c3-2;

if((c4 > c2) && (c4 > c3) && (c4 > c1) && (c4 > c5) && (c4 > c6) && (c4 > c7)); c4=c4-2;

if((c5 > c2) && (c5 > c3) && (c5 > c4) && (c5 > c1) && (c5 > c6) && (c5 > c7)); c5=c5-2;

if((c6 > c2) && (c6 > c3) && (c6 > c4) && (c6 > c5) && (c6 > c1) && (c6 > c7)); c6=c6-2;

if((c7 > c2) && (c7 > c3) && (c7 > c4) && (c7 > c5) && (c7 > c6) && (c7 > c1)); c7=c7-2; 

This will give an answer as c7 = 3.8

I was trying to implement this in z3 and I assigned the values to c1....c7

ite( (and((> c1  c2) (> c1  c3) (> c1  c4) (> c1  c5) (> c1  c6) (> c1  c7)))  (= c1_1 (- c1 2)  (= c1_1 c1))
.
.
.repeated till c7_1

and when I get the model values it should give c7_1 as 3.8

Is it possible to define this in z3? When I am using the and's of different conditions in if condition (in ite) its giving me an error. Can it not be defined like this? Is there someway around this?

Thanks in advance

[problem description][1]

I am experimenting with the Z3 tool, It was easy to get he first part However for the second part is being a bit difficult.

  • Is there any reason why you are using `z3` rather than, let's say, `nuXmv` or `minizinc`? The problem would be much more easily solved using one of the last two tools. The problem with `SMT` tools is that operations like addition/assignment can only be encoded with an increasing number of variables, one for each intermediate stage of the operations. This effort takes the focus away from the real problem. – Patrick Trentin Oct 17 '19 at 14:13
  • My understanding is that NuSMV gives an counter example when the water is above 7.0 but I am not sure if that is the minimum number of steps. In z3 I coded one iteration (filling and emptying)to see if the model is SAT. If unSAT, I kept on adding the iterations until it gives a SAT. This way I can be sure that the water is overflowing in minimum number of steps. Yes it was quite a work to encode the variables in each iteration. Moreover it was a requirement to implement it on Z3 rather than the other 2 – mutyala mahesh Oct 17 '19 at 14:55
  • One technique to discover short counter-examples with `nuXmv` is *Bounded Model Checking*. – Patrick Trentin Oct 17 '19 at 15:51

2 Answers2

3

Sure. Here it is in SMTLib:

; declare the cups
(declare-const c1 Real)
(declare-const c2 Real)
(declare-const c3 Real)
(declare-const c4 Real)
(declare-const c5 Real)
(declare-const c6 Real)
(declare-const c7 Real)

; each cup has a non-negative units of water
(assert (>= c1 0))
(assert (>= c2 0))
(assert (>= c3 0))
(assert (>= c4 0))
(assert (>= c5 0))
(assert (>= c6 0))
(assert (>= c7 0))

; each amount is different
(assert (distinct c1 c2 c3 c4 c5 c6 c7))

; find maximum, helper function
(define-fun max ((a Real) (b Real)) Real (ite (> a b) a b))

; find the cup with maximum water in it
(define-fun maxC () Real (max c1 (max c2 (max c3 (max c4 (max c5 (max c6 c7)))))))

; make sure there's at least 2 units in the max, per the problem
(assert (>= maxC 2))

; final value
(define-fun finalRes () Real (- maxC 2))

; solve
(check-sat)
(get-value (c1 c2 c3 c4 c5 c6 c7 maxC finalRes))

z3 says:

sat
((c1 2.0)
 (c2 (/ 11.0 6.0))
 (c3 (/ 19.0 12.0))
 (c4 (/ 7.0 4.0))
 (c5 (/ 3.0 2.0))
 (c6 (/ 23.0 12.0))
 (c7 (/ 5.0 3.0))
 (maxC 2.0)
 (finalRes 0.0))

So, looks like it put 2 units in c1, less than 2 on all the others, so you ended up with a final value of 0 left.

Your question is rather vague in what other constraints might be at play here, but hopefully this will get you started.

alias
  • 28,120
  • 2
  • 23
  • 40
  • Thank you very much, it indeed answered my question – mutyala mahesh Oct 17 '19 at 11:41
  • can you please give me an idea on how to find three max's of cups using if then else condition – mutyala mahesh Oct 17 '19 at 17:14
  • I'm not exactly sure what you're asking. It's best to ask a separate question showing what you tried and what happened. Please pose a new question following the MCVE guidelines: https://stackoverflow.com/help/minimal-reproducible-example – alias Oct 17 '19 at 19:36
2

Here's an alternative approach for finding max that doesn't use ITE.

; declare the cups
(declare-const c1 Real)
(declare-const c2 Real)
(declare-const c3 Real)
(declare-const c4 Real)
(declare-const c5 Real)
(declare-const c6 Real)
(declare-const c7 Real)

; each cup has a non-negative units of water
(assert (>= c1 0))
(assert (>= c2 0))
(assert (>= c3 0))
(assert (>= c4 0))
(assert (>= c5 0))
(assert (>= c6 0))
(assert (>= c7 0))

; each amount is different
(assert (distinct c1 c2 c3 c4 c5 c6 c7))

(declare-fun max () Real)

(assert (and (<= c1 max) (<= c2 max) (<= c3 max) (<= c4 max) (<= c5 max) (<= c6 max) (<= c7 max)))

(assert (or (<= max c1) (<= max c2) (<= max c3) (<= max c4) (<= max c5) (<= max c6) (<= max c7) ))

; make sure there's at least 2 units in the max, per the problem
(assert (<= 2 max))

; final value
(define-fun finalRes () Real (- max 2))

; solve
(check-sat)
(get-value (c1 c2 c3 c4 c5 c6 c7 maxC finalRes))

And the result:

sat
((c1 2.0)
 (c2 (/ 4.0 3.0))
 (c3 0.0)
 (c4 (/ 1.0 3.0))
 (c5 1.0)
 (c6 (/ 2.0 3.0))
 (c7 (/ 5.0 3.0))
 (max 2.0)
 (finalRes 0.0))
Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
  • Nice! I wonder what the performance implications are when you don’t use if-then-else but just resort to comparisons like this. – alias Oct 17 '19 at 12:54
  • @alias I guess it depends on the solver, and whether there are symmetries in the problem, like in this case, or not. – Patrick Trentin Oct 17 '19 at 13:13
  • yes it helped!! Is it possible to define a function in Z3 such a way that it will take the 7 cups and find the three cups with highest value and remove a specific different amount from each cup?? 1stmax -2.0 ; 2nd max- 1.5 ; 3rd max -1.0 for a better understanding, I have attached the problem statement to the question – mutyala mahesh Oct 17 '19 at 13:39
  • @AnoopKrishna it is definitely possible, albeit not efficient. The second-maximum `max_2` must be smaller or equal all `c_i`, strictly smaller than the absolute maximum `max_1`, and larger or equal all-but-one variables `c_1`. – Patrick Trentin Oct 17 '19 at 15:53