How to derive the loop invariant? - loops

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.

Related

Make 2 numbers reach their target numbers at the same time

I'm trying to code a mouse drag function in C. Basically, i want X to reach targetX, and Y to reach targetY at the same time. For example:
x = 0, y = 0;
targetX = 10, targetY = 20;
I want to make x reach targetX by the time y reaches targetY. I want it to loop until both x and y reach their target number, incrementing them by 1 each time to actually achieve that. So, at one point, x would be 9, and y would be 19, then it would increment them each by 1, causing them to both equal their target numbers, instead of x reaching targetX first, then y getting incremented solo (which is what my current code does). Also, i need it to be able to decrement (instead of increment) x or y (or both), as well.
Here is what i have now:
for (x; x < targetX || x > targetX;) {
x = (x < targetX) ? x + 1 : x - 1;
y = (y < targetY) ? y + 1 : y - 1;
mouse_move(x, y);
}
for (y; y < targetY || y > targetY;) {
y = (y < targetY) ? y + 1 : y - 1;
mouse_move(x, y);
}
It doesn't have to be in C, i'm just looking for a way to make x and y reach their target numbers at the same time.
Save the initial x.
Save the initial y.
delta x = target x - initial x
delta y = target y - initial y
num steps = max of the deltas (or whatever you want)
For step = 1 .. num steps,
fraction = step / num steps
x = initial x + ( fraction * delta x )
y = initial y + ( fraction * delta y )
Move the mouse

What is the fastest way to determine n^m = m^n if m != n?

It's one of the questions from the practice section in hackerearth. We need to determine whether m^n = n^m. It is trivial when n = m, so we focus on m != n.
1 <= m, n <= 10^10000
What I have tried is
n^m = m^n implies
m*log(n) = n*log(m)
But the problem is how to take log of such a huge number? Is there an alternative way of checking equality?
Let's do some math to determine how to program for solutions:
It is easy to see that neither n nor m can equal 1 as they must be different and cannot be null. Let's look for solutions where 1 < n < m.
As you correctly stated, nm = mn implies m.log(n) = n.log(m)
hence we are looking for solutions to m / log(m) = n / log(n) and 1 < n < m.
We can study the function f(x) = x / log(x) for x > 1:
Its derivative is f'(x) = (log(x) - 1) / log(x)2
The derivative has a single zero at x = e, f(x) is strictly decreasing between x = 1 and x = e and strictly increasing from x = e all the way to infinity.
Any 2 distinct numbers n and m such that f(n) = f(m), n < m must be such that 1 < n < e and m > e
The only possible integer value for n is 2 and it happens to be a solution with the corresponding value of m as 4, there is no other integer in the interval 1 to e.
Hence the only solutions are n=2, m=4 and n=4, m=2
Here is a C program to output all possible results:
#include <stdio.h>
int main() {
printf("2 4\n");
printf("4 2\n");
return 0;
}

Solving compound assignment expressions

Okay, I know the output for the expression (x *= y = z = 4;) is 40; but how exactly did we get 40? Can you please show me step by step.
I thought the precedence is from right to left so (2 * 4) = (z =4), I don't understand
#include <stdio.h>
#define PRINTX printf("%d\n",x)
int main (void){
int x = 2, y, z;
x *= 3 + 2;
PRINTX;
x *= y = z = 4;
PRINTX;
x = y == z;
PRINTX;
x == ( y = z );
PRINTX;
return 0;
}
No, the only way that assignment can be evaluated here is right to left.
First, note that x *= 99, for example, is shorthand for x = x * 99.
With that said,
x *= y = z = 4;
is equivalent to
z = 4;
y = z;
x *= y; // This is shorthand for x = x * 4
Consider what would happen if you tried to evaluate it the other way around:
// y is unininitialized
x *= y;
y = z;
z = 4;
It would fail.
So really,
// x = 2
int x = 2, y, z;
// x = x * (3 + 2) = x * 5 = 2 * 5 = 10
x *= 3 + 2;
// x = x * 4 = 10 * 4 = 40
x *= y = z = 4;
This can be rewritten as
int x, y, z;
x = 2; // x = 2
x = x * (3 + 2); // This is 2 * 5, so x = 10 after this
z = 4; // z = 4
y = z; // y = 4
x = x * y; // x = 10 * 4 = 40
And that's how you end up with 40.
All of the assignment operators have equal precedence, and right-to-left associativity (which affects what happens when multiple operators of equal precedence are present in an expression).
This means x *= y = z = 4 is equivalent to x *= (y = (z = 4)). z = 4 must be evaluated first (which assigns z to 4, and gives a result of 4). The assignment y = ... then gives the value y the value of 4, and also produces a result of 4. The assignment x *= ... then multiples x (which has a value 10) by 4, giving a result of 40.
(The reason x *= 3 + 2 gives x the value 10 is that addition has higher precedence than assignment, so x *= 3+2 is equivalent to x *= (3 + 2) rather than (x *= 3) + 2.)
If the assignment operators were instead left-to-right associative, x *= y = z = 4 would be equivalent to (((x *= y) = y) = z) = 4 which would not compile.
You have:
int x = 2, y, z;
x *= 3 + 2;
This is a shorthand for x = x * (3 + 2), which evaluates to 10 given that x starts at 2.
PRINTX;
x *= y = z = 4;
After this, y == z and both are set to 4; and x is 4 times its previous value of 10, hence 40.
PRINTX;
x = y == z;
This compares y and z; they're equal, so x is assigned 1 (comparisons always evaluate to 0 or 1).
PRINTX;
x == ( y = z );
This assigns z to y (leaving the value unchanged at 4); nominally, this is compared with x but the compiler can ignore the comparison. Therefore, x is unchanged and still 1.

OCaml issue Loop in Loop

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.

Control Instructions in C

I am not understanding for loop statement and expression following it. Please do help me understand.
#include<stdio.h>
int main()
{
int x = 1;
int y = 1;
for( ; y ; printf("%d %d\n",x,y))
y = x++ <= 5;
return 0;
}
And the output I got
2 1
3 1
4 1
5 1
6 1
7 0
y = x++ <= 5; ==> y = (x++ <= 5); ==> first compare x with 5 to check whether x is small then or equals to 5 or not. Result of (x++ <= 5) is either 1, 0 assigned to y,
As x becomes > 5, (x++ <= 5) becomes 0 so y = 0 and condition false and loop break,
Basically the for syntax is:
for(StartCondition; Test; PostLoopOperation) DoWhileTestPasses;
In this case:
StartCondition == None
Test == (y != 0)
PostLoopOperation == do some printing
DoWhileTestPasses == set y to zero if x > 5 otherwise to non-zero THEN increment x.
Which is all rather bad practice because it is confusing.
Would be better written as:
int x=0;
int y=0;
for(y=0; y = (x <= 6); x++)
{
printff("%d %d\n",x,y);
}
return(0);
In y = x++ <= 5;, y stores the value that is output by the condition x++ <= 5 (here x++ is post increment). If the condition is true then y = 1 else y = 0.
for( ; y ; printf("%d %d\n",x,y))
In the for loop you are printing the values of x and y after executing the for loop body.
Initialize your variables:
int x = 1; int y = 1;
There are 3 statements for the for loop: -1. Initialize, 2. Condition, 3. Iteration:increment/decrement
In your case, you did not provide the initialize condition, however, you have the part of condition and incrementation. I do not think your for loop is used in the correct way.
You should swap the part of incrementation with your body like this:
for(; y; y = x++ <= 5;)
printf("%d %d\n", x, y)
First, you check whether the condition is true or not, y is true or not. Then, you print x and y out. Then, the part of incrementation is executed, x++ <= 5 or not. The result is assigned to y. It does so until your condition is false, y == false.
NOTE: For the good programming, you should enclose your body with a curly braces.
similar to this
int x = 1;
for( int y = 1; y!=0 ; )
{
if (x++ <= 5)
{
y = 1;
}
else
{
y = 0;
}
printf("%d %d\n",x,y);
}
Perhaps this slightly transformed (but functionally equal) code will help:
int x = 1;
int y = 1;
while (y) {
y = (x <= 5);
x = x + 1;
printf("%d %d\n", x, y)
}

Resources