for (int i = 0; i < (n - 1); i++)
{
for (int j = 0; j < (n - i - 1); j++)
{
if (array[j] > array[j + 1])
{
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
I have replaced (i < n-1) with (i<n) and it works fine for all the test cases.
If 'n' is number of variables in array (i<n) doesn't any segmentation error as it access only last element for maximum value of i.
(if n =10, for a condition (i<n), maximum value of i could be 9 and it access last element i.e a[9].So there would be no segmentation error).
Then what is the purpose if i<n-1 in the outer loop of bubble sort?
In Dafny I am trying to make a Max polymorphic and high-order function that, given a sequence and a predicate, returns the longest subsequence that holds it. For instance, the longest increasing subsequence, or the longest subsequence in which all the elements are zero.
To do so, I designed a slow algorithm (given the P predicate and a S sequence):
1. Start an i pivot in the left and a j pivot in the same place.
2. Start the max_sequence = [] and the max_sequence_length = 0.
3. While i<S.length:
counter = 0
j = i
While max_sequence[i..j] satisfies P and j<S.length:
If counter > max_sequence_length:
max_sequence_length = counter
max_sequence = max_sequence[i..j]
Increment j
Increment i
4. Return max_sequence
You can see it implemented:
method maxPropertySequence<T>(P: seq<T> -> bool, sequ: seq<T>) returns (max_seq: seq<T>)
{
var i := 0;
var j := 0;
var longest := 0;
var the_sgmt := sequ;
var fresh_segmnt := sequ;
var counter := longest;
while i<(|sequ|)
decreases |sequ|-i
{
j := i;
counter := 0;
fresh_segmnt := [sequ[i]];
if P(fresh_segmnt)
{
j := j+1;
counter:=counter+1;
if counter>longest {
longest:=counter;
the_sgmt := fresh_segmnt;
}
while P(fresh_segmnt) && j<|sequ|
decreases |sequ|-j
{
fresh_segmnt := fresh_segmnt + [sequ[j]];
j := j+1;
counter:=counter+1;
if counter>longest {
longest:=counter;
the_sgmt := fresh_segmnt;
}
}
}
i := i+1;
}
return the_sgmt;
}
My question is: how can I verify that the Max function behaves as I expect? More concretely: which are the ensures I have to add?
I have thought something like: forall the subsequences of the original sequence, there is no subsequence that holds P and is longer than the_sgmt. But I do not know how to express it efficiently.
Thanks!
I wrote code for finding the (leftmost) longest subsequence of zeros from a given integer array. Since you can map sequ using the predicate, these two are almost identical problems.
// For a given integer array, let's find the longest subesquence of 0s.
// sz: size, pos: position. a[pos..(pos+sz)] will be all zeros
method longestZero(a: array<int>) returns (sz:int, pos:int)
requires 1 <= a.Length
ensures 0 <= sz <= a.Length
ensures 0 <= pos < a.Length
ensures pos + sz <= a.Length
ensures forall i:int :: pos <= i < pos + sz ==> a[i] == 0
ensures forall i,j :: (0 <= i < j < a.Length && getSize(i, j) > sz) ==> exists k :: i <= k <= j && a[k] != 0
{
var b := new int[a.Length]; // if b[i] == n, then a[i], a[i-1], ... a[i-n+1] will be all zeros and (i-n ==0 or a[i-n] !=0)
if a[0] == 0
{b[0] := 1;}
else
{b[0] := 0;}
var idx:int := 0;
while idx < a.Length - 1 // idx <- 0 to a.Length - 2
invariant 0 <= idx <= a.Length - 1
invariant forall i:int :: 0 <= i <= idx ==> 0 <= b[i] <= a.Length
invariant forall i:int :: 0 <= i <= idx ==> -1 <= i - b[i]
invariant forall i:int :: 0 <= i <= idx ==> (forall j:int :: i-b[i] < j <= i ==> a[j] == 0)
invariant forall i:int :: 0 <= i <= idx ==> ( 0 <= i - b[i] ==> a[i - b[i]] != 0 )
{
if a[idx + 1] == 0
{ b[idx + 1] := b[idx] + 1; }
else
{ b[idx + 1] := 0;}
idx := idx + 1;
}
idx := 1;
sz := b[0];
pos := 0;
// Let's find maximum of array b. That is the desired sz.
while idx < a.Length
invariant 1 <= idx <= b.Length
invariant 0 <= sz <= a.Length
invariant 0 <= pos < a.Length
invariant pos + sz <= a.Length
invariant forall i:int :: 0 <= i < idx ==> b[i] <= sz
invariant forall i:int :: pos <= i < pos + sz ==> a[i] == 0
invariant forall i, j:int :: (0 <= i < j < idx && getSize(i,j) > sz) ==> a[j-b[j]] != 0
{
// find max
if b[idx] > sz
{
sz := b[idx];
pos := idx - b[idx] + 1;
}
idx := idx + 1;
}
}
function getSize(i: int, j:int) : int
{
j - i + 1
}
Since I am new to dafny, any comments on style or anything are appreciated.
Good day to all! I wrote the Shell sort verification code, but I can’t build the correct loop invariants.It is not possible to correctly compose invariants and prove the correctness of the program... Please help me!
/*# predicate Sorted{L}(int* a, integer m, integer n) =
# \forall integer i, j; m <= i <= j < n ==> a[i] <= a[j];
*/
/*# predicate GapSorted(int* a, integer m, integer n, integer gap) =
# \forall integer i, j; (m <= i <= j < n && j % gap == i % gap) ==> a[i] <=a[j];
*/
/*#
# requires \valid(arr + (0..n-1));
# requires n > 1;
# ensures GapSorted(arr, 0, n, 1);
*/
void shell_lr(int *arr, int n) {
int i, j, tmp, gap;
/*# ghost int gap1 = n
# loop invariant 0 <= gap1 <= n/2;
# loop invariant gap1 < n/2 ==> GapSorted(arr, 0, n, gap+1);
# //loop invariant \forall integer k; gap < k <= n/2 ==> GapSorted(arr, 0, n, k);
# loop variant gap1;
*/
for (gap = n / 2; gap > 0; gap--) {
/*# loop invariant 0 <= i <= n;
# //loop invariant \forall integer m; gap < m <= n/2 ==> GapSorted(arr, 0, i, m);
# loop invariant GapSorted(arr, 0, i, gap);
# loop variant n - i; */
for (i = gap; i < n; i++) {
tmp = arr[i];
/*#
# loop invariant 0 <= j <= i;
# //loop invariant arr[j] >= tmp;
# loop invariant \forall integer k; (j < k <= i) ==> GapSorted(arr, 0, i, k);
#// loop invariant \forall integer k; j <= k <= gap ==> GapSorted(arr, k, i, gap);
# loop variant j;
#*/
for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
arr[j] = arr[j - gap];
//# assert arr[j] >= arr[j - gap];
//# assert tmp < arr[j - gap];
}
//# assert j>=0;
arr[j] = tmp;
}
//# assert i == n;
//# assert GapSorted(arr, 0, i, gap);
//# assert gap > 0;
// assert GapSorted(arr, 0, n, gap);
}
First, the code you provided is not syntactically correct:
a brace closing the function's body is missing
the ghost declaration of gap1 cannot be mixed with the loop annotations. This should be two distinct annotations. Anyway, I don't see the use of gap1 (especially as it is not updated inside the loop), everything can be expressed with gap. If what you were trying to achieve was to have a local variable for the whole loop annotation, this is not possible in ACSL: you have the \let gap1 = ...; ... construction, but its scope is only a single term/predicate: you can't share it with across two loop invariants (or loop invariants and loop variant)
Now, your most pressing issue here is the lack of loop assigns in your loop annotations. You must provide such clauses for all your loops, or WP will not be able to assume much about the state of the program after the loops (see for instance this answer for more detail). You might also want to strengthen a bit your invariant on i in the middle loop as gap <= i <= n, but this is a detail.
With the following loop assigns, most of your annotations gets proved (Frama-C 20.0 Calcium with -wp -wp-rte).
/*# predicate Sorted{L}(int* a, integer m, integer n) =
# \forall integer i, j; m <= i <= j < n ==> a[i] <= a[j];
*/
/*# predicate GapSorted(int* a, integer m, integer n, integer gap) =
# \forall integer i, j; (m <= i <= j < n && j % gap == i % gap) ==> a[i] <=a[j];
*/
/*#
# requires \valid(arr + (0..n-1));
# requires n > 1;
# ensures GapSorted(arr, 0, n, 1);
*/
void shell_lr(int *arr, int n) {
int i, j, tmp, gap;
/*#
# loop invariant 0 <= gap <= n/2;
# loop invariant gap < n/2 ==> GapSorted(arr, 0, n, gap+1);
# loop assigns gap, i, j, tmp, arr[0 .. n - 1];
# //loop invariant \forall integer k; gap < k <= n/2 ==> GapSorted(arr, 0, n, k);
# loop variant gap;
*/
for (gap = n / 2; gap > 0; gap--) {
/*# loop invariant gap <= i <= n;
# //loop invariant \forall integer m; gap < m <= n/2 ==> GapSorted(arr, 0, i, m);
# loop invariant GapSorted(arr, 0, i, gap);
loop assigns i,j,tmp,arr[0..n-1];
# loop variant n - i; */
for (i = gap; i < n; i++) {
tmp = arr[i];
/*#
# loop invariant 0 <= j <= i;
# //loop invariant arr[j] >= tmp;
# loop invariant \forall integer k; (j < k <= i) ==> GapSorted(arr, 0, i, k);
#// loop invariant \forall integer k; j <= k <= gap ==> GapSorted(arr, k, i, gap);
loop assigns j, arr[gap .. i];
# loop variant j;
#*/
for (j = i; j >= gap && arr[j - gap] > tmp; j -= gap) {
arr[j] = arr[j - gap];
//# assert arr[j] >= arr[j - gap];
//# assert tmp < arr[j - gap];
}
//# assert j>=0;
arr[j] = tmp;
}
//# assert i == n;
//# assert GapSorted(arr, 0, i, gap);
//# assert gap > 0;
// assert GapSorted(arr, 0, n, gap);
}
}
What remains to be proved are the GapSorted invariants for the two inner loops, which probably require more work and an answer much longer than what is fit for this format.
This is the algorithm:
// Precondition: n > 0
l = -1;
r = n;
while (l+1 != r) {
m = (l+r)/2;
// I && m == (l+r)/2
if (a[m] <= x) {
l = m;
} else {
r = m;
}
}
// Postcondition: -1 <= l < n
I have done some research and narrowed the invariant down to if x is in a[0 .. n-1] then a[l] <= x < a[r].
I have no idea how to progress from there though. The precondition seems too broad, so I'm having trouble showing that P -> I.
Any help is extremely appreciated. These are the logic rules that can be used to prove the algorithm's correctness:
The invariant is
-1 <= l and l + 1 < r <= n and a[l] <= x < a[r]
with the implicit convention a[-1] = -∞, a[n] = +∞.
Then in the if statement
a[l] <= x < a[r] and a[m] <= x implies a[m] <= x < a[r]
and
a[l] <= x < a[r] and x < a[m] implies a[l] <= x < a[m].
In either case, the assignment establishes a[l] <= x < a[r].
At the same time, -1 <= l and l + 1 < r <= n ensures -1 < m < n, so that the evaluation of a[m] is possible.
Upon termination, l + 1 = r and by the invariant
-1 <= l < n and a[l] <= x < a[l + 1].
I read the article about
How to determine the longest increasing sub-sequence using dynamic programming
with this algorithm:
int maxLength = 1, bestEnd = 0;
DP[0] = 1;
prev[0] = -1;
for (int i = 1; i < N; i++)
{
DP[i] = 1;
prev[i] = -1;
for (int j = i - 1; j >= 0; j--)
if (DP[j] + 1 > DP[i] && array[j] < array[i])
{
DP[i] = DP[j] + 1;
prev[i] = j;
}
if (DP[i] > maxLength)
{
bestEnd = i;
maxLength = DP[i];
}
}
but i want to know how to solve this problem with this condition that we can take the arrays with joined integers.
For example: 1,5,3,1,5,6,7,8,1,2,9
we can have this set:1,3,5,6,7,8,12 for solution
that 12 is joint form 1 and 2
so conditions are:
The input array includes 1-9 numbers! and the integers can joined from few other integers.
Original problem
dp[i] = max(DP[j] + 1, a[j] < a[i])
Your problem
Let:
a[x,y] = a[x] + a[x + 1] + ... + a[y] (+ means concatenate)
So:
f[x,y] = max(DP[j] + 1, a[j] < a[x,y], j < x)
dp[i] = max(f[i,j], 0 <= j <= i) = max(
max(DP[j] + 1, a[j] < a[i], j < i) # f(i, i)
max(DP[j] + 1, a[j] < a[i-1, i], j < i - 1) # f(i-1, i)
...
)
If you still have some problems, please don't hesitate to leave a comment here.