Sort and switch methods in Dafny (Invariants error) - while-loop
I am new to Dafny and wrote two methods, switch and sort. In sort I get an error in line 10 and 12 and in switch in line 24 and 26. Both based on the forall invaraiants. I'm struggling and can't figure out why.
The error messages I'm getting are "this loop invariant might not be mantained by the loop".
method sort(a: array<int>)
modifies a
ensures forall h, k: int ::
0 <= h < k < a.Length ==> a[h] <= a[k];
{
var i := 0;
while i < a.Length
invariant 0 <= i <= a.Length
invariant forall h, k: int :: //error (forall)
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int :: //error (error forall)
0 <= h < k < i ==> a[h] <= a[k];
{
var index := i;
var j := i+1;
while j < a.Length
invariant 0 <= i < j <= a.Length
invariant 0 <= index < j
invariant forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
invariant forall k: int ::
i <= k < j ==> a[index] <= a[k]
{
if a[j] < a[index] {
index := j;
}
j := j + 1;
}
var tmp := a[index];
a[index] := a[i];
a[i] := tmp;
i := i + 1;
}
}
method switch(a: array<int>, b: array<int>, j: int)
modifies a
modifies b
requires 0 <= j <= a.Length
requires 0 <= j <= b.Length
ensures forall k: int ::
(0 <= k < j ==> a[k] == old(b[k]))
ensures forall k: int ::
(0 <= k < j ==> b[k] == old(a[k]))
ensures forall k: int ::
(j <= k < b.Length ==> b[k] == old(b[k]))
ensures forall k: int ::
(j <= k < a.Length ==> a[k] == old(a[k]))
{
var i := 0;
while i < j
invariant 0 <= i <= j <= a.Length;
invariant forall k: int ::
(j <= k < a.Length ==> a[k] == old(a[k]))
invariant forall k: int ::
(j <= k < b.Length ==> b[k] == old(b[k]))
invariant forall k: int :: // error (forall)
(0 <= k < i ==> a[k] == old(b[k]))
invariant forall k: int :: // error (forall)
(0 <= k < i ==> b[k] == old(a[k]))
{
var tmp := b[i];
b[i] := a[i];
a[i] := tmp;
i := i + 1;
//assert a[i - 1] == old(b[i-1]);
}
}
How can I fix this, what would be the correct invariants?
Let me introduce you to the almost universal technique of verification debugging introduced recently in the docs.
Let me apply it to your case. First, you get the message that the "invariant might not be maintained by the loop". So the first idea, is to move the assertion at the end of the loop, to capture this idea, like this:
method sort(a: array<int>)
modifies a
ensures forall h, k: int ::
0 <= h < k < a.Length ==> a[h] <= a[k];
{
var i := 0;
while i < a.Length
invariant 0 <= i <= a.Length
invariant forall h, k: int :: //No more error
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int :: //No more error
0 <= h < k < i ==> a[h] <= a[k];
{
var index := i;
var j := i+1;
while j < a.Length
invariant 0 <= i < j <= a.Length
invariant 0 <= index < j
invariant forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
invariant forall k: int ::
i <= k < j ==> a[index] <= a[k]
{
if a[j] < a[index] {
index := j;
}
j := j + 1;
}
var tmp := a[index];
a[index] := a[i];
a[i] := tmp;
i := i + 1;
assert forall h, k: int :: //error (forall)
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int :: //error (error forall)
0 <= h < k < i ==> a[h] <= a[k];
}
}
Now, the technique of verification debugging consists of moving the assertions back through the definitions in what is called a weakest precondition calculus (mostly described practically in the link at the beginning of this post). For example, to move these assertions above the assignment i := i + 1, you'd simply replace i by i + 1 in these assertions, like this:
method sort(a: array<int>)
modifies a
ensures forall h, k: int ::
0 <= h < k < a.Length ==> a[h] <= a[k];
{
var i := 0;
while i < a.Length
invariant 0 <= i <= a.Length
invariant forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
{
var index := i;
var j := i+1;
while j < a.Length
invariant 0 <= i < j <= a.Length
invariant 0 <= index < j
invariant forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
invariant forall k: int ::
i <= k < j ==> a[index] <= a[k]
{
if a[j] < a[index] {
index := j;
}
j := j + 1;
}
var tmp := a[index];
a[index] := a[i];
a[i] := tmp;
assert forall h, k: int :: //error (forall)
0 <= h < i+1 && i+1 <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int :: //error (error forall)
0 <= h < k < i+1 ==> a[h] <= a[k];
i := i + 1;
assert forall h, k: int :: //no more error
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int :: //no more error
0 <= h < k < i ==> a[h] <= a[k];
}
}
Now, note that the assignment with temporary variable:
var tmp := a[index];
a[index] := a[i];
a[i] := tmp;
can actually be simplified in Dafny to:
a[i], a[index] := a[index], a[i];
it makes verification easier for the step below (one step instead of three steps). To move the assertions up this double assignment, we need to ensure we can swap the values a[i] and a[index] in the assertions. For that, we need to explicit what the forall means for these two indices, so that we can swap them.
Since our indices h can be i in the first forall, and k can be i in the second forall, and because we don't know the relative position between index and i, we will need to split the cases. To split the cases, we just insert a if-then-else structure with the conditions, and put back our assertions in them:
method sort(a: array<int>)
modifies a
ensures forall h, k: int ::
0 <= h < k < a.Length ==> a[h] <= a[k];
{
var i := 0;
while i < a.Length
invariant 0 <= i <= a.Length
invariant forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
{
var index := i;
var j := i+1;
while j < a.Length
invariant 0 <= i < j <= a.Length
invariant 0 <= index < j
invariant forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
invariant forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
invariant forall k: int ::
i <= k < j ==> a[index] <= a[k]
{
if a[j] < a[index] {
index := j;
}
j := j + 1;
}
a[i], a[index] := a[index], a[i];
if i < index {
assert forall h, k: int ::
0 <= h < i+1 && i+1 <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int ::
0 <= h < k < i+1 ==> a[h] <= a[k];
} else if i == index {
assert forall h, k: int ::
0 <= h < i+1 && i+1 <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int ::
0 <= h < k < i+1 ==> a[h] <= a[k];
} else {
assert forall h, k: int :: //error (forall)
0 <= h < i+1 && i+1 <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int :: //error (forall)
0 <= h < k < i+1 ==> a[h] <= a[k];
}
assert forall h, k: int :: //no more error
0 <= h < i+1 && i+1 <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int :: //no more error
0 <= h < k < i+1 ==> a[h] <= a[k];
i := i + 1;
assert forall h, k: int ::
0 <= h < i && i <= k < a.Length ==> a[h] <= a[k];
assert forall h, k: int ::
0 <= h < k < i ==> a[h] <= a[k];
}
}
Now, something interesting happens. The assertions are proved if i == index or i < index, but not if index < i.
Looking at the inner while loop, it looks like index started at i and is assigned j from time to time, j is increased, and j starts at i+1. Could it be that index <= i in any case?
Let's add the invariant invariant index <= i in the inner loop...
Magic, everything verifies now!
You can now remove the assertions one by one until you get back to your original code.
Related
Error (10028): Can't resolve multiple constant drivers and Error (10029): Constant driver
I am new to Verilog, and trying to write a traffic light code where the LED light changes after certain time. I'm keep getting on different errors while compiling. I tried to fix them by changing the arrangement, or variables in the code, but it still fails. This is the code I wrote, module traffic_light(clk, reset, G1, Y1, R1, G2, Y2, R2); input clk, reset; output reg G1, Y1, R1, G2, Y2, R2; // parameters for each light control parameter GREEN = 3'b001, YELLOW = 3'b010, RED = 3'b100, LEFT_GREEN = 3'b101, // assume both red and green will be turned on LEFT_YELLOW = 3'b110; // assume both red and yellow will be turned on // finite-state definition (Moore Type): // --------------------------- // NSlight EWlight // --------------------------- parameter S0 = 3'd0, // GREEN RED S1 = 3'd1, // YELLOW RED S2 = 3'd2, // RED, GREEN RED S3 = 3'd3, // RED, YELLOW RED S4 = 3'd4, // RED GREEN S5 = 3'd5, // RED YELLOW S6 = 3'd6, // RED RED, GREEN S7 = 3'd7; // RED RED, YELLOW // internal state variables reg [2:0] state, next_state; integer t1 = 19, t2 = 4; integer count; // buttons are appropriate for use as clock or reset inputs in a circuit always #(posedge clk, negedge reset) if(reset == 'b0) // button pressed, when reset is active low begin next_state = S0; count = t1; end else state <= next_state; always #(next_state) begin next_state = S0; count = t1; case(state) S0: if (count < 0) // load: if the count reaches below 0, reset begin count <= t2; next_state <= S1; end else // enable begin // down count count <= count - 1; // assign LEDs G1 <= 1; Y1 <= 0; R1 <= 0; G2 <= 0; Y2 <= 0; R2 <= 1; end S1: if (count < 0) begin count <= t1; next_state <= S2; end else begin G1 <= 0; Y1 <= 1; R1 <= 0; G2 <= 0; Y2 <= 0; R2 <= 1; count <= count - 1; end S2: if (count < 0) begin count <= t2; next_state <= S3; end else begin G1 <= 1; Y1 <= 0; R1 <= 1; G2 <= 0; Y2 <= 0; R2 <= 1; count <= count - 1; end S3: if (count < 0) begin count <= t1; next_state <= S4; end else begin G1 <= 0; Y1 <= 1; R1 <= 1; G2 <= 0; Y2 <= 0; R2 <= 1; count <= count - 1; end S4: if (count < 0) begin count <= t1; next_state <= S5; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 1; Y2 <= 0; R2 <= 0; count <= count - 1; end S5: if (count < 0) begin count <= t1; next_state <= S6; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 0; Y2 <= 1; R2 <= 0; count <= count - 1; end S6: if (count < 0) begin count <= t2; next_state <= S7; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 1; Y2 <= 0; R2 <= 1; count <= count - 1; end S7: if (count < 0) begin count <= t1; next_state <= S0; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 0; Y2 <= 1; R2 <= 1; count <= count - 1; end endcase end endmodule and these are the errors generated from the above code: Error (10028): Can't resolve multiple constant drivers for net "next_state.S0" at traffic_light.v(41) Error (10029): Constant driver at traffic_light.v(32) Error (10028): Can't resolve multiple constant drivers for net "next_state.S1" at traffic_light.v(41) Error (10028): Can't resolve multiple constant drivers for net "next_state.S2" at traffic_light.v(41) Error (10028): Can't resolve multiple constant drivers for net "next_state.S3" at traffic_light.v(41) Error (10028): Can't resolve multiple constant drivers for net "next_state.S6" at traffic_light.v(41) Error (10028): Can't resolve multiple constant drivers for net "next_state.S7" at traffic_light.v(41) Error (12152): Can't elaborate user hierarchy "traffic_light:inst" Hope I can get any suggestions or solutions to this problem. Thank you in advance. I solved the problem after few more searching. Error (10028): Can't resolve multiple constant drivers for net... VHDL ERROR "Multiple Constant Drivers" Error Verilog with Quartus Prime These two links helped solving, the problem is that you cannot assign one variable in two different always block. The below code is the fixed one. module traffic_light(clk, reset, G1, Y1, R1, G2, Y2, R2, time_); input clk, reset; output reg G1, Y1, R1, G2, Y2, R2; output reg [4:0] time_; // added, it displays the remaining time // parameters for each light control parameter GREEN = 3'b001, YELLOW = 3'b010, RED = 3'b100, LEFT_GREEN = 3'b101, // assume both red and green will be turned on LEFT_YELLOW = 3'b110; // assume both red and yellow will be turned on // finite-state definition (Moore Type): // --------------------------- // NSlight EWlight // --------------------------- parameter S0 = 3'd0, // GREEN RED S1 = 3'd1, // YELLOW RED S2 = 3'd2, // RED, GREEN RED S3 = 3'd3, // RED, YELLOW RED S4 = 3'd4, // RED GREEN S5 = 3'd5, // RED YELLOW S6 = 3'd6, // RED RED, GREEN S7 = 3'd7; // RED RED, YELLOW // internal state variables and time settings reg [2:0] state, next_state; integer t1 = 19, t2 = 4; reg count; // changed to count only always #(posedge clk) if(reset == 0) // button pressed, when reset is active low begin state <= S0; time_ <= t1; end else begin state <= next_state; time_ <= count; end always #(*) // changed according to advice in the comment case(state) S0: if (count < 0) // load: if the count reaches below 0, reset begin count <= t2; next_state <= S1; end else // enable begin // down count count <= count - 1; // assign LEDs G1 <= 1; Y1 <= 0; R1 <= 0; G2 <= 0; Y2 <= 0; R2 <= 1; end S1: if (count < 0) begin count <= t1; next_state <= S2; end else begin G1 <= 0; Y1 <= 1; R1 <= 0; G2 <= 0; Y2 <= 0; R2 <= 1; count <= count - 1; end S2: if (count < 0) begin count <= t2; next_state <= S3; end else begin G1 <= 1; Y1 <= 0; R1 <= 1; G2 <= 0; Y2 <= 0; R2 <= 1; count <= count - 1; end S3: if (count < 0) begin count <= t1; next_state <= S4; end else begin G1 <= 0; Y1 <= 1; R1 <= 1; G2 <= 0; Y2 <= 0; R2 <= 1; count <= count - 1; end S4: if (count < 0) begin count <= t2; next_state <= S5; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 1; Y2 <= 0; R2 <= 0; count <= count - 1; end S5: if (count < 0) begin count <= t1; next_state <= S6; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 0; Y2 <= 1; R2 <= 0; count <= count - 1; end S6: if (count < 0) begin count <= t2; next_state <= S7; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 1; Y2 <= 0; R2 <= 1; count <= count - 1; end S7: if (count < 0) begin count <= t1; next_state <= S0; end else begin G1 <= 0; Y1 <= 0; R1 <= 1; G2 <= 0; Y2 <= 1; R2 <= 1; count <= count - 1; end default: begin next_state <= S0; count <= t1; end endcase endmodule
You have next_state assigned in both processes, and that is causing troubles. We can find it actually described in the Verilog Standard. section 14.5 Driving wired logic Module path output nets shall not have more than one driver within the module. Therefore, wired logic is not allowed at module path outputs And it also provides an example:
Time complexity from pseudocode
I am trying to find the Time complexity from the lines of code. However, I am not really getting it. int codeMT(int n) { int a = 1; int i = 1; while (i < n * n) { j = 1; while (j < n * n * n) { j = j * 3; a = a + j + i; } i = i + 2; } return a; } In this case, this is my thought process. Firstly, we need to start from the inner loop. while (j < n * n * n) { j = j * 3; a = a + j + i; } In here, there is j = j * 3 which makes this log(n)(log base 3) but then we have a loop guard that has nnn which makes the n^3. Therefore, this part of code has log(n^3) time complexity. Secondly, the outer while loop has the loop guard of n * n which makes it n^2. Thus, O(n^2(log(n^3)) Is my approach okay? or is there anything that I am missing/things that I could improve my thought process? Thank you
Time complexity for nested loops?
a) sum = 0; for(i=1;i<2*n;i++) for(j=1;j<i*i;j++) for(k=1;k<j;k++) if (j % i == 1) sum++; b) sum = 0; for(i=1;i<2*n;i++) for(j=1;j<i*i;j++) for(k=1;k<j;k++) if (j % i) sum++; I chanced the above two pseudo code above while looking for algorithm analysis questions to practice on. The answers for the above two snippets are O(n4) and O(n5) respectively. Note that the running time corresponds here to the number of times the operation sum++ is executed. How is it that the time complexity for the above two algorithms different by an order of n when the only difference is the if loop testing for equality to 1? How would I go about counting the O(n) complexity for such a question?
Algorithm A Let's call f(n) the number of operations aggregated at the level of the outer loop, g(n) that for the first inner loop, h(n) for the most inner loop. We can see that f(n) = sum(i=1; i < 2n; g(i)) g(i) = sum(j=1, j < i*i; h(j)) h(j) = sum(k=1; k < j; 1 if j%i = 1, else 0) How many times j%i = 1 while j varies from 1 to i*i? Exactly i times for the following values of j: j = 0.i + 1 j = 1.i + 1 j = 2.i + 1 ... j = (i-1)*i + 1 So: h(j) = sum(k=1; k < j; 1 if `j%i = 1`, else 0) = i => g(i) = sum(j=1, j < i*i; h(j)) = sum(j=1, j < i*i; i) = i*i * i = i^3 => f(n) = sum(i=1; i < 2n; g(i)) = sum(i=1; i < 2n; i^3) <= sum(i=1; i < 2n; 16.n^3) // Here just cap every i^3 with (2n)^3 <= 32.n^4 => f(n) = O(n^4) Algorithm B (With the same naming conventions as algorithm A) How many times do we have j%i casting to true? Every time j%i is different from 0. And how many times does this happen? We need to remove the occurrences for which j is a multiple of i, which are i, 2.i, ... (i-1).i, over the range of integers 1 to i*i, which has i*i numbers. This quantity is i*i - (i-1) = i^2 - i + 1. As a result, h(j) = sum(k=1; k < j; 1 if j%i = 1, else 0) = i^2 - i + 1 = i^2 // dropping the terms i and 1 which are dominated by i^2 as i -> +Inf. => g(i) = sum(j=1, j < i*i; h(j)) = sum(j=1, j < i*i; i^2) = i*i * i^2 = i^4 => f(n) = sum(i=1; i < 2n; g(i)) = sum(i=1; i < 2n; i^4) <= sum(i=1; i < 2n; 32.n^4) // Here just cap every i^4 with (2n)^4 <= 64.n^5 => f(n) = O(n^5) Bottom line The difference of complexities between algorithms A and B comes from the fact that: You have i values of j for which i%j = 1 You have i^2 - i + 1 values of j for which i%j <> 0
VHDL Syntax error in user defined package RNG for genetic algorithm in line number 5
Library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Type arr is array (1 to mut_bits) of integer; type chrom_matrix is array (1 to pop_size) of std_logic_vector(1 to n_comp); type fitness_arr is array (1 to pop_size) of integer range 0 to 1000; --type fitness_arr1 is array(1 to pop_size) of real; type adj_matrix is array (1 to n_comp,1 to n_comp) of bit; function evalfnc (signal chromosome: in std_logic_vector(1 to 8); signal cut_info:adj_matrix) return integer; procedure randg (variable x,y,t:in integer range 0 to 1000; variable z: out integer); procedure convert_bit(variable a:in integer;variable y:out std_logic_vector(8 downto 1)); end rng; package body rng is procedure randg (variable x,y,t:in integer range 0 to 1000; variable z: out integer) is variable val, a:integer range 0 to 1000:= 0; begin if x>y then a:= x-y; else a:= y-x; end if; if t > 3*a then val:= (t-a)/2; elsif t > a then val:= t-a; else val:= (x+y+t)/2; end if; z:= val; end randg; function evalfnc (signal chromosome: in std_logic_vector(1 to 8); signal cut_info:adj_matrix) return integer is variable fitness: integer range 0 to 500:= 0; variable cut_val: integer range 0 to 15:= 0; variable max_fit:integer range 0 to 360:=100; begin for i in 1 to n_comp loop for j in 1 to n_comp loop if cut_info(i,j)= ‘1’ then cut_val:= cut_val +1; end if; end loop; end loop; fitness := max_fit - cut_val; return fitness; end evalfnc; procedure convert_bit(variable a:in integer ; variable y:out std_logic_vector(8 downto 1)) is variable no:std_logic_vector(8 downto 1):=”00000000”; variable num: integer range 0 to 256; begin num:= a; if num <= 255 and num>= 128 then no(8):=’1’; num:=num - 128; end if; if num < 128 and num >= 64 then no(7):=’1’; num:=num - 64; end if; if num < 64 and num >= 32 then no(6):=’1’; num:=num −32; end if; if num < 32 and num >= 16 then no(5):=’1’; num:=num - 16; end if; if num < 16 and num >= 8 then no(4):=’1’; num:=num - 8; end if; if num < 8 and num >= 4 then no(3):=’1’; num:=num - 4; end if; if num < 4 and num >= 2 then no(2):=’1’; num:=num - 2; end if; if num < 2 then no(1):=’1’; end if; y:= no; end convert_bit; end rng;
Line 5 should read package rng is.
Time complexity of this while loop?
What's the time complexity of this loop? j=2 while(j <= n) { //body of the loop is Θ(1) j=j^2 }
You have j = 2 and each loop : j = j^2 The pattern is : 2 = 2^(2^0) 2*2 = 2^(2^1) 4*4 = 2^(2^2) 16*16 = 2^(2^3) Which can be seen as : 2^(2^k) with k being the number of iteration Hence loop stops when : 2^(2^k) >= n log2(2^(2^k)) >= log2(n) 2^k >= log2(n) log2(2^k) >= log2(n) k >= log2(log2(n)) the complexity is log2(log2(n))