OCaml issue Loop in Loop - loops

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.

Related

What's an inductive invariant for this piece of code?

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.

Convert c code to haskell code using recursion instead of loops (no lists)

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'

Determining time complexity of a specific function

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...

How to derive the loop invariant?

Given the following code fragment, where x is a number.
{ y >= 0 }
z = 0
n = y
while (n > 0) begin
z = z + x
n = n – 1
end
What does it compute? Prove it, showing how you derive the loop invariant.
How can I do that please?
This example is known like most correct program, because it is proved in every software verification course. Here is listing of the program with invariants on every step:
{ y >= 0 }
z = 0 // invariant: z = 0
n = y // invariant: n = y and z = 0
while (n > 0) begin // loop invariant: y * x - n * x = z
z = z + x
n = n – 1
end
// Final invariant: n = 0 and y * x = z
All theoretical details for this example are provided in my paper page 118.
For given X and Y it computes X * Y.
at the beginning, value of the Z is zero, and the N = Y (loop's variable which will countdown in our loop).
the loop executes Y times and in every time that it executes, it accumulates the X to the Z.
finally, when the N reached to 0 the loop will terminate, then the value of Z should be X * Y.

Filtering out Non-integers in my array OCTAVE/MATLAB

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.

Resources