Base 2 exponential of native int - native

Some algorithms (allocate a binary tree...) need to compute a base 2 exponential. How to compute it for this native type?
newtype {:nativeType "uint"} u32 =
x: nat | 0 <= x < 2147483648
This is an obvious try:
function pow2(n: u32): (r: u32)
requires n < 10
{
if n == 0 then 1 else 2 * pow2(n - 1)
}
It fails because Dafny doubts that the product stays below u32's max value. How to prove that it's value is below 2**10?

In this case, it is more convenient to first define the unbounded version of the function, and then prove a lemma showing that when n < 10 (or n < 32, even) it is in bounds.
function pow2(n: nat): int
{
if n == 0 then 1 else 2 * pow2(n - 1)
}
lemma pow2Bounds(n: nat)
requires n < 32
ensures 0 <= pow2(n) < 0x100000000
{ /* omitted here; two proofs given below */ }
function pow2u32(n: u32): u32
requires n < 32
{
pow2Bounds(n as nat);
pow2(n as nat) as u32
}
Intuitively, we might expect the lemma to go through automatically, because there are only a small number of cases to consider: n = 0, n = 1, ... n = 31. But Dafny will not perform such case analysis automatically. Instead, we have a couple of options.
First proof
First, we can prove a more general property, which, by the magic of inductive reasoning, is easier to prove, despite being stronger than what we need.
lemma pow2Monotone(a: nat, b: nat)
requires a < b
ensures pow2(a) < pow2(b)
{} // Dafny is able to prove this automatically by induction.
The lemma then follows.
lemma pow2Bounds(n: nat)
requires n < 32
ensures 0 <= pow2(n) < 0x100000000
{
pow2Monotone(n, 32);
}
Second proof
Another way to prove it is to tell Dafny it should unroll pow2 up to 32 times, using a :fuel attribute. These 32 unrollings are essentially the same as asking Dafny to do case analysis on each possible value. Dafny can then complete the proof without additional help.
lemma {:fuel pow2,31,32} pow2Bounds(n: nat)
requires n < 32
ensures 0 <= pow2(n) < 0x100000000
{}
The :fuel attribute is (lightly) documented in the Dafny Reference Manual in Section 24.

A bit of a cheat, but with so narrow a domain, this works very well.
const pow2: seq<u32> :=
[0x1, 0x2, 0x4, 0x8, 0x10, 0x20];
lemma pow2_exponential(n: u32)
ensures n == 0 ==> pow2[n] == 1
ensures 0 < n < 6 ==> pow2[n] == 2 * pow2[n - 1]
{}

Related

Axiomatic Semantics - How to calculate a weakest precondition of a program

Assuming the post-condition, how can I compute the weakest pre-condition of a program containing two statements?
For example :
a=x;
y = 0
{x = y + a}
Another example:
y = x;
y = x + x + y
{y = 3x ^ z> 0}
I tried to solve them but both questions resulted in pre-conditions or post-condition that are identical to the statement and I don't know if this is valid.
for example, the precondition of the last statement is "y=x" , thus it is the post condition of the preceding statement which is " y=x" as well
You can apply the rules of Hoare Logic here. Specifically, for the examples you have, you only need the rule for assignment:
{ P[E/x] } x = E { P }
Here, P[E/x] means take P and substitute (i.e. replace) all occurrences of x with E. For example, if P is x == 0 then P[0/x] gives 0 == 0.
To calculate the weakest precondition, you start from the end and work backwards. For your first example, we start with the last statement:
{ ??? } y = 0 { x == y + a }
The goal is to determine something suitable for ???. Applying our rule for assignment above, we can see that this is a solution:
{ x == 0 + a } y = 0 { x == y + a }
We can further simplify this to { x == a }. Then, we move on to address the statement before y = 0, and so on.

Time complexity of this code?

So these are the for loops that I have to find the time complexity, but I am not really clearly understood how to calculate.
for (int i = n; i > 1; i /= 3) {
for (int j = 0; j < n; j += 2) {
... ...
}
for (int k = 2; k < n; k = (k * k) {
...
}
}
For the first line, (int i = n; i > 1; i /= 3), keeps diving i by 3 and if i is less than 1 then the loop stops there, right?
But what is the time complexity of that? I think it is n, but I am not really sure. The reason why I am thinking it is n is, if I assume that n is 30 then i will be like 30, 10, 3, 1 then the loop stops. It runs n times, doesn't it?
And for the last for loop, I think its time complexity is also n because what it does is
k starts as 2 and keeps multiplying itself to itself until k is greater than n.
So if n is 20, k will be like 2, 4, 16 then stop. It runs n times too.
I don't really think I am understanding this kind of questions because time complexity can be log(n) or n^2 or etc but all I see is n.
I don't really know when it comes to log or square. Or anything else.
Every for loop runs n times, I think. How can log or square be involved?
Can anyone help me understanding this? Please.
If you want to calculate the time complexity of an algorithm, go through this post here: How to find time complexity of an algorithm
That said, the way you're thinking about algorithm complexity is small and linear. It helps to think about it in orders of magnitude, then plot it that way. If you take:
x, z = 0
for (int i = n; i > 1; i /= 3) {
for (int j = 0; j < n; j += 2) {
x = x + 1
}
for (int k = 2; k < n; k = (k * k) {
z = z + 1
}
}
and plot x and z on a graph where n goes from 1 -> 10 -> 100 -> 1000 -> 10^15 or so, you'll get an answer which looks like an n^2 graph. When analyzing algorithmic complexity you're primarily interested in maximum the number of times, in either the worst or most common case, your inputs are looped through omitting constants. So in this case I would expect your algorithm to be O(n^2)
For further reading, I suggest https://en.wikipedia.org/wiki/Introduction_to_Algorithms ; it's not exactly easy but covers this in depth.

Find nth int with 10 set bits

Find the nth int with 10 set bits
n is an int in the range 0<= n <= 30 045 014
The 0th int = 1023, the 1st = 1535 and so on
snob() same number of bits,
returns the lowest integer bigger than n with the same number of set bits as n
int snob(int n) {
int a=n&-n, b=a+n;
return b|(n^b)/a>>2;
}
calling snob n times will work
int nth(int n){
int o =1023;
for(int i=0;i<n;i++)o=snob(o);
return o;
}
example
https://ideone.com/ikGNo7
Is there some way to find it faster?
I found one pattern but not sure if it's useful.
using factorial you can find the "indexes" where all 10 set bits are consecutive
1023 << x = the (x+10)! / (x! * 10!) - 1 th integer
1023<<1 is the 10th
1023<<2 is the 65th
1023<<3 the 285th
...
Btw I'm not a student and this is not homework.
EDIT:
Found an alternative to snob()
https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
int lnbp(int v){
int t = (v | (v - 1)) + 1;
return t | ((((t & -t) / (v & -v)) >> 1) - 1);
}
I have built an implementation that should satisfy your needs.
/** A lookup table to see how many combinations preceeded this one */
private static int[][] LOOKUP_TABLE_COMBINATION_POS;
/** The number of possible combinations with i bits */
private static int[] NBR_COMBINATIONS;
static {
LOOKUP_TABLE_COMBINATION_POS = new int[Integer.SIZE][Integer.SIZE];
for (int bit = 0; bit < Integer.SIZE; bit++) {
// Ignore less significant bits, compute how many combinations have to be
// visited to set this bit, i.e.
// (bit = 4, pos = 5), before came 0b1XXX and 0b1XXXX, that's C(3, 3) + C(4, 3)
int nbrBefore = 0;
// The nth-bit can be only encountered after pos n
for (int pos = bit; pos < Integer.SIZE; pos++) {
LOOKUP_TABLE_COMBINATION_POS[bit][pos] = nbrBefore;
nbrBefore += nChooseK(pos, bit);
}
}
NBR_COMBINATIONS = new int[Integer.SIZE + 1];
for (int bits = 0; bits < NBR_COMBINATIONS.length; bits++) {
NBR_COMBINATIONS[bits] = nChooseK(Integer.SIZE, bits);
assert NBR_COMBINATIONS[bits] > 0; // Important for modulo check. Otherwise we must use unsigned arithmetic
}
}
private static int nChooseK(int n, int k) {
assert k >= 0 && k <= n;
if (k > n / 2) {
k = n - k;
}
long nCk = 1; // (N choose 0)
for (int i = 0; i < k; i++) {
// (N choose K+1) = (N choose K) * (n-k) / (k+1);
nCk *= (n - i);
nCk /= (i + 1);
}
return (int) nCk;
}
public static int nextCombination(int w, int n) {
// TODO: maybe for small n just advance naively
// Get the position of the current pattern w
int nbrBits = 0;
int position = 0;
while (w != 0) {
final int currentBit = Integer.lowestOneBit(w); // w & -w;
final int bitPos = Integer.numberOfTrailingZeros(currentBit);
position += LOOKUP_TABLE_COMBINATION_POS[nbrBits][bitPos];
// toggle off bit
w ^= currentBit;
nbrBits++;
}
position += n;
// Wrapping, optional
position %= NBR_COMBINATIONS[nbrBits];
// And reverse lookup
int v = 0;
int m = Integer.SIZE - 1;
while (nbrBits-- > 0) {
final int[] bitPositions = LOOKUP_TABLE_COMBINATION_POS[nbrBits];
// Search for largest bitPos such that position >= bitPositions[bitPos]
while (Integer.compareUnsigned(position, bitPositions[m]) < 0)
m--;
position -= bitPositions[m];
v ^= (0b1 << m--);
}
return v;
}
Now for some explanation. LOOKUP_TABLE_COMBINATION_POS[bit][pos] is the core of the algorithm that makes it as fast as it is. The table is designed so that a bit pattern with k bits at positions p_0 < p_1 < ... < p_{k - 1} has a position of `\sum_{i = 0}^{k - 1}{ LOOKUP_TABLE_COMBINATION_POS[i][p_i] }.
The intuition is that we try to move back the bits one by one until we reach the pattern where are all bits are at the lowest possible positions. Moving the i-th bit from position to k + 1 to k moves back by C(k-1, i-1) positions, provided that all lower bits are at the right-most position (no moving bits into or through each other) since we skip over all possible combinations with the i-1 bits in k-1 slots.
We can thus "decode" a bit pattern to a position, keeping track of the bits encountered. We then advance by n positions (rolling over in case we enumerated all possible positions for k bits) and encode this position again.
To encode a pattern, we reverse the process. For this, we move bits from their starting position forward, as long as the position is smaller than what we're aiming for. We could, instead of a linear search through LOOKUP_TABLE_COMBINATION_POS, employ a binary search for our target index m but it's hardly needed, the size of an int is not big. Nevertheless, we reuse our variant that a smaller bit must also come at a less significant position so that our algorithm is effectively O(n) where n = Integer.SIZE.
I remain with the following assertions to show the resulting algorithm:
nextCombination(0b1111111111, 1) == 0b10111111111;
nextCombination(0b1111111111, 10) == 0b11111111110;
nextCombination(0x00FF , 4) == 0x01EF;
nextCombination(0x7FFFFFFF , 4) == 0xF7FFFFFF;
nextCombination(0x03FF , 10) == 0x07FE;
// Correct wrapping
nextCombination(0b1 , 32) == 0b1;
nextCombination(0x7FFFFFFF , 32) == 0x7FFFFFFF;
nextCombination(0xFFFFFFEF , 5) == 0x7FFFFFFF;
Let us consider the numbers with k=10 bits set.
The trick is to determine the rank of the most significant one, for a given n.
There is a single number of length k: C(k, k)=1. There are k+1 = C(k+1, k) numbers of length k + 1. ... There are C(m, k) numbers of length m.
For k=10, the limit n are 1 + 10 + 55 + 220 + 715 + 2002 + 5005 + 11440 + ...
For a given n, you easily find the corresponding m. Then the problem is reduced to finding the n - C(m, k)-th number with k - 1 bits set. And so on recursively.
With precomputed tables, this can be very fast. 30045015 takes 30 lookups, so that I guess that the worst case is 29 x 30 / 2 = 435 lookups.
(This is based on linear lookups, to favor small values. By means of dichotomic search, you reduce this to less than 29 x lg(30) = 145 lookups at worse.)
Update:
My previous estimates were pessimistic. Indeed, as we are looking for k bits, there are only 10 determinations of m. In the linear case, at worse 245 lookups, in the dichotomic case, less than 50.
(I don't exclude off-by-one errors in the estimates, but clearly this method is very efficient and requires no snob.)

Binary Search, when should I increment high or low?

I am having difficult to understand how to increment low or high.
For instance, this is a question from leetcode:
Implement int sqrt(int x).
My code:
class Solution {
public:
int mySqrt(int x) {
if (x<=0) return 0;
int low=1, high=x, mid=0;
while (low<=high){ // should I do low<high?
mid=low+(high-low)/2;
if (x/mid==mid) return mid;
if (x/mid>mid) low= mid+1; //can I just do low=mid?
else high=mid-1; // can I do high =mid?
}
return high; //after breaking the loop, should I return high or low?
}
};
You see, after a condition is fufill, I don't know whether I should set low=mid OR low=mid+1. Why mid+1?
In general, I am having trouble to see whether I should increment low from mid point or not. I am also having trouble when should I include low <= high or low < high in the while loop.
Your algo is not binary search.
Also, it doesn't work.
Take example x = 5
Initial:
low = 1, high = 5
Iter 1:
mid = 3
5/3 = 1 so high = 4
Iter 2:
mid = 2.5 => 2 (because int)
5/2 = 2 (because int)
<returns 2>
For perfect square inputs, your algo will give correct results only through mid not high or low.
BTW you need to increase mid if x/mid > mid and you need to decrease it otherwise. Your method of increasing and decreasing mid is incrementing low, or decrementing high respectively.
This is OK, but this doesn't yield a binary search. Your high would be walking through all the integers from x to (2*sqrt - 1).
Please follow #sinsuren comment to a far better solution
This is Babylonian method for square root:
/*Returns the square root of n.*/
float squareRoot(float n)
{
/*We are using n itself as initial approximation
This can definitely be improved */
float x = n;
float y = 1;
float e = 0.000001; /* e decides the accuracy level*/
while(x - y > e)
{
x = (x + y)/2;
y = n/x;
}
return x;
}
For more understanding you can always follow this link

Haskell, function works when using numbers, but not with variables

I'm using ghci and I'm having a problem with a function for getting the factors of a number.
The code I would like to work is:
let factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]
It doesn't complain when I then hit enter, but as soon as I try to use it (with 66 in this case) I get this error message:
Ambiguous type variable 't0' in the constraints:
(Integral t0)
arising from a use of 'factors' at <interactive>:30:1-10
(Num t0) arising from the literal '66' at <interactive>:30:12-13
(RealFrac t0)
arising from a use of 'factors' at <interactive:30:1-10
Probable fix: add a type signature that fixes these type variable(s)
In the expression: factors 66
In the equation for 'it': it = factors 66
The following code works perfectly:
let factorsOfSixtySix = [x | x <- [1..truncate (66/2)], mod 66 x == 0]
I'm new to haskell, and after looking up types and typeclasses, I'm still not sure what I'm meant to do.
Use div for integer division instead:
let factors n = [x | x <- [1.. n `div` 2], mod n x == 0]
The problem in your code is that / requires a RealFrac type for n while mod an Integral one. This is fine during definition, but then you can not choose a type which fits both constraints.
Another option could be to truncate n before using mod, but is more cumbersome. After all, you do not wish to call factors 6.5, do you? ;-)
let factors n = [x | x <- [1..truncate (n/2)], mod (truncate n) x == 0]
If you put a type annotation on this top-level bind (idiomatic Haskell), you get different, possibly more useful error messages.
GHCi> let factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]
GHCi> :t factors
factors :: (Integral t, RealFrac t) => t -> [t]
GHCi> let { factors :: Double -> [Double]; factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]; }
<interactive>:30:64:
No instance for (Integral Double) arising from a use of `truncate'
Possible fix: add an instance declaration for (Integral Double)
In the expression: truncate (n / 2)
In the expression: [1 .. truncate (n / 2)]
In a stmt of a list comprehension: x <- [1 .. truncate (n / 2)]
GHCi> let { factors :: Integer -> [Integer]; factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]; }
<interactive>:31:66:
No instance for (RealFrac Integer) arising from a use of `truncate'
Possible fix: add an instance declaration for (RealFrac Integer)
In the expression: truncate (n / 2)
In the expression: [1 .. truncate (n / 2)]
In a stmt of a list comprehension: x <- [1 .. truncate (n / 2)]
<interactive>:31:77:
No instance for (Fractional Integer) arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Integer)
In the first argument of `truncate', namely `(n / 2)'
In the expression: truncate (n / 2)
In the expression: [1 .. truncate (n / 2)]
I am new to Haskell so please forgive my courage to come up with an answer here but recently i have done this as follows;
factors :: Int -> [Int]
factors n = f' ++ [n `div` x | x <- tail f', x /= exc]
where lim = truncate (sqrt (fromIntegral n))
exc = ceiling (sqrt (fromIntegral n))
f' = [x | x <- [1..lim], n `mod` x == 0]
I believe it's more efficient. You will notice if you do like;
sum (factors 33550336)