erlang max function logic - function

I have a maximum function. If I use this like: "module:max(6,6)." the result will be 6.
Why not "X = Y. There is no maximum." ?
max(X,Y) when X > Y -> X;
max(X,Y) when X < Y -> Y;
max(X,Y) -> io:fwrite("X = Y. There is no maximum.\n").

As I said your code should work since it works for me.
But try this one
max(X,X) -> io:fwrite("X = Y. There is no maximum.\n");
max(X,Y) when X > Y -> X;
max(X,Y) -> Y.

A function must return something. And better without any side effects. How do you understand that inputs are equal in your case? Especially if it's called like 'max(ok, ok)' or 'max(ok, 0)'.
Erlang max function definition just mimics mathematical one, it's the same in all sensible programming languages.

Works for me.
Are you actually using module:max/2 ?
It looks like you're using erlang:max/2.

Related

bidirectional and deterministic binary decrement

I am wondering whether its possible to implement in pure Prolog alone a binary decrementer which is bidirectional and deterministic. Example runs include and for mode (-,+):
?- dec(X,[0,0,1]).
X = [1,0,1]
?- dec(X,[1,1,1]).
X = [0,0,0,1]
And for mode (+,-):
?- dec([1,0,1],X).
X = [0,0,1]
?- dec([0,0,0,1],X).
X = [1,1,1]
Optionally none of the modes should leave any choice points. But mandatorily the implementation must be in pure Prolog alone, so no cut, no findall, no var, etc...
I already tried a definition as follows dec(X,Y) :- binary_plus([1],Y,X). using the binary adder here. But it doesn't pass the last test case, since I get dec([0,0,0,1],X). X = [1, 1, 1]; X = [1, 1, 1, 0] ; false..
The following two queries test for determinism. They do not succeed. Both run infinitely as is ; and fail with a given N. To indicate that non-termination is intended, the queries are prefixed with :/-&.
:/-& length(Bs,N), dec(Bs, Ds1), dif(Ds1, Ds2), dec(Bs, Ds2).
:/-& length(Ds,N), dec(Bs1, Ds), dif(Bs1, Bs2), dec(Bs2, Ds).
dec([1|Bs],[0|Bs]) :-
nil_or_ends_with_one(Bs).
dec([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
nil_or_ends_with_one([]).
nil_or_ends_with_one([E|Es]) :-
ends_with_one(Es, E).
ends_with_one([], 1).
ends_with_one([E|Es], _) :-
ends_with_one(Es, E).
deci([1],[]).
deci([1|Bs],[0|Bs]) :-
Bs = [B|_],
ends_with_one(Bs, B).
deci([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
The solution is still a bit too general, in that it accepts
?- dec([1,non_digit,1],[0,non_digit,1]).
This can be easily fixed but does not seem to be worth the cost.
I got a different solution which is not targeted towards a deep indexing Prolog, rather a flat indexing Prolog. So far all 4 test cases do not leave any choice point in Jekejeke Prolog which has full flat indexing. :-)
% check binary number
num([]).
num([X|Y]) :- dig(X, Y).
dig(1, []).
dig(T, [X|Y]) :- aux(T, X, Y).
aux(0, X, Y) :- dig(X, Y).
aux(1, X, Y) :- dig(X, Y).
% check binary number and its pseudo decrement
dec([X|Y], Z) :- dig(X, Y, Z).
dig(1, [], []).
dig(T, [X|Y], [U|V]) :- aux(T, U, V, X, Y).
aux(0, 1, Z, X, Y) :- dig(X, Y, Z).
aux(1, 0, [X|Y], X, Y) :- dig(X, Y).
https://gist.github.com/jburse/649f828c330ff3c770834ee8bca250a8#file-tarai-p
But the drawback of full flat indexing is the additional overhead when coding a predicate, to bring it into flat form. Flat form is also popular as the binary_plus/3 example shows. But the best would possibly be to have both flat and deep, and the later in a way that there exists a
deep dec/2 version which never leaves choice points.

F# function composition where the first function has arity >1

I have two functions f and g:
let f (x:float) (y:float) =
x * y
let g (x:float) =
x * 2.0
I want to compose (>>) them to get a new function that performs f and then g on the result.
The solution should behave like:
let h x y =
(f x y) |> g
This does not work:
// Does not compile
let h =
f >> g
How should >> be used?
I think you want to achieve this:
let fog x = f x >> g
You can't compose them directly f >> g in that order, it makes sense since f expects two parameters, so doing f x will result in a partially applied function, but g expects a value, not a function.
Composing the other way around works and in your specific example you get even the same results, because you are using commutative functions. You can do g >> f and you get a composition that results in a partially applied function since g expects a single value, so by applying a value to g you get another value (not a function) and f expects two values, then you will get a partially applied function.
Writing in point-free style, i.e. defining functions without explicit arguments, can become ugly when the implicit arguments are more than one.
It can always be done, with the correct combination of operators. But the outcome is going to be a disappointment and you will lose the primary benefit of point-free style - simplicity and legibility.
For fun and learning, we'll give it a try. Let's start with the explicit (a.k.a. "pointful") style and work from there.
(Note: we're going to rearrange our composition operators into their explicit form (>>) (a) (b) rather than the more usual a >> b. This will create a bunch of parentheses, but it will make things easier to grok, without worrying about sometimes-unintuitive operator precedence rules.)
let h x y = f x y |> g
let h x = f x >> g
// everybody puts on their parentheses!
let h x = (>>) (f x) (g)
// swap order
let h x = (<<) (g) (f x)
// let's put another pair of parentheses around the partially applied function
let h x = ((<<) g) (f x)
There we are! See, now h x is expressed in the shape we want - "pass x to f, then pass the result to another function".
That function happens to be ((<<) g), which is the function that takes a float -> float as argument and returns its composition with g.
(A composition where g comes second, which is important, even if in the particular example used it doesn't make a difference.)
Our float -> float argument is, of course, (f x) i.e. the partial application of f.
So, the following compiles:
let h x = x |> f |> ((<<) g)
and that can now be quite clearly simplified to
let h = f >> ((<<) g)
Which isn't all that awful-looking, when you already know what it means. But anybody with any sense will much rather write and read let h x y = f x y |> g.

Error plotting a function of 2 variables

I am trying to plot the function
f(x, y) = (x – 3).^2 – (y – 2).^2.
x is a vector from 2 to 4, and y is a vector from 1 to 3, both with increments of 0.2. However, I am getting the error:
"Subscript indices must either be real positive integers or logicals".
What do I do to fix this error?
I (think) I see what you are trying to achieve. You are writing your syntax like a mathematical function definition. Matlab is interpreting f as a 2-dimensional data type and trying to assign the value of the expression to data indexed at x,y. The values of x and y are not integers, so Matlab complains.
If you want to plot the output of the function (we'll call it z) as a function of x and y, you need to define the function quite differently . . .
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
z = f( repmat(x(:)',numel(y),1) , repmat(y(:),1,numel(x) ) );
surf(x,y,z);
xlabel('X'); ylabel('Y'); zlabel('Z');
This will give you an output like this . . .
The f = #(x,y) part of the first line states you want to define a function called f taking variables x and y. The rest of the line is the definition of that function.
If you want to plot z as a function of both x and y, then you need to supply all possible combinations in your range. This is what the line containing the repmat commands is for.
EDIT
There is a neat Matlab function meshgrid that can replace the repmat version of the script as suggested by #bas (welcome bas, please scroll to bas' answer and +1 it!) ...
f = #(x,y)(x-3).^2 - (y-2).^2;
x=2:.2:4;
y=1:.2:3;
[X,Y] = meshgrid(x,y);
surf(x,y,f(X,Y));
xlabel('x'); ylabel('y'); zlabel('z');
I typically use the MESHGRID function. Like so:
x = 2:0.2:4;
y = 1:0.2:3;
[X,Y] = meshgrid(x,y);
F = (X-3).^2-(Y-2).^2;
surf(x,y,F);
xlabel('x');ylabel('y');zlabel('f')
This is identical to the answer by #learnvst. it just does the repmat-ing for you.
Your problem is that the function you are using uses integers, and you are trying to assign a double to it. Integers cannot have decimal places. To fix this, you can make it to where it increases in increments of 1, instead of 0.2

Shading regions/inequalities of a 2D function in MATLAB

I've defined my own function with two input arguments (call it z(x,y) say) and managed to produce a contour plot. What I'd like to do now is to shade the region where, for example, z > 5. The main problem is that z is too complicated to be able to deduce the restrictions on x,y myself. Is there any simple way of doing this?
Did you try to use NaN?
z(condition) = nan;
before calling contour(), where condition can be on any combination of z, x, y, resulting binary matrix, for instance:
z(abs(z) > x - y) = nan;

Good explanation of "Combinators" (For non mathematicians)

Anyone got a good explanation of "combinators" (Y-combinators etc. and NOT the company)?
I'm looking for one for the practical programmer who understands recursion and higher-order functions, but doesn't have a strong theory or math background.
(Note: that I'm talking about these things)
Unless you're deeply into theory, you can regard the Y combinator
as a neat trick with functions, like monads.
Monads allow you to chain actions, the Y combinator allows you to
define self-recursive functions.
Python has built-in support for self-recursive functions, so you
can define them without Y:
> def fun():
> print "bla"
> fun()
> fun()
bla
bla
bla
...
fun is accessible inside fun itself, so we can easily call it.
But what if Python were different, and fun weren't accessible
inside fun?
> def fun():
> print "bla"
> # what to do here? (cannot call fun!)
The solution is to pass fun itself as an argument to fun:
> def fun(arg): # fun receives itself as argument
> print "bla"
> arg(arg) # to recur, fun calls itself, and passes itself along
And Y makes that possible:
> def Y(f):
> f(f)
> Y(fun)
bla
bla
bla
...
All it does it call a function with itself as argument.
(I don't know if this definition of Y is 100% correct, but I think it's the general idea.)
Reginald Braithwaite (aka Raganwald) has been writing a great series on combinators in Ruby over at his new blog, homoiconic.
While he doesn't (to my knowledge) look at the Y-combinator itself, he does look at other combinators, for instance:
the Kestrel
the Thrush
the Cardinal
the Obdurate Kestrel
other Quirky Birds
and a few posts on how you can use them.
Quote Wikipedia:
A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.
Now what does this mean? It means a combinator is a function (output is determined solely by its input) whose input includes a function as an argument.
What do such functions look like and what are they used for? Here are some examples:
(f o g)(x) = f(g(x))
Here o is a combinator that takes in 2 functions , f and g, and returns a function as its result, the composition of f with g, namely f o g.
Combinators can be used to hide logic. Say we have a data type NumberUndefined, where NumberUndefined can take on a numeric value Num x or a value Undefined, where x a is a Number. Now we want to construct addition, subtraction, multiplication, and division for this new numeric type. The semantics are the same as for those of Number except if Undefined is an input, the output must also be Undefined and when dividing by the number 0 the output is also Undefined.
One could write the tedious code as below:
Undefined +' num = Undefined
num +' Undefined = Undefined
(Num x) +' (Num y) = Num (x + y)
Undefined -' num = Undefined
num -' Undefined = Undefined
(Num x) -' (Num y) = Num (x - y)
Undefined *' num = Undefined
num *' Undefined = Undefined
(Num x) *' (Num y) = Num (x * y)
Undefined /' num = Undefined
num /' Undefined = Undefined
(Num x) /' (Num y) = if y == 0 then Undefined else Num (x / y)
Notice how the all have the same logic concerning Undefined input values. Only division does a bit more. The solution is to extract out the logic by making it a combinator.
comb (~) Undefined num = Undefined
comb (~) num Undefined = Undefined
comb (~) (Num x) (Num y) = Num (x ~ y)
x +' y = comb (+) x y
x -' y = comb (-) x y
x *' y = comb (*) x y
x /' y = if y == Num 0 then Undefined else comb (/) x y
This can be generalized into the so-called Maybe monad that programmers make use of in functional languages like Haskell, but I won't go there.
A combinator is function with no free variables. That means, amongst other things, that the combinator does not have dependencies on things outside of the function, only on the function parameters.
Using F# this is my understanding of combinators:
let sum a b = a + b;; //sum function (lambda)
In the above case sum is a combinator because both a and b are bound to the function parameters.
let sum3 a b c = sum((sum a b) c);;
The above function is not a combinator as it uses sum, which is not a bound variable (i.e. it doesn't come from any of the parameters).
We can make sum3 a combinator by simply passing the sum function as one of the parameters:
let sum3 a b c sumFunc = sumFunc((sumFunc a b) c);;
This way sumFunc is bound and hence the entire function is a combinator.
So, this is my understanding of combinators. Their significance, on the other hand, still escapes me. As others pointed out, fixed point combinators allow one to express a recursive function without explicit recursion. I.e. instead of calling itself the recusrsive function calls lambda that is passed in as one of the arguments.
Here is one of the most understandable combinator derivations that I found:
http://mvanier.livejournal.com/2897.html
This looks a good one : http://www.catonmat.net/blog/derivation-of-ycombinator/
This is a good article.
The code examples are in scheme, but they shouldn't be hard to follow.
I'm pretty short on theory, but I can give you an example that sets my imagination aflutter, which may be helpful to you. The simplest interesting combinator is probably "test".
Hope you know Python
tru = lambda x,y: x
fls = lambda x,y: y
test = lambda l,m,n: l(m,n)
Usage:
>>> test(tru,"goto loop","break")
'goto loop'
>>> test(fls,"goto loop","break")
'break'
test evaluates to the second argument if the first argument is true, otherwise the third.
>>> x = tru
>>> test(x,"goto loop","break")
'goto loop'
Entire systems can be built up from a few basic combinators.
(This example is more or less copied out of Types and Programming Languages by Benjamin C. Pierce)
Shortly, Y combinator is a higher order function that is used to implement recursion on lambda expressions (anonymous functions). Check the article How to Succeed at Recursion Without Really Recursing by Mike Vanier - it's one of best practical explanation of this matter I've seen.
Also, scan the SO archives:
What is a y-combinator?
Y-Combinator Practical Example