overriding a constraint in AMPL - constraints

I am wondering how we can override a constraint in AMPL. in a very basic example :
var x >= 0 ;
var y >= 0;
minimize cost : x^2 + y^4;
subject to constraint1 : x+2*y >= 100;
subject to constraint1 : x+2*y <= 10;
---------------------------------
"constraint1 is already defined"
AMPL uses the first "constraint1" as its constraint and ignores the second one , is there any way that AMPL uses the last "constraint1" ?

It is not possible to override constraints with the same variable name.
It is possible to toggle between constraints that are assigned to the same name via conditional logic (if statements come to mind), but they cannot be overwritten.

As mentioned from #Everyone_Else you can use an if statement.
In the AMPL book in Chapter 13, there are some examples of how to use it, in particular, subchapter:
13.4 Testing a condition: the if-then-else statement.
https://ampl.com/resources/the-ampl-book/chapter-downloads/
Your case would look like this:
if -->condition<--
subject to constraint1 : x+2*y >= 100;
else
subject to constraint1 x+2*y <= 10;

Related

Proving Floor_Log2 in Spark

New to Spark, and new to Ada, so this question may be overly broad. However, it's asked in good faith, as part of an attempt to understand Spark. Besides direct answers to the questions below, I welcome critique of style, workflow, etc.
As my first foray into Spark, I chose to try to implement (easy) and prove correctness (unsuccessful so far) the function .
Question: What is the proper way of implementing and proving the correctness of this function?
I started with the following util.ads:
package Util is
function Floor_Log2(X : Positive) return Natural with
Post => 2**Floor_Log2'Result <= X and then X < 2**(Floor_Log2'Result + 1);
end Util;
I have no pre-condition because the ranges of the input fully expresses the only interesting pre-condition. The post-condition I wrote based on the mathematical definition; however, I have an immediate concern here. If X is Positive'Last, then 2**(Floor_Log2'Result + 1) exceeds Positive'Last and Natural'Last. Already I'm up against my limited knowledge of Ada here, so: Sub-question 1: What is the type of the sub-expression in the post condition, and is this overflow a problem? Is there a general way to resolve it? To avoid the issue in this particular case, I revised the specification to the less-intuitive but equivalent:
package Util is
function Floor_Log2(X : Positive) return Natural with
Post => 2**Floor_Log2'Result <= X and then X/2 < 2**Floor_Log2'Result;
end Util;
There are many ways to implement this function, and I'm not particularly concerned about performance at this point, so I'd be happy with any of them. I'd consider the "natural" implementation (given my particular C background) to be something like the following util.adb:
package body Util is
function Floor_Log2 (X : Positive) return Natural is
I : Natural := 0;
Remaining : Positive := X;
begin
while Remaining > 1 loop
I := I + 1;
Remaining := Remaining / 2;
end loop;
return I;
end Floor_Log2;
end Util;
Attempting to prove this with no loop invariants fails, as expected. Results (this and all results are GNATprove level 4, invoked from GPS as gnatprove -P%PP -j0 %X --ide-progress-bar -u %fp --level=4 --report=all):
util.adb:6:13: info: initialization of "Remaining" proved[#2]
util.adb:7:15: info: initialization of "I" proved[#0]
util.adb:7:17: medium: overflow check might fail[#5]
util.adb:8:23: info: initialization of "Remaining" proved[#1]
util.adb:8:33: info: range check proved[#4]
util.adb:8:33: info: division check proved[#8]
util.adb:10:14: info: initialization of "I" proved[#3]
util.ads:3:14: medium: postcondition might fail, cannot prove 2**Floor_Log2'Result <= X[#7]
util.ads:3:15: medium: overflow check might fail[#9]
util.ads:3:50: info: division check proved[#6]
util.ads:3:56: info: overflow check proved[#10]
Most of the errors here make basic sense to me. Starting with the first overflow check, GNATprove cannot prove that the loop terminates in less than Natural'Last iterations (or at all?), so it cannot prove that I := I + 1 doesn't overflow. We know that this isn't the case, because Remaining is decreasing. I tried to express this adding the loop variant pragma Loop_Variant (Decreases => Remaining), and GNATprove was able to prove that loop variant, but the potential overflow of I := I + 1 is unchanged, presumedly because proving the loop terminates at all is not equivalent to proving that it terminates in less than Positive'Last iterations. A tighter constraint would show that the loop terminates in at most Positive'Size iterations, but I'm not sure how to prove that. Instead, I "forced it" by adding a pragma Assume (I <= Remaining'Size); I know this is bad practice, the intent here was purely to let me see how far I could get with this first issue "swept under the covers." As expected, this assumption lets the prover prove all range checks in the implementation file. Sub-question 2: What is the correct way to prove that I does not overflow in this loop?
However, we've still made no progress on proving the postcondition. A loop invariant is clearly needed. One loop invariant that holds at the top of the loop is that pragma Loop_Invariant (Remaining * 2**I <= X and then X/2 < Remaining * 2**I); besides being true, this invariant has the nice property that it is clearly equivalent to the post-condition when the loop termination condition is true. However, as expected GNATprove is unable to prove this invariant: medium: loop invariant might fail after first iteration, cannot prove Remaining * 2**I <= X[#20]. This makes sense, because the inductive step here is non-obvious. With division on the real numbers one could imagine a straightforward lemma stating that for all I, X * 2**I = (X/2) * 2**(I+1), but (a) I don't expect GNATprove to know that without a lemma being provided, and (b) it's messier with integer division. So, Sub-Question 3a: Is this the appropriate loop invariant to try to use to prove this implementation? Sub-Question 3b: If so, what's the right way to prove it? Externally prove a lemma and use that? If so, what exactly does that mean?
At this point, I thought I'd explore a completely different implementation, just to see if it led anywhere different:
package body Util is
function Floor_Log2 (X : Positive) return Natural is
begin
for I in 1 .. X'Size - 1 loop
if 2**I > X then
return I - 1;
end if;
end loop;
return X'Size - 1;
end Floor_Log2;
end Util;
This is a less intuitive implementation to me. I didn't explore this second implementation as much, but I leave it here to show what I tried; to give a potential avenue for other solutions to the main question; and to raise additional sub-questions.
The idea here was to bypass some of the proof around overflow of I and termination conditions by making termination and ranges explicit. Somewhat to my surprise, the prover first choked on overflow checking the expression 2**I. I had expected 2**(X'Size - 1) to be provably within the bounds of X -- but again, I'm up against the limits of my Ada knowledge. Sub-Question 4: Is this expression actually overflow-free in Ada, and how can that be proven?
This has turned out to be a long question... but I think the questions I'm raising, in the context of a nearly-trivial example, are relatively general and likely to be useful to others who, like me, are trying to understand if and how Spark is relevant to them.
I can't help with your SPARK questions, but I can answer some of your Sub-Questions.
Sub-Question 1: Since you're using "<" for Integer, the sub-expression will be of type Integer as well. For Positive'Last (2 ** 31 - 1 with GNAT), your function result should be 30, and the sub-expression will overflow. (This is from a SPARK point of view; compilers are allowed to use larger ranged types when evaluating expressions to obtain the mathematically/logically correct result even if a sub-expression would overflow, and GNAT will do this for some values of -gnato.)
Sub-Question 4: 2 ** (X'Size - 1) can overflow. The reason has to do with the 2 meanings of 'Size: Positive'Size is the minimum number of bits needed to store a value of subtype Positive; X'Size is the actual number of bits allocated to X. Since you're using GNAT,
Integer'Last = Positive'Last = 2 ** 31 - 1. X'Size = 32. Positive'Size = 31.
So, 2 ** (X'Size - 1) = 2 ** 31 > Positive'Last. You probably want to use Positive'Size instead of X'Size.
(Again, from the SPARK point of view; compilers are allowed to obtain the logically correct result.)
Aside: the short-circuit forms and then and or else should only be used when they're actually needed. Modern processors do all sorts of optimizations at the machine-code level that have to be turned off for short-circuit evaluation. Although they may look like optimizations, in practice they are often the opposite.
HTH.
(You might want to tag this with [ada]. I only saw it because you referenced it in c.l.ada.)
Preventing overflow in the post condition
Given the original function signature
function Floor_Log2 (X : Positive) return Natural with
Post => 2**Floor_Log2'Result <= X and then X < 2**(Floor_Log2'Result + 1);
I observe that I need to limit the domain of X in order to prevent overflow in the second term of the post condition. Given the definitions in Standard.ads, i.e.
type Integer is range -(2**31) .. +(2**31 - 1);
for Integer'Size use 32;
subtype Natural is Integer range 0 .. Integer'Last;
subtype Positive is Integer range 1 .. Integer'Last;
I conclude that, in order to prevent overflow,
X < 2**(Floor_Log2'Result + 1) <= 2**31 - 1
and therefore X <= 2**30 - 1. Hence, I changed the function signature to:
subtype Pos is Positive range 1 .. 2**30 - 1
function Floor_Log2 (X : Pos) return Natural with
Post => 2**Floor_Log2'Result <= X and then X < 2**(Floor_Log2'Result + 1);
First Approach
In principle, I could now proof the post condition as follows in GNAT CE 2019 (note that I use a different algorithm compared to the one stated in the question):
util.ads
package Util with SPARK_Mode is
subtype Pos is Positive range 1 .. 2**30 - 1
function Floor_Log2 (X : Pos) return Natural with
Post => 2**Floor_Log2'Result <= X and then X < 2**(Floor_Log2'Result + 1);
end Util;
util.adb
package body Util with SPARK_Mode is
----------------
-- Floor_Log2 --
----------------
function Floor_Log2 (X : Pos) return Natural is
L : Positive := 1;
H : Positive := L * 2;
I : Natural := 0;
begin
while not (L <= X and then X < H) loop
pragma Loop_Invariant
(L = 2 ** I and H = 2 ** (I+1));
pragma Loop_Invariant
(for all J in 0 .. I =>
not (2 ** J <= X and then X < 2 ** (J+1)));
L := H;
H := H * 2;
I := I + 1;
end loop;
return I;
end Floor_Log2;
end Util;
Unfortunately, however, the provers have difficulties with the non-linear arithmetic (i.e. exponentiation) and all proof sessions (on my computer) end with a timeout. In fact, if I run gnatprove with effort level 0, then I can only proof the post condition when I limit the upper bound of Pos to 2**7 - 1, i.e.
subtype Pos is Positive range 1 .. 2**7 - 1;
Increasing the effort level (or timeout) allows me to proof the post condition for larger values of Pos'Last.
Second Approach
In order to work around the limitation of the provers, I applied a little trick by redefining the exponentiation function. I could then use the following code to prove the post condition for the full range of Pos when I run gnatprove with effort level 1:
spark_exp.ads
generic
type Int is range <>;
Base : Int;
N_Max : Natural;
package SPARK_Exp with SPARK_Mode is
subtype Exp_T is Natural range 0 .. N_Max;
function Exp (N : Exp_T) return Int with Ghost;
private
type Seq_T is array (Exp_T range <>) of Int;
function Exp_Seq return Seq_T with
Ghost,
Post => (Exp_Seq'Result'First = 0)
and then (Exp_Seq'Result'Last = N_Max)
and then (Exp_Seq'Result (0) = 1)
and then (for all I in 1 .. N_Max =>
Exp_Seq'Result (I) = Base * Exp_Seq'Result (I - 1) and
Int'First < Exp_Seq'Result (I) and Exp_Seq'Result (I) < Int'Last);
function Exp (N : Exp_T) return Int is (Exp_Seq (N));
end SPARK_Exp;
spark_exp.adb
package body SPARK_Exp with SPARK_Mode is
-------------
-- Exp_Seq --
-------------
function Exp_Seq return Seq_T is
S : Seq_T (Exp_T'Range) := (others => 1);
begin
for I in 1 .. N_Max loop
pragma Loop_Invariant
(for all J in 1 .. I - 1 =>
S (J) = Base * S (J - 1) and
(Int'First / Base) < S (J) and S (J) < (Int'Last / Base));
S (I) := Base * S (I - 1);
end loop;
return S;
end Exp_Seq;
end SPARK_Exp;
util.ads
with SPARK_Exp;
package Util with SPARK_Mode is
subtype Pos is Positive range 1 .. 2**30 - 1;
package SPARK_Exp_2 is
new SPARK_Exp (Positive, 2, 30);
function Exp2 (N : SPARK_Exp_2.Exp_T) return Positive
renames SPARK_Exp_2.Exp;
function Floor_Log2 (X : Pos) return Natural with
Post => (Exp2 (Floor_Log2'Result) <= X) and then
(X < Exp2 (Floor_Log2'Result + 1));
end Util;
util.adb
package body Util with SPARK_Mode is
----------------
-- Floor_Log2 --
----------------
function Floor_Log2 (X : Pos) return Natural is
L : Positive := 1;
H : Positive := L * 2;
I : Natural := 0;
begin
while not (L <= X and then X < H) loop
pragma Loop_Invariant
(L = Exp2 (I) and H = Exp2 (I + 1));
pragma Loop_Invariant
(for all J in 0 .. I =>
not (Exp2 (J) <= X and then X < Exp2 (J + 1)));
L := H;
H := H * 2;
I := I + 1;
end loop;
return I;
end Floor_Log2;
end Util;
This implementation proves all checks within the body, but the preconditions are still not proven:
package body Util is
pragma SPARK_Mode (On);
function Floor_Log2 (X : Positive) return Natural is
I : Natural := 30;
Prod : Natural := 2**30;
type Large_Natural is range 0 .. 2**31;
Prev_Prod : Large_Natural := Large_Natural'Last with Ghost;
begin
while I > 0 loop
if X >= Prod then
pragma Assert (Large_Natural (X) < Prev_Prod);
return I;
end if;
pragma Loop_Invariant (I > 0);
pragma Loop_Invariant (Prod >= X and Prev_Prod >= Large_Natural (X));
-- pragma Loop_Invariant (2**I > X);
Prod := Prod / 2;
I := I - 1;
end loop;
pragma Assert (I = 0);
return 0;
end Floor_Log2;
end Util;
This gives the following output with gnatprove:
gnatprove -P/Users/pnoffke/projects/ada/spark/floor_log2/floor_log2.gpr -j0 --ide-progress-bar -u util.adb --level=2 --report=all
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
util.adb:10:13: info: initialization of "I" proved
util.adb:11:18: info: initialization of "Prod" proved
util.adb:12:28: info: assertion proved
util.adb:12:48: info: initialization of "Prev_Prod" proved
util.adb:13:20: info: initialization of "I" proved
util.adb:15:33: info: initialization of "I" proved
util.adb:15:33: info: loop invariant preservation proved
util.adb:15:33: info: loop invariant initialization proved
util.adb:16:33: info: initialization of "Prod" proved
util.adb:16:33: info: loop invariant preservation proved
util.adb:16:33: info: loop invariant initialization proved
util.adb:16:47: info: initialization of "Prev_Prod" proved
util.adb:18:18: info: initialization of "Prod" proved
util.adb:18:23: info: division check proved
util.adb:19:15: info: initialization of "I" proved
util.adb:19:17: info: range check proved
util.adb:22:22: info: initialization of "I" proved
util.adb:22:22: info: assertion proved
util.ads:5:15: info: overflow check proved
util.ads:5:44: medium: postcondition might fail, cannot prove X / 2 < 2**Floor_Log2'result (e.g. when Floor_Log2'Result = 0 and X = 2)
util.ads:5:46: info: division check proved
util.ads:5:53: medium: overflow check might fail (e.g. when Floor_Log2'Result = 30)
I don't understand why gnatprove cannot prove the commented Loop_Invariant. If I try to do so, I get the following additional output:
util.adb:17:33: medium: loop invariant might fail after first iteration, cannot prove 2**I > X (e.g. when I = 0 and X = 0)
util.adb:17:33: medium: loop invariant might fail in first iteration, cannot prove 2**I > X (e.g. when I = 30 and X = 1)
util.adb:17:34: medium: overflow check might fail (e.g. when I = 0)
In the counter-example, it says "when I = 0 and X = 0", but I cannot be 0 per the first Loop_Invariant.
Also if I initialize Prod to 2**I instead of 2**30, I get:
util.adb:6:26: medium: overflow check might fail (e.g. when I = 30 and Prod = 0)
I suspect gnatprove has some fundamental issue with the ** operator. I was hoping to use Prev_Prod to help prove your preconditions, but I don't see how to get there with the above issues I'm having.

add constraint rule pyomo

I have been trying to create a constraint based on a certain condition that is the binary output of my function ('Check_Condition'). The type of constraint is just a basic "conflicting" constraint to avoid that two conflicting variables are chosen. The constraint seems to be ignored (I included the print statement as a check), although I do not get any error. Here is the code. I do not want to use nested loops as they considerably slow down the code. Thanks!
model.n = RangeSet(n_operations)
model.triangular = Set(within=model.n * model.n, filter=lambda i, j: j < i)
def con(model, i, j):
if Check_Condition(operations[i],operations[j])==1:
print('added constraint')
return model.x[i] + model.x[j] <= 1
else:
return Constraint.Skip
model.OverlapConst = Constraint(model.triangular, rule=con)

How to use predicate exactly in MiniZinc

New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.

power-of (pow) constraints in minizinc

Is there any way (direct or indirect) by which pow constraints can be supported in minizinc. Gecode supports the pow constraint with float and int variables, however Minizinc and FlatZinc does not support pow for variables. Minizinc and Flatzinc supports pow only for parameters to the model.
Any pointers on where to look to add support in MiniZinc to Flatzinc (mzn2fzn) parser to do this.
I want to have a constraint such as - " pow( 4, x ) == y " , i.e. 4^x == y .
What I know it's not possible in current version of MiniZinc to use pow/2 with decision variables.
Perhaps it would be enough to emulate it with "exists"? Here's a simple example (the domain of "i" is too large in this example).
var 0..10000: x;
var 0..10000: y;
solve satisfy;
constraint
exists(i in lb(x)..ub(x)) (
i = x /\
pow(4,i) = y
)
;
output [ show([x,y]) ];

Is there better syntax for simple if, assigning variable

I have code that basically assigns a variable in one case, else a different in another. Is there a neater way that is more efficient?
I.e., not taking up so many lines. Or is this the best way?
if (ViewBag.Date != RoomBooking.StartDateTime.Date || ViewBag.DayPlannerStartTime * 12 > (Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5)
{
StartBlock = ViewBag.DayPlannerStartTime * 12;
}
else
{
StartBlock = ((Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5);
}
Maybe this (it's arguably neater, but definitely has the same efficiency):
StartBlock = (ViewBag.Date != RoomBooking.StartDateTime.Date || ViewBag.DayPlannerStartTime * 12 > (Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5)
? ViewBag.DayPlannerStartTime * 12
: ((Int32)RoomBooking.StartDateTime.TimeOfDay.TotalMinutes / 5);
EDIT: You can slightly optimize the condition as well. I suspect that your DayPlannerStartTime is expressed in seconds, and if I'm right you can rewrite the comparison the following way (I just divided both operands of the > operator by 12, and TotalMinutes divided by 5*12 became TotalHours):
ViewBag.DayPlannerStartTime > (Int32)RoomBooking.StartDateTime.TimeOfDay.TotalHours
Yes, you can use the ?: operator to create a single expression that will evaluate to the first expression if the condition is true, or else to the second expression:
// condition ? first_expression : second_expression;
var value = (something that is true or false) ? value if true : value if false;

Resources