Mutable variables in Haskell? - haskell

I'm starting to wrap my head around Haskell and do some exciting experiments. And there's one thing I just seem to be unable to comprehend (previous "imperativist" experience talks maybe).
Recently, I was yearning to implement integer division function as if there where no multiply/divide operations. An immensely interesting brain-teaser which led to great confusion.
divide x y =
if x < y then 0
else 1 + divide (x - y) y
I compiled it and it.. works(!). That's mind-blowing. However, I was told, I was sure that variables are immutable in Haskell. How comes that with each recursive step variable x keeps it's value from previous step? Or is my glorious compiler lying to me? Why does it work at all?

Your x here doesn't change during one function call (i.e., after creation) - that's exactly what immutable means. What does change is value of x during multiple (recursive) calls. In a single stack frame (function call) the value of x is constant.
An example of execution of your code, for a simple case
call divide 8 3 -- (x = 8, y = 3), stack: divide 8 3
step 1: x < y ? NO
step 2: 1 + divide 5 3
call: divide 5 3 -- (x = 5, y = 3), stack: divide 8 3, divide 5 3
step 1: x < y ? NO
step 2: 1 + divide 2 3
call divide 2 3 -- (x = 2, y = 3), stack: divide 8 3, divide 5 3, divide 2 3
step 1: x < y ? YES
return: 0 -- unwinding bottom call
return 1 + 0 -- stack: divide 8 3, divide 5 3, unwinding middle call
return 1 + 1 + 0 -- stack: divide 8 3
I am aware that the above notation is not anyhow formalized, but I hope it helps to understand what recursion is about and that x might have different values in different calls, because it's simply a different instance of whole call, thus also different instance of x.

x is actually not a variable, but a parameter, and isn't that different from parameters in imperative languages.
Maybe it'd look more obvious with explicit return statements?
-- for illustrative purposes only, doesn't actually work
divide x y =
if x < y
then return 0
else return 1 + divide (x - y) y
You're not mutating x, just stacking up several function calls to calculate your desired result with the values they return.
Here's the same function in Python:
def divide(x, y):
if x < y:
return 0
else:
return 1 + divide(x - y, y)
Looks familiar, right? You can translate this to any language that allows recursion, and none of them would require you to mutate a variable.
Other than that, yes, your compiler is lying to you. Because you're not allowed to directly mutate values, the compiler can make a lot of extra assumptions based on your code, which helps translating it to efficient machine code, and at that level, there's no escaping mutability. The major benefit is that compilers are way less likely to introduce mutability-related bugs than us mortals.

Related

The initializer parameter of reduce() on the sum of elements of an iterable

A query regarding this code:
from functools import reduce
def sum_even(it):
return reduce(lambda x, y: x + y if not y % 2 else x, it,0)
print(sum_even([1, 2, 3, 4]))
Why not adding the third parameter of reduce() adds the first odd element of the list?
If you don't pass an initial element explicitly, then the first two elements of the input become the arguments to the first call to the reducer, so x would be 1 and y would be 2. Since your test only excludes odd ys, not xs, the x gets preserved, and all future xs are sums based on that initial 1. Using 0 as an explicit initial value means only 0 and (later) the accumulated total of that 0 and other even numbers is ever passed as x, so an odd number is never passed as x.
Note that this is kind of a silly way to do this. It's much simpler to build this operation from parts, using one tool to filter to even, and another to sum the surviving elements from the filtering operation. For example:
def sum_even(it):
return sum(x for x in it if not x % 2)
is shorter, clearer, and (likely) faster than the reduce you wrote.

Algorithm: find two positive integers whose difference is minimized and whose product is known

Some background...
I am currently building a macro that will estimate the cost of an injection molding tool. These tools have cavities which are filled with plastic. The number of cavities a tool has is the number of parts that will be formed.
So far my program will determine the minimum number of cavities a tool can have based on customer demand. This number is always even. The tool should have an even number of cavities. Given the bounding length and width of a cavity, and setting a limit to how much space the cavities can occupy within the tool, I need my program to calculate the combination of number of cavities along the length and width whose difference is minimized and whose product is equal to the total number of minimum cavities the tool should have.
I am programming my macro is SolidWorks VBA. I first constructed this problem in Excel and used the solver tool. But, I am unable to find a way to reference the Excel Solver Tool in SolidWorks to automate this optimization problem. I am hoping to find a clever set of equations that can solve this specific problem for me. But if someone else has a better idea of what to use, that would be awesome.
Rephrasing in an optimization format...
Variables
x = number of cavities along width of tool
y = number of cavities along length of tool
z = suggested number of total cavities
Objective Function
Minimize x - y
Such that
x * y = z
x >= 1
y >= 1
x <= y
x is an integer
y is an integer
Example
My macro says that in order to meet demand, our tool needs to have at least 48 cavities. Find the number of cavities along the length and width of the tool such that the difference is minimized and the product is equal to 48. Ideally in this case the macro would return x = 6 and y = 8.
Thanks!
Just to clarify, in the question did you actually mean to Min y-x rather than Min x-y? Otherwise there is a naïve solution taking x = 1 and y = z. Min x - y = 1-z.
I don't program in VBA but here is the idea.
Since x and y are positive integers and there product is z, with x <= y. You can essentially start with x = floor(sqrt(z)) and decrement until x = 1.
For each x, check if there exists an integer y such that x * y = z. If there is, break the loop and that's the pair you are looking for. Otherwise continue until x = 1
If you need any pseudo code so you can translate it into VBA. Here it is
int x, y;
for (x = floor(sqrt(z)); x >= 1; --x)
{
y = z / x;
if (x * y == z)
break;
}
I think you can just test out a few examples. No fancy algorithm is needed.
If you relax the condition to be 2 numbers, x and y, whose product is z and with a minimum difference, then the answer is SQRT(z).
That is not an integer that meets your needs (in general). However, you can then try integers around the square root to see if they divide z. The first one you hit (i.e. minimum difference from SQRT(z)) should have the minimum difference.
If you relax the condition to be |z - x * y| is minimized, then I would recommend testing the numbers around sqrt(z). You need to check two cases -- the floor and ceiling of the square root (and the appropriate other number).
Just in case someone is needs something similar to this in the future, but can't figure out the pseudo-code I went ahead wrote it up. I wasn't sure how to output it as two values so I just threw them together as a string for the user to see.
Option Explicit
Function Factors(ByVal Test As Long) As String
Dim Val As Long
Dim i As Long
Val = Test
i = Int(Sqr(Val))
While Val / i >= 2
If Int(Val / i) * i = Val Then
Factors = i & " & " & Val / i
Exit Function
End If
i = i - 1
Wend
End Function

how dependent bindings in let are evaluated?

Is it safe to use bindings that depend on each other in let? For example:
let x = 1
y = x + 2
in y
Is it possible that they are evaluated in parallel? my ghci shows that it is evaluated correctly, but will this be always the case?
Haskell is lazy evaluated. This means that expressions are only evaluated by necessity. Let's start with your example.
let x = 1
y = x + 2
in y
The system looks at the y part (the expression), and says "Hey. I know what y equals. It equals x + 2" But it can only evaluate x + 2 if it has a definition for x, so it does the same thing and decides that y is 1 + 2 which is of course 3. Now this is only a small portion of the power of lazy evaluation. The next example shows it more fully.
let x = 0 : y
y = 1 : x
in take 50 x
This expression will evaluate correctly, yielding the first fifty elements on the list x, which will be 0 and 1 alternating. Both of the values x and y are infinite lists that depend on each other, and indeed in most languages this would overflow the stack. However, the evaluation rules allow the system to only see the parts it needs, which in that example is the first fifty elements.
So to answer your question about evaluation order, the system evaluates what it sees. If the function is supposed to return y, it evaluates y and then as necessary x. If you had put x in your first example, it would have evaluated x and left y alone. For example, this code will not err.
let x = 1
y = error "I'm an error message!"
in x
This is because the y form is never needed, so the piece of code that would crash the program is never even looked at.
In Haskell (regardless of whether you use a single let, multiple lets, case, where or function parameters) an expression is evaluated when the evaluation of another expression depends on its value.
So in your case, as soon as y's value is required (which of course depends on the surrounding program), y will be evaluated and x will be evaluated as part of y's evaluation.
Another way to think of it is this: whenever you use the value of a variable, it will be evaluated at that point at the latest. That is it might have been evaluated previously (if it was needed previously) or it might be evaluated now, but, as long as you do use the value, it will never not be evaluated. So, except for performance reasons, there's no need to worry about when a variable will be evaluated.

Does ((a^x) ^ 1/x) == a in Zp? (for Jablon's protocol)

I have to implement Jablon's protocol (paper) but I've been sitting on a bug for two hours.
I'm not very good with math so I don't know if it's my fault in writing it or it just isn't possible. If it isn't possible, I don't see how Jablon's protocol can be implemented since it relies on the fact that ((gP ^ x) ^ yi) ^ (1/x) == gP^yi .
Take the following code. It doesn't work.
BigInteger p = new BigInteger("101");
BigInteger a = new BigInteger("83");
BigInteger x = new BigInteger("13");
BigInteger ax = a.modPow(x, p);
BigInteger xinv = x.modInverse(p);
BigInteger axxinv = ax.modPow(xinv, p);
if (a.equals(axxinv))
System.out.println("Yay!");
else
System.out.println("How is this possible?");
Your problem is that you're not calculating k(1/x) correctly. We need k(1/x))k to be x. Fermat's Little Theorem tells us that kp-1 is 1 mod p. Therefore we want to find y such that x * y is 1 mod p-1, not mod p.
So you want BigInteger xinv = x.modInverse(p-1);.
This will not work if x shares a common factor with p-1. (Your case avoids that.) For that, you need additional theory.
If p is a prime, then r is a primitive root if none of r, r^2, r^3, ..., r^(p-2) are congruent to 1 mod p. There is no simple algorithm to produce a primitive root, but they are common so you usually only need to check a few. (For p=101, the first number I tried, 2, turned out to be a primitive root. 83 is also.) Testing them would seem to be hard, but it isn't so bad since it turns out that (omitting a bunch of theory here) only divisors of p-1 need to be checked. For instance for 101 you only need to check the powers 1, 2, 4, 5, 10, 20, 25 and 50.
Now if r is a primitive root, then every number mod p is some power of r. What power? That's called the discrete logarithm problem and is not simple. (It's difficulty is the basis of RSA, which is a well known cryptography system.) You can do it with trial division. So trying 1, 2, 3, ... you eventually find that, for instance, 83 is 2^89 (mod 101).
But once we know that every number from 1 to 100 is 2 to some power, we are armed with a way to calculate roots. Because raising a number to the power of x just multiplies the exponent by x. And 2^100 is 1. So exponentiation is multiplying by x (mod 100).
So suppose that we want y ^ 13 to be 83. Then y is 2^k for some k such that k * 13 is 89. If you play around with the Chinese Remainder Theorem you can realize that k = 53 works. Therefore 2^53 (mod 101) = 93 is the 13'th root of 89.
That is harder than what we did before. But suppose that we wanted to take, say, the 5th root of 44 mod 101. We can't use the simple procedure because 5 does not have a multiplicative inverse mod 100. However 44 is 2^15. Therefore 2^3 = 8 is a 5th root. But there are 4 others, namely 2^23, 2^43, 2^63 and 2^83.

Stuck on a Concurrent programming example, in pseudocode(atomic actions/fine-grained atomicity)

My book presents a simple example which I'm a bit confused about:
It says, "consider the following program, and assume that the fine-grained atomic actions are reading and writing the variables:"
int y = 0, z = 0;
co x = y+z; // y=1; z=2; oc;
"If x = y + z is implemented by loading a register with y and then adding z to it, the final value of x can be 0,1,2, or 3. "
2? How does 2 work?
Note: co starts a concurrent process and // denote parallel-running statements
In your program there are two parallel sequences:
Sequence 1: x = y+z;
Sequence 2: y=1; z=2;
The operations of sequence 1 are:
y Copy the value of y into a register.
+ z Add the value of z to the value in the register.
x = Copy the value of the register into x.
The operations of sequence 2 are:
y=1; Set the value of y to 1.
z=2; Set the value of z to 2.
These two sequences are running at the same time, though the steps within a sequence must occur in order. Therefore, you can get an x value of '2' in the following sequence:
y=0
z=0
y Copy the value of y into a register. (register value is now '0')
y=1; Set the value of y to 1. (has no effect on the result, we've already copied y to the register)
z=2; Set the value of z to 2.
+ z Add the value of z to the value in the register. (register value is now '2')
x = Copy the value of the register into x. (the value of x is now '2')
Since they are assumed to run in parallel, I think an even simpler case could be y=0, z=2 when the assignment x = y + z occurs.

Resources