catch badarg error in the supervisor function - parallel-processing

Here I have a program that does some simple mathematical operations. The program is running with a supervisor.
However sometimes the program would crash as I run it. Especially when I first time run calc_sup_start_link() and then some times with calc_test(). Anyone has any idea ? The program is as follows:
calc_sup_start_link() ->
spawn_link(fun calc_sup/0).
calc_sup() ->
process_flag(trap_exit, true),
{ok, _Pid} = calc_start_link(),
receive
{'EXIT', _From, normal} ->
ok;
{'EXIT', _From, _Reason} ->
calc_sup() % Crash: restart
end.
calc_start_link() ->
S = spawn_link(fun calc_loop/0),
register(calc, S),
{ok, S}
calc_loop() ->
receive
{add, P, A, B} ->
P ! {add_reply, A + B},
calc_loop();
{mul, P, A, B} ->
{_, _, N} = now(),
if N rem 5 =/= 0 -> ok end,
P ! {mul_reply, A * B},
calc_loop()
end.
calc_add(A, B) ->
calc ! {add, self(), A, B},
receive
{add_reply, C} -> C
end.
calc_mul(A, B) ->
calc ! {mul, self(), A, B},
receive
{mul_reply, C} -> C
end.
calc_client(X, Y, Z) ->
Q = calc_mul(X, Y),
timer:sleep(500),
R = calc_add(Q, 3),
timer:sleep(500),
calc_mul(R, Z).
calc_test() ->
io:format("Running calc_client(2, 4, 5)~n"),
R = calc_client(2, 4, 5),
io:format("calc_client(2, 4, 5) returned ~p~n", [R]).

I think it crash in this bloc:
calc_loop() ->
receive
{add, P, A, B} ->
P ! {add_reply, A + B},
calc_loop();
{mul, P, A, B} ->
{_, _, N} = now(),
if N rem 5 =/= 0 -> ok end, %% if doesn't work as in C or java !!!
P ! {mul_reply, A * B},
calc_loop()
end.
in fact if N is a multiple of 5, (N rem 5) == 0 and there is no branch to evaluate the result of if, and in erlang all the statement have to return a value. You can verify in the shell:
1> if ((11 rem 5) =/= 0) -> ok end.
ok
2> if ((10 rem 5) =/= 0) -> ok end.
** exception error: no true branch found when evaluating an if expression
3> if ((10 rem 5) =/= 0) -> ok; true -> false end.
false
4>
In your case you should write:
calc_loop() ->
receive
{add, P, A, B} ->
P ! {add_reply, A + B},
calc_loop();
{mul, P, A, B} ->
{_, _, N} = now(),
case (N rem 5) of
0 -> P ! {mul_reply, A * B},
calc_loop();
_ -> ok
end
end.
this will perform the multiplication and loop if N is multiple of 5; and it will terminate with reason normal in other cases (I am not sure it is what you want to do since the if expression is not complete)

if your write tail recursion all by yourself,
the better way is always call external functions(for the code only save two version in memory).
like this :
change calc_loop() to ?MODULE:calc_loop().
it will always call the newest version of code.
http://www.erlang.org/doc/reference_manual/code_loading.html#id88331

Related

Wolfram Mathematica: Why not looking for a maximum in real numbers?

Maximize[{Log[B e^(20 a)] - (B (-1 + e^(20 a)))/(a Log[e]), a > 0,
B > 0, e > 1}, {a, B, e}, Reals]
There is probably no closed-form solution for that transcendental equation.
NMaximize[{Log[B e^(20 a)] - (B (-1 + e^(20 a)))/(a Log[e]), a > 0,
B > 0, e > 1}, {a, B, e}, Reals]
Gives
{-1.55421, {a -> 1.14072, B -> 3.85825*10^-6, e -> 1.67175}}
and the message
The function value Indeterminate is not a number at {a,B,e} =
{1.153668136677547,0.,1.688137312684115}

Getting array/list element index

I was trying to solve this little problem from LeetCode:
-module(two_sum).
-export([main/2]).
-spec main(List :: list(), Target :: non_neg_integer()) -> list().
%%%==================================================================
%%% Export
%%%==================================================================
main(List, Target) ->
P = [{string:str(List, [X]), string:str(List, [Y]), X + Y} || X <- List, Y <- List, Y > X andalso X + Y =:= Target],
io:format("Result: ~w~n", [P]).
%%[X + Y || X <- List, Y <- List, Y > X].
%%iterate(List, Target, 0, {}).
%%%==================================================================
%%% Internal
%%%==================================================================
iterate([], _Target, _Sum, _Result) -> {};
iterate([H | T], Target, Sum, Result) ->
%%io:format("H >> ~w; T >> ~w, Target >> ~w~n", [H, T, Target]).
Acc = Sum + H,
case Acc =:= Target of
true -> erlang:append_element(Result, H);
false -> iterate(T, Target, Acc, Result)
end.
My questions are:
Is there a more efficient way to get the element's index from an array/list? Currently I'm using this: {string:str(List, [X]), but I'm not sure if that's correct, although it gets the job done.
If I happen to get, for instance, a result like this: R = [{1,2,9},{1,3,13},{1,4,17},{2,3,18},{2,4,22},{3,4,26}], how do I pattern match for {1,2,9}, knowing that 9 is Target? I tried [{X1, X2, Target}] = R...but it didn't like it!
How about this. For each element, check its sum with each subsequent element in the list, carrying along the two indices, to be used to report to the user if a match is found.
find_indices(Target, [_H | T] = L) ->
find_indices(Target, L, T, 0, 1).
find_indices(_Target, [_], [], _I, _J) ->
io:format("No match~n");
find_indices(Target, [_Curr | LeftRest], [], I, _J) ->
find_indices(Target, LeftRest, tl(LeftRest), I + 1, I + 2);
find_indices(Target, [Curr | _LeftRest], [Other | _RightRest], I, J)
when Target =:= Curr + Other ->
io:format("Match at indices ~p and ~p: ~p + ~p = ~p~n",
[I, J, Curr, Other, Target]),
ok;
find_indices(Target, L, [_Other | RightRest], I, J) ->
find_indices(Target, L, RightRest, I, J + 1).
Example:
1> index:find_indices(7, [1,2,3,4,5,6]).
Match at indices 2 and 3: 3 + 4 = 7
ok
2> index:find_indices(11, [1,2,3,4,5,6]).
Match at indices 4 and 5: 5 + 6 = 11
ok
3> index:find_indices(12, [1,2,3,4,5,6]).
No match
ok
4> index:find_indices(4, [1,2,3,4,5,6]).
Match at indices 0 and 2: 1 + 3 = 4
ok

Is there a built-in Mathematica function to find operators rather than numbers in equations?

How can the following be best accomplished in Mathematica?
In[1] := Solve[f[2,3]==5,f ∈ {Plus,Minus,Divide}]
Out[1] := Plus
The desired expression syntax can be transformed into a set of Solve expressions:
fSolve[expr_, f_ ∈ functions_List] :=
Map[Solve[(expr /. f -> #) && f == #, f] &, functions] // Flatten
Sample use:
In[6]:= fSolve[f[2,3] == 5, f ∈ {Plus, Subtract, Divide}]
Out[6]= {f -> Plus}
In[7]:= fSolve[f[4,2] == 2, f ∈ {Plus, Subtract, Divide}]
Out[7]= {f -> Subtract, f -> Divide}
The advantage of this approach is that the full power of Solve remains available for more complex expressions, e.g.
In[8]:= fSolve[D[f[x], x] < f[x], f ∈ {Log, Exp}]
Out[8]= {f -> ConditionalExpression[Log, x Log[x]∈Reals && x>E^ProductLog[1]]}
In[9]:= fSolve[D[f[x], x] <= f[x], f ∈ {Log, Exp}]
Out[9]= {f -> ConditionalExpression[Log, x Log[x]∈Reals && x>=E^ProductLog[1]],
f -> ConditionalExpression[Exp, E^x ∈ Reals]}
Please tell me if this does what you want:
findFunction[expr_, head_ ∈ {ops__}] :=
Quiet#Pick[{ops}, expr /. head -> # & /# {ops}]
findFunction[f[2, 3] == 5, f ∈ {Plus, Minus, Divide}]
(* Out[]= {Plus} *)
I'm not aware of a built-in function, but it's not hard to write one yourself. Here is one approach that you can use:
Clear#correctOperatorQ;
correctOperatorQ[expr_, value_,
operators_] := (expr == value) /. Head[expr] -> # & /# operators
By the way, the correct operator for 2-3 is Subtract, not Minus. The result for your example:
correctOperatorQ[f[2, 3], 5, {Plus,Subtract,Divide}]
Out[1]={True, False, False}

Mathematica function with multiple IF[] conditionals

I have here a complicated bit of code that is not pretty nor easy to follow, but it represents a simplification of a larger body of code I am working with. I am a Mathematica novice and have already received some help on this issue from stackoverflow but it is still not solving my problem. Here is the code for which I hope you can follow along and assume what I am trying to get it to do. Thanks to you programming whizzes for the help.
a[b_, c_] = -3*b + 2*c + d + e + f;
g[b_, c_] := If[a[b, c] < 0, -3*a[b, c], a[b, c]];
h[T_, b_, c_] = (T/g[b, c]);
i[h_, T_, b_, c_] := If[h[T, b, c] > 0, 4*h[T, b, c], -5*h[T, b, c]];
j[b_, c_] := If[a[b, c] < 0, 5*a[b, c], 20*a[b, c]];
XYZ[h_, T_, i_, g_, j_, b_, c_] = T*i[h, T, b, c]*g[b, c] + j[b, c]
rules = {a -> 1, b -> 2, c -> 3, d -> 4, e -> 5, f -> 6, T -> 10};
XYZ[h, T, i, g, j, b, c] //. rules
Preserving as much of your code as possible, it will work with just a few changes:
a[b_, c_] := -3*b + 2*c + d + e + f;
g[b_, c_] := If[# < 0, -3 #, #] & # a[b, c]
h[T_, b_, c_] := T / g[b, c]
i[h_, T_, b_, c_] := If[# > 0, 4 #, -5 #] & # h[T, b, c]
j[b_, c_] := If[# < 0, 5 #, 20 #] & # a[b, c]
XYZ[h_, T_, i_, g_, j_, b_, c_] := T*i[h, T, b, c]*g[b, c] + j[b, c]
rules = {a -> 1, b -> 2, c -> 3, d -> 4, e -> 5, f -> 6, T -> 10};
XYZ[h, T, i, g, j, b, c] /. rules
(* Out= 700 *)
If statements are again externalized, as in the last problem.
all definitions are made with SetDelayed (:=), as a matter of good practice.
The presumed error T - 10 in your rules is corrected to T -> 10
Notice that again ReplaceRepeated (//.) is not needed, and is changed to /.
We still have a nonsensical rule a -> 1 but it does not cause a failure.

Pattern matching Inequality

I'd like to extract arguments from instances of Inequality. Following doesn't work, any idea why and how to fix it?
Inequality[1, Less, x, Less, 2] /. Inequality[a_, _, c_, _, e_] -> {a, c, e}
Inequality[1,Less,x,Less,2] /. HoldPattern[Inequality[a_,_,b_,_,c_]] -> {a, b, c}
Out: {1, x, 2}
Also, you can do this:
Inequality[1, Less, x, Less, 2] /.
Literal # Inequality[ a_ , _ , c_ , _ , e_ ] -> {a, c, e}
ADL
Why don't you use standard access to subexpression?
expr = Inequality[1, Less, x, Less, 2];
{a,c,e} = {expr[[1]], expr[[3]], expr[[5]]};

Resources