Использование функции в Guard не разрешено. Предложения по альтернативной реализации приветствуются

Я пытаюсь создать факторизатор простых чисел, используя fermats method.

Эта строка выдает ошибку

find_factors(A, B, FactorThis) when is_a_square(B) == true ->

call to local/imported function is_a_square/1 is illegal in guard

Единственная возможная альтернатива, которую я вижу в этой реализации, это использование какого-то оператора case внутри функции. Я избегал этого, так как это может испортить хвостовую рекурсию. Я - профан в Erlang. Какие еще есть способы реализовать эту функциональность?

get_int_part_of_sqrt(N) ->
    trunc(math:sqrt(N)).

is_a_square(N) ->
    get_int_part_of_sqrt(N) * get_int_part_of_sqrt(N) == N.

calculate_new_b(A, FactorThis) ->
    NewB = trunc(abs((A * A) - FactorThis)),
    io:format("Calculate_new_b A^2 ~w- FT ~w= NB ~w ~n",[A*A,FactorThis,NewB]),

find_factors(A, B, FactorThis) when is_a_square(B) == true ->
    io:format("find_factors true ~w ~w~n", [A, B]),
    {ok, A + get_int_part_of_sqrt(B), A - get_int_part_of_sqrt(B)};

find_factors(A, B, FactorThis) ->
    io:format("find_factors false ~w ~w~n", [A, B]),
    NewA = A + 1,
    NewB = calculate_new_b(NewA, FactorThis),
    find_factors(NewA, NewB, FactorThis).

Исследование1

Исследование2

Отредактировано. исправлен аргумент в вызове calculate_new_b

добавлен недостающий get_int_part_of_sqrts.

6
задан Community 23 May 2017 в 10:30
поделиться