Understanding recursive function with implicit return statement - scala

Below recursive method sums the integer values between a range
def sumInts(a: Int, b: Int): Int = {
if(a > b) 0
else {
println(a +"," + b)
a + sumInts(a + 1 , b)
}
}
So sumInts(2 , 5) returns 14
I'm confused about how the recursive call to sumInts sums the integer range. Can explain textually how this method works ?
How does sumInts return the incremented value ?? Perhaps I am missing something fundamental to recursion here

It calculates the sum of values in the range [a, b] by first calculating the sum of the range [a+1, b] (by recursively calling sumInts(a + 1 , b)) then adding a to it.
[Update] In Scala, the return statement is optional; functions return the value of the last expression evaluated. Thus the above function body is equivalent to
if(a > b) return 0
else {
println(a +"," + b)
return a + sumInts(a + 1 , b)
}
[/Update]
Which for the range [2, 5] it would do the following (I removed the println call for the sake of simplicity, and added brackets to mark recursive calls):
if(2 > 5) 0 else 2 + sumInts(2 + 1, 5) which, the condition being false, evaluates to
2 + sumInts(3, 5)
2 + (if(3 > 5) 0 else 3 + sumInts(3 + 1, 5)) which evaluates to
2 + (3 + sumInts(4, 5))
2 + (3 + (if(4 > 5) 0 else 4 + sumInts(4 + 1, 5))) which evaluates to
2 + (3 + (4 + sumInts(5, 5)))
2 + (3 + (4 + (if(5 > 5) 0 else 5 + sumInts(5 + 1, 5)))) which evaluates to
2 + (3 + (4 + (5 + sumInts(6, 5))))
2 + (3 + (4 + (5 + (if(6 > 5) 0 else 6 + sumInts(6 + 1, 5))))) which, the condition being true, evaluates to
2 + (3 + (4 + (5 + (0))))

Related

Modulo simplification in coq

I am a beginner at Coq and I'm stuck at a problem in Coq, I am not able to simplify this further. It would be great if anyone had any tips on how to break the problem down into smaller steps. The lemma is this:
forall (n : N) (n0 : N),
((1 + 2 * n + (2 * N.pos (2 ^ 32) - 1 - (0 + 2 * n0)))
mod (2 * N.pos (2 ^ 32)) / (2 * 1)) mod N.pos (2 ^ 32) =
(((n + (N.pos (2 ^ 32) - 1 - n0)) mod N.pos (2 ^ 32) + 1 mod N.pos (2 ^ 32))
mod N.pos (2 ^ 32) / 1) mod N.pos (2 ^ 32)
As such, your goal is not provable, you can try:
Goal exists (n : N) (n0 : N),
((1 + 2 * n + (2 * N.pos (2 ^ 32) - 1 - (0 + 2 * n0)))
mod (2 * N.pos (2 ^ 32)) / (2 * 1)) mod N.pos (2 ^ 32) <>
(((n + (N.pos (2 ^ 32) - 1 - n0)) mod N.pos (2 ^ 32) + 1 mod N.pos (2 ^ 32))
mod N.pos (2 ^ 32) / 1) mod N.pos (2 ^ 32).
Proof.
now exists 0, (N.pos 2^33).
Qed.
The issue comes from subtraction between positive numbers, which returns 0 when its second argument is larger, so that it is not injective.

Scala tail recursive method has an divide and remainder error

I'm currently computing the binomial coefficient of two natural numbers by write a tail recursion in Scala. But my code has something wrong with the dividing numbers, integer division by k like I did as that will give you a non-zero remainder and hence introduce rounding errors. So could anyone help me figure it out, how to fix it ?
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
def binomtail(n: Int, k: Int, ac: Int): Int = {
if (n == k || k == 0) ac
else binomtail(n - 1, k - 1, (n*ac)/k)
}
binomtail(n,k,1)
}
In general, it holds:
binom(n, k) = if (k == 0 || k == n) 1 else binom(n - 1, k - 1) * n / k
If you want to compute it in linear time, then you have to make sure that each intermediate result is an integer. Now,
binom(n - k + 1, 1)
is certainly an integer (it's just n - k + 1). Starting with this number, and incrementing both arguments by one, you can arrive at binom(n, k) with the following intermediate steps:
binom(n - k + 1, 1)
binom(n - k + 2, 2)
...
binom(n - 2, k - 2)
binom(n - 1, k - 1)
binom(n, k)
It means that you have to "accumulate" in the right order, from 1 up to k, not from k down to 1 - then it is guaranteed that all intermediate results correspond to actual binomial coefficients, and are therefore integers (not fractions). Here is what it looks like as tail-recursive function:
def binom(n: Int, k: Int): Int = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: Int): Int = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, 1)
}
Little visual test:
val n = 12
for (i <- 0 to n) {
print(" " * ((n - i) * 2))
for (j <- 0 to i) {
printf(" %3d", binom(i, j))
}
println()
}
prints:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
1 12 66 220 495 792 924 792 495 220 66 12 1
Looks ok, compare it with this, if you want.
Andrey Tyukin's excellent example will fail with larger n, say binom(10000, 2), but can be easily adapted to use BigInt.
def binom(n: Int, k: Int): BigInt = {
require(0 <= k && k <= n)
#annotation.tailrec
def binomtail(nIter: Int, kIter: Int, ac: BigInt): BigInt = {
if (kIter > k) ac
else binomtail(nIter + 1, kIter + 1, (nIter * ac) / kIter)
}
if (k == 0 || k == n) 1
else binomtail(n - k + 1, 1, BigInt(1))
}

How do you factor over a Z field?

I have to factorize a polynomial e.g.
over the field of Z5 using Matlab or Mupad.
And i tried everything read a lot of Matlab and Mupad documentation and still can't find it, so i am guessing it is the math i don't know that's going to help me factor it.
Don't kill a mosquito with a cannon!
You only need to find a root between 0, 1, 2, -2, -1.
Also, given that x5 = x, the problem reduces to finding x such that
2x + 2x^4 + x^3 + 2x^2 - 3 = 0
and since x ≠ 0, x^4 = 1 hence
2x + x^3 + 2x^2 - 1 = 0
Well, let's try!
1: 2 + 1 + 2 - 1 -> -1
2: -1 + 3 - 2 - 1 -> -1
-2: 1 - 3 + 3 - 1 -> 0 -> root!
Then the polynomial is divisible by (x - 3), and you can repeat the procedure with the quotient until there are no roots left.
Addendum
After dividing by (x - 3) we get
x4 + x2 + 1
which we can expressed as
(x2 + 1)2 - x2
or
((x2 + 1) - x)((x2 + 1) + x)
To find the factors of degree 2 programmatically, just try with x2 + ax + b for a and b between 0 and 4.
I found a mupad command to do what i needed.
Still thanks for exaplaining the math behind it.

Netlogo reduce polynomial example

In the Netlogo dictionary for "reduce" they show an example with one "+" operator
reduce [?1 + ?2] [1 2 3 4]
which they expand as equivalent to (((1 + 2) + 3) + 4).
Later they give this example:
;; evaluate the polynomial, with given coefficients, at x
to-report evaluate-polynomial [coefficients x]
report reduce [(x * ?1) + ?2] coefficients
end
;; evaluate 3x^2 + 2x + 1 at x = 4
show evaluate-polynomial [3 2 1] 4
=> 57
What is the equivalent expansion (using parentheses) for that evaluation?
observer> show (4 * ((4 * 3) + 2)) + 1
observer: 57
The key to understand it is to do it step by step. reduce starts by taking the first two elements of the list and plugging them into ?1 and ?2, so
(x * ?1) + ?2
becomes
(x * 3) + 2
That whole expression then becomes ?1, and the last element of the list, 1, becomes ?2. Replacing ?1 and ?2 in the initial expression again, we get:
(x * ((x * 3) + 2)) + 1
All that's left is to replace x with 4:
(4 * ((4 * 3) + 2)) + 1

Boolean Logic Simplification: AB+A'B'=?

I have some problem simplifying the equation AB+A'B'= ? Is there any straight forward answer like AB'+A'B = A^B ; (^)=XOR sign ?
It's the XNOR function, which typically doesn't occur often enough to warrant its own operator. It's the negation of XOR, though, which can be seen by applying De Morgan's law twice.
AB + A'B' = ((AB)'(A'B')')'
= ((A' + B')(A + B))'
= (A'A + B'A + A'B + B'B)'
= (0 + AB' + A'B + 0)'
= (AB' + A'B)'
= (A ^ B)'
or by simply comparing truth tables
A B A ^ B AB + A'B'
-------------------------
0 0 0 1
0 1 1 0
1 0 1 0
1 1 0 1
(Put another way, XNOR is equivalence for two arguments, so you can think of A XNOR B as an operator that converts comparison to a value. A XNOR B equals 1 if A == B is true, 0 if it is false.)