I have been given this code by our teacher. I am having trouble following what this code does. This is all I know so far: [x1, y1 | z1] = Output2.abc(3) is called, and so function abc(2) will spawn a new process assigned as y. Then it will send the value 2 to y. When it receives 2, I am stuck at what receive is doing. What does z -> z mean?
Also, the prof asks what `x1, y1 are. I don't understand where these variables are located in this code. If someone can just guide me through this it would be much appreciated. Thanks
defmodule Output2 do
def abc(x) do
y = spawn_link(__MODULE__, :n, [self()])
send y, x
receive do
z -> z
end
end
def n(z) do
receive do
v -> send z, n(v * v, v)
end
end
defp n(x, x), do: [x]
defp n(x, y), do: [y | n(x, y + y)]
end
[x1, y1 | z1] = Output2.abc(2)
Output2.abc(2) is called.
A linked process is started with spawn_link/3 using n(z) as the receiver
The original process waits for a message from the recently spawned process.
The parameter x (i.e. 2) is sent to the process started in #2
The process started in #2 sends back the result of n(v * v, v)
n(v * v, v) is a call to n(x, y) because x, and y are different values.
So, we have n(2*2, 2). n(x,y) returns a list of y concatenated with n(x, y+y) where x = 4, and y = 2
From the previous step n(4, 2+2) is called, which invokes n(x, x) returning a single item list of [4]
From 4.2, [2 | [4]] results in [2 | 4] (a list of two elements: 2, 4)
The original process received the list as z, and returns z (z -> z)
Pattern matching is used to assign x1 = 2, and y1 = 4. z1 is the tail of the rest, which is empty.
z -> z is just like function define: fun(z) {return z}
and z is parameter which got from receive function.
Related
I'm trying to implement a cantor set using prolog. The problem is defined in this link. I have implemented the code like this.
create_cantor_set(X, Y, D, List):-
cantor(D, X, Y, Temp), % Depth, X, Y, temporary list
reverse(List, Temp).
% base condition
cantor(1, X, Y, [[X|Y]|_]).
cantor(D, X, Y, Temp):-
X1 is X + ((Y - X) / 3),
Y1 is Y - ((Y - X) / 3),
decrement(D, D1),
cantor(D1, X, X1, [[X|X1]|Temp]),
cantor(D1, Y1, Y, [[Y1|Y]|Temp]).
% Decrement helper
decrement(N, N1):-
N1 is N-1.
However, I'm getting an output like this:
List = [] ;
List = [_4770] ;
List = [_4770, _4776] ;
List = [_4770, _5442, _4776] ;
List = [_4770, _5442, _5448, _4776] ;
List = [_4770, _5442, _6114, _5448, _4776]
I'm not able to understand why it is giving placeholder variables rather than the actual values.
I'm trying to add the set [X|Y] when D = 0. The answer should be one final list. Thank you for your help.
EDIT:
sample query: create_cantor_set(0, 1, 2, List).
expected output: [[0, 0.333],[0.666, 1]]
div_interval(N, X-Y, Xn-Yn) :-
Xn is X/N, Yn is Y/N.
add_interval(A, X-Y, Xa-Ya) :-
Xa is X + A, Ya is Y + A.
step_cantor(Ii, Io) :-
maplist(div_interval(3), Ii, Io1),
maplist(add_interval(2/3), Io1, Io2),
union(Io1, Io2, Io).
cantor(0, [0-1]).
cantor(N, X) :-
N > 0, N1 is N - 1, cantor(N1, X1),
step_cantor(X1, X).
cantor_len(S, L) :-
foldl([X-Y, A, O]>>(O is (A+Y-X)), S, 0, L).
I am representing an interval [a, b] with a pair a-b.
?- cantor(0, X), cantor_len(X, Y).
X = [0-1],
Y = 1
?- cantor(1, X), cantor_len(X, Y).
X = [0-0.3333333333333333, 0.6666666666666666-1.0],
Y = 0.6666666666666666
?- cantor(2, X), cantor_len(X, Y).
X = [0-0.1111111111111111, 0.2222222222222222-0.3333333333333333, 0.6666666666666666-0.7777777777777777, 0.8888888888888888-1.0],
Y = 0.4444444444444444
Is it possible to use map with a function that takes multiple arguments?
I want to use map's second and third arguments repeatedly as the function's arguments.
As in
mapF x y z = map (f y z) [1, 2, 3]
So it'll evaluate f with the same y and z values, but with x = 1, x = 2, x = 3 and so on.
You should use a lambda function, to see this works lets start by using a helper function to map f over some list.
map helper [1, 2, 3] where
helper x = f x y z
In Haskell there are two syntax for functions so lets use the lambda syntax to define our helper function:
map helper [1, 2, 3] where
helper = \x -> f x y z
using the lambda syntax we don't need to give our helper function an explicit name, it can just be an anonymous function we map over the input
map (\x -> f x y z) [1, 2, 3]
So now you can say
mapF y z = map (\x -> f x y z) [1,2,3]
But presumably you don't want x to be 1, 2 and 3, you want it to be a list
you pass as an argument to mapF. So you need to give that a different name:
mapF xs y z = map (\x -> f x y z) xs
It is Haskell convention to use s as a suffix for variables that hold lists or other containers. So if one value is x then a list of them is xs
There are guaranteed to be better ways to do this (still learning) but you can:
f' = map f [1,2,3]
f' is now a list of partially applied f
g y z= map (\h -> h y z) f'
will take each of those functions and run it on the arguments y z.
You can hack that all in one line.
I'm starting to code in python and I came across this code snippet:
for [x, y] in L:
for ix in range(-1, 2):
for iy in range(-1, 2):
cir = pylab.Circle((x + ix, y + iy), radius=sigma, fc='r')
pylab.gca().add_patch(cir)
at the line 1 I can not understand what is happening because I had never seen anything like it in another programming language. How this works?
for [x, y] in L:
[x, y] is a list? i dont know.
L must be a sequence of lists (or tuples) with two elements, which can be iterated over. So whenever for [x,y] in L: is executed, it picks each item in th sequence one by one and enters into the loop.
let the sequence be L = [[2,3], [4,5], ['Jeff', 7]]
Now here what will happen when for [x,y] in L: will be executed is :- first list in the sequence [2,3] will be picked up and assigned as x and y respectively. And in the next iteration x and y will get the value 4 & 5 respectively. Like wise in third iteration x will be Jeff and y will be 7.
L = [[2,3], [4,5], ['Jeff', 7]]
count = 0
for [x,y] in L:
count += 1
print " Iteration :- %d, \t x :- %s, \t y:- %s" %(count, str(x), str(y))
Yes, [x, y] is a list with two elements. For your loop to work, L must be a list (or other iterable data structure) that contains a bunch of lists with two elements. Each time through the loop one of those lists is copied into [x, y], then the individual values of x and y are used in the body of the loop.
Try this and see if it makes sense:
L = [ [1, 2], [3, 4] ]
for [x, y] in L:
print x
print y
I want to create a function that given two lists (of floats, but could be anything) gives a list with all the combinations of taking two elements from the first list and putting it in the last and all the combinations of the former putting one of the elements from the last (now with more elements) and putting it back on the first.
For every movement it also gives the greatest value that moved (in the second movement only one moves, that is the value). It should all end when the first list is empty (there would be no second movement).
I can't expect anyone to understand that so, examples:
next [1,2,3,4] [] -> [(([1,2], [3,4], 4), ([1,2,3],[4],3)), (([1,2], [3,4], 4), ([1,2,4],[3],4)), (([1,3], [2,4], 4), ([1,2,3],[4],2)), (([1,3], [2,4], 4), ([1,3,4],[2],4)).....
next [1,2] [3,4] -> [(([], [1,2,3,4],2),)], ())
What I have so far:
module Test where
next :: [Float] -> [Float] -> [(([Float],[Float], Float),([Float],[Float], Float))]
next [] _ = []
next (a:b:[]) s
|a>b = [([],a:b:s, a)]
|otherwise = [([],a:b:s, b)]
next d s = [([x,z], i:j:s, j), b | i <- d, j <- d, i < j, x <- d, z <- d, x < z, z /= i, z /= j, x /= z, x /= i, x /= j, b <- (back [x,z] i:j:s)]
where
back d s = [(i:d, [x,z], i) | i <- s, x <- s, z <- s, x < z, z /= i, x /= z]
Compiling that code gives back an error on the first comprehension list at the | character. I'd kind of understand an error in the back function. Why won't that compile?
The comprehension syntax is
[ <expression> | ... ]
For <expression> you have ([x,z], i:j:s, j), b which is syntactically wrong. Did you mean ([x,z], i:j:s, b)?
I have this statement:
let val x =
let val x = 5
in(fn y =>(y,x+y))
end
in
let val y=3 and z=10
in x z
end
end;
The output is :
(10,15)
I've been trying to track how this answer was produced but am getting confused. Is there a better way to write this that would help me understand what variables are being used where? Thank you!
First, some alpha-conversion:
let val fnPairOfInputAndInputPlus5 =
let val five = 5
in ( fn input => ( input, five + input ) )
end
in let val ignored = 3 and input = 10
in fnPairOfInputAndInputPlus5 input
end
end;
This code is demonstrating that when you declare a function value, unbound values in the declaring scope, such as the value five, are "enclosed" by the declaration (hence the term "closures"). Thus the function always returns a pair consisting of its input and its input plus five.
You could simplify it to
let fun f y = (y,5+y)
val y=3 and z=10
in
f z
end;
Note that the two instances of y are independent. The inner occurrence of x (which I've eliminated) is independent of the outer one (now renamed f).
Can be understood using manual evaluation with detailed explanations.
Starting with your initial expression:
let val x =
let val x = 5
in (fn y => (y,x + y))
end
in
let val y = 3 and z = 10
in x z
end
end;
Line 2,3,4 is an expression whose type is a function, as you see in the in part. It does not depends on any outer context, so it may be simplified as just fn y => (y, 5 + y), substituting x to 5, according to the binding given in let.
So you now have this:
let val x = fn y => (y, 5 + y)
in
let val y = 3 and z = 10
in x z
end
end;
After substitution of x (and removal of the let which in then now not necessary any more):
let val y = 3 and z = 10
in (fn y => (y, 5 + y)) z
end;
Note the y appearing in (y, 5 + y) are bound to the function's argument, and not to 3. There is no reference to this outer y, so its biding may be removed.
Now you have:
let z = 10
in (fn y => (y, 5 + y)) z
end;
Substituting z to 10 and removing the let which is not necessary any more, you get:
(fn y => (y, 5 + y)) 10;
This is a function application. You may evaluate it, to get:
(10, 5 + 10);
Which gives the final and constant result you noticed:
(10, 15);