For this piece of code:
// n is a user input that can be any integer
s = 0
i = 0
while i < n:
s = s + 1
i = i + 1
return s
I would like to prove that the post condition is if n > 0 then s = sum(0, n) else s = 0 where sum(s,e) just adds 1 from s to e exclusive, starting from initial value of 0.
I thought an invariant is
if n > 0 and i < n then s = sum(0, i) else s = 0 but I can't get it to be proven in Coq or z3. Any hints?
You seem to imply that this algorithm computes the sum but it doesn't actually do that. Instead, it'll count up to n. Perhaps what you intended is:
i = 0
s = 0
while i < n:
i = i+1
s = s+i
Note that we increment s by i, not by 1 as in your program.
Assuming this is the intended program, then a good invariant would be:
s is the sum of all numbers upto and including i
i is at most n
In more programmatic notation:
s == i*(i+1)/2 && i <= n
To see why, remember that the invariant has to hold before and after each loop iteration; and when the loop condition is false, it needs to imply your post-condition. That's why you need the conjunct i <= n, so that when you exit the loop, s will contain the sum indeed.
How about this solution:
// Function left unimplemented, for simplicity
function sum(s: Int, e: Int): Int
ensures result == e - s
method foo(n: Int) returns (s: Int)
requires 0 <= n
{
var i: Int := 0
s := 0
while (i < n)
invariant s == n - sum(i, n)
{
s := s + 1
i := i + 1
}
}
Language and tool are called Viper. You can try your example online (the web interface is somewhat slow and unstable), or use the VSCode plugin.
Related
I want to convert the following c code to haskell code, without using lists. It returns the number of occurrences of two numbers for a given n , where n satisfies n=(a*a)*(b*b*b).
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void) {
int n = 46656;
int i,j,counter=0,res=1;
int tr = sqrt(n);
for(i=1; i<=tr; i++) {
for(j=1; j<=tr; j++) {
res = (i*i) * (j*j*j) ;
if(res==n) {
counter=counter+1;
}
printf("%d\n",res);
}
}
printf("%d\n",counter);
}
I've managed to do something similar in haskell in regarding to loops, but only for finding the overall sum. I find difficult implementing the if part and counter part(see on c code) in haskell also. Any help much appreciated! Heres my haskell code also:
sumF :: (Int->Int)->Int->Int
sumF f 0 = 0
sumF f n = sumF f (n-1) + f n
sumF1n1n :: (Int->Int->Int)->Int->Int
sumF1n1n f 0 = 0
sumF1n1n f n = sumF1n1n f (n-1)
+sumF (\i -> f i n) (n-1)
+sumF (\j -> f n j) (n-1)
+f n n
func :: Int->Int->Int
func 0 0 = 0
func a b = res
where
res = (a^2 * b^3)
call :: Int->Int
call n = sumF1n1n func n
I guess an idiomatic translation would look like this:
n = 46656
tr = sqrt n
counter = length
[ ()
| i <- [1..tr]
, j <- [1..tr]
, i*i*j*j*j == n
]
Not that it isn't possible, but definitely not the best looking:
counter n = go (sqrt n) (sqrt n)
where
go 0 _ = 0
go i tr = (go2 tr 0 i) + (go (i - 1) tr)
go2 0 c i = c
go2 j c i = go2 (j - 1) (if i^2 * j^3 == n then c + 1 else c) i
A general and relatively straightforward way to translate imperative code is to replace each basic block with a function, and give it a parameter for every piece of state it uses. If it’s a loop, it will repeatedly tail-call itself with different values of those parameters. If you don’t care about printing the intermediate results, this translates straightforwardly:
The main program prints the result of the outer loop, which begins with i = 1 and counter = 0.
main = print (outer 1 0)
where
These are constants, so we can just bind them outside the loops:
n = 46656
tr = floor (sqrt n)
The outer loop tail-calls itself with increasing i, and counter updated by the inner loop, until i > tr, then it returns the final counter.
outer i counter
| i <= tr = outer (i + 1) (inner 1 counter)
| otherwise = counter
where
The inner loop tail-calls itself with increasing j, and its counter (counter') incremented when i^2 * j^3 == n, until j > tr, then it returns the updated counter back to outer. Note that this is inside the where clause of outer because it uses i to calculate res—you could alternatively make i an additional parameter.
inner j counter'
| j <= tr = inner (j + 1) $ let
res = i ^ 2 * j ^ 3
in if res == n then counter' + 1 else counter'
| otherwise = counter'
This is a question from one of the old exams from algorithms and data structure that I recently came upon. I'm having a hard time understanding the solution.
I need to find big-O, big-ϴ and big-Ω bounds of a function:
void recursion(int n) {
int i;
if (n == 0) {
return;
}
for (i = 0; i < n; i++) {
recursion(i);
}
}
The solution is 2^n for all three and I can't understand why. I've tried writing things down and I can't even get close to the solution. I would appreciate if anyone would explain where the 2^n comes from here.
Let's look at a simpler recursion which is known to be O(2^n)
void fib(int n) {
if (n < 3) {
return 1;
} else {
return fib(n - 1) + fib(n - 2);
}
}
Here you can see, for the non-trivial case of n > 2, this will result in 2^(n-2) calls to itself. For example, if n = 5:
n = 5
n = 4
n = 3
n = 2
n = 1
n = 2
n = 3
n = 2
n = 1
There are 8 (2^3) recursive calls, because each call with n > 2 spawns two more recursive calls, so fib(n+1) has twice as many recursive calls as fib(n).
So for your example:
n = 3
n = 2
n = 1
n = 0
n = 0
n = 1
n = 0
n = 0
so we get 7 recursive calls when n = 3
for n = 4
n = 4
n = 3
n = 2
n = 1
n = 0
n = 0
n = 1
n = 0
n = 0
n = 2
n = 1
n = 0
n = 0
n = 1
n = 0
n = 0
Here, we have 15 calls. Looking at the execution tree above, you can see that recusrsion(4) is basically recursion(3) + recursion(3) + 1
n = 4
n = 3 // + 1
n = 2 //
n = 1 //
n = 0 // recursion(3)
n = 0 //
n = 1 //
n = 0 //
n = 0 //
n = 2 //
n = 1 //
n = 0 // recursion(3)
n = 0 //
n = 1 //
n = 0 //
n = 0 //
So in general, recursion(n + 1) will have one more recursive calls than 2 * recursion(n)....which is basically doubling for every +1 to n....which is O(2^n)
Let's denote the total runtime as f(n). Due to the loop in the function the f(n) is actually a sum of f(i) for i between 0 and n-1. That's a sum of n items. Let's try to simplify the expression. A standard trick in such situations is to find a complimentary equation. Let's see what is the value of f(n-1). Similary to the previous case, it's a sum of f(i) for i between 0 and n-2. So now we have 2 equations:
f(n)=f(1)+...+f(n-1)
f(n-1)=f(1)+...+f(n-2)
Let's subtract second from the first:
f(n)-f(n-1)=f(n-1)
--> f(n)=2f(n-1)
Now this is a homogeneous linear recurrence relation with constant coefficients.
The solution is immediate (see the link for more details):
f(n)=f(1)*2n=2n
Since this smells like a homework question, this answer is incomplete by design.
The usual trick behind these kind of problems is to create a recurrence equation. That is, the time complexity of recursion(k+1) is somehow related to the complexity of recursion(k). Just writing down the recurrence itself is not sufficient to prove the complexity, you have to demonstrate why the recurrence is true. But, for 2n, this suggests that recursion(k+1) takes twice as long as recursion(k).
Let T(k) denote the time complexity of recursion(k). Since recursion(0) returns immediately, let T(0) = 1. For k > 0, given the iterative implementation of recursion Thus You can inductively prove that T(k) = 2k.
r(n) = r(n-1)+r(n-2)+...+r(0) // n calls.
r(n-1) = r(n-2)+r(n-3)+...+r(0) // n-1 calls.
r(n-2) = r(n-3)+r(n-4)+...+r(0) // n-2 calls.
.
.
.
r(1) = r(0) // 1 call.
r(0) = return; // 0 call.
So,
r(n) = r(n-1)+r(n-2)+...+r(0) // n calls.
= 2 * (r(n-2)+...+r(0)) // 2 * (n - 1) calls.
= 2 * ( 2 * (r(n-3)+...+r(0)) ) // 2 * 2 * (n - 2) calls.
.
.
.
This follows that =>
2^(n-1) * (n - (n-1))
And that would be
2^n calls...
I am writing program to count Bell numbers,
it is my first big program in OCaml.
I want to use loop While in the loop While, but there is syntax error.
Please correct it. Thanks.
I'm using site http://try.ocamlpro.com/
let rec factorial n =
if n < 2
then 1
else
n * factorial(n-1)
let rec newton n k =
factorial n / (factorial k * factorial (n-k))
let bell = [|1;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0|]
let i = ref 2
let k = ref 0
let x = ref 0
let z = ref 0
let s = ref 0
here you need to choose number u want to calc e.g. 4
let n = ref 4
if !n != 0 || !n != 1 then
while !i <= !n do
while !k <= (!i-1) do
x := newton (!i-1) !k;
s := !s + (!x * bell.(!k));
k := !k + 1 ;
z := !k + 1
done
s:=0;
i:= !i + 1;
done
else
bell.(!n)<-1
should use Num to calc Bell numbers, but I first I I would like to make the program work on int
You can try to add ; after 1st done.
I want to know a algorithm to find out the maximum xor value of three elements of an array.
I have read about the maximum xor for two elements from an array but cannot understand how to apply it on finding the maximum value of XOR taking 3 elements of an array . Can someone point out a hint ?
Required complexity : less than O(N^3) where N is the number of elements in the array.
Example:
A = [1,2,3,4]
All Possible Triplets :-
1^2^3 = 0
1^2^4 = 7
1^3^4 = 6
2^3^4 = 5
Thus, the maximum XOR value is 7.
Edit :
I have thought of a solution having complexity O(N^2 * log(MAX)) and it has solved my purpose :D .
MAX = Maximum Value in the Array
Well, I have found a solution with complexity O(N^2 * log(MAX)) where MAX is the largest value in the array .
Let there be 3 elements X,Y,Z fron the array A.
where X = A[i] , Y = A[j] , Z = A[k] and i != j != k
We want the maximum value of (X^Y^Z) .
Let us assume W = X*Y.
Then we would like to find such a Z which give maximum value for W^Z and Z != X and Z != Y
Now this has been reduced to the problem of finding "Two elements whose XOR is maximum" which can be done for a given W in O(log(MAX)) using a Trie .
Explanation for Trie :
Let us assume W = 10001 here W is in binary .
Now we know 1^0 = 1 , 0^0 = 0 , 1^1 = 0 , so the maximum value we
can get for W^Z is when Z is 01110 because
W^Z will give = 11111.
But it is not necessary to have 15 or Base2(11111) in our array so
we would take the best possible option available.
So we will create a Trie of all the elements of the array
according to their binary representation.
If A = [1,2,7] , then 1 = 001 , 2 = 010 , 7 = 111 in
binary .
Then the Trie will look like :-
Top
/ \
0 1
/ \ \
0 1 1
\ / \
1 0 1
Now to lets assume W = 7 , and we want to find Z such that
W^Z is maximum (when Z = 000 ) then we will start at the Top and look if we have branch leading to 0 since the first bit of 7 is 1
, then we will down through that branch and then again look if we have
branch leading to 0 at 2nd bit , again we find it , then for the last
time we search for branch leading to a 0 at 3rd bit but we do not find
it , so we go down through the other branch which gives us Z =
001. Thus, the maximum W^Z will be 7^1 = 6 . Now , the
complexity of finding Z will be maximum height of the Trie which
will be log(MAX).
Thus , we have N*(N-1)/2 number of W's and for each W we can find the Maximum value of W^Z and if we take the Maximum from all the values of W^Z we will have our answer.
With three nested loop:
int max2=0,max3=0;
for (int i=0;i<arr.size();i++)
for (int j=0;j<arr.size();j++)
for (int k=0;k<arr.size();k++)
{
if (arr[i]^arr[j]>max2) // for 2 elements
max2 = arr[i]^arr[j];
if (arr[i]^arr[j]^arr[k]>max3) // for 3 elements
max3 = arr[i]^arr[j]^arr[k];
}
int max = max2; // for both
if (max3>max2)
max = max3;
following will do the O(N^3), but in an more optimized approach - not testing same combination more than once, not testing element against itself,
and somewhat optimized evaluation (xoring the first two elements once for all possible third elements)
Number of Xor operations performed will be:
n(n-1)(n-2)/6 + n(n-1)/2
Complexity is still n(n-1)(n-2)/6 ===> O(N^3) though.
unsigned int maxXor3(unsigned int* element, int len)
{
unsigned int max = 0;
unsigned int xor2 = 0;
unsigned int xor3 = 0;
int j = k = 0;
for (int i = 0 ; i < len ; i++)
{
for (j = i + 1 ; j < len ; j++)
{
xor2 = element[i] ^ element[j];
for(k = j + 1; k < len; k++)
{
xor3 = xor2 ^ element[k];
if (xor3 > max)
max = xor3;
}
}
}
return max;
}
I have a code that determines prime factors written as:
N=12345678
for i = 2 : N
q = 0;
while N/i == floor(N/i)
N = N/i;
q = q + 1;
end
if q > 0
fac=i
if N == 1
break
end
end
end
However, I want my desired values which are 2, 3 ,47, and 14593 into one single matrix.
How can I do this?
If as it seems your code is in MATLAB, you simply can do this:
N=12345678
fac = [];
for i = 2 : N
q = 0;
while N/i == floor(N/i)
N = N/i;
q = q + 1;
end
if q > 0
fac=[fac, i];
if N == 1
break
end
end
end
Did you try to do it yourself on purpose? You could use Matlab's factor function instead,
factor(N)
which gives the same result.