Синтаксическая ошибка в охране, вызывающая неопределенную функцию - PullRequest
1 голос
/ 02 мая 2020

Понятия не имею, в чем проблема, это код -

solve_bdd(BddTree, ListVars) ->
  findRes(BddTree, maps:from_list(ListVars++[{one, 1}, {zero, 0}])).
findRes(BddTree, Map) when is_record(BddTree, node)-> Val = maps:get(getName(BddTree)), Name = getName(BddTree),
  if Name=='one' or Name=='zero' -> maps:get(getName(BddTree));
     (Val==1 or Val=='true') -> findRes(getRight(BddTree), Map);
     (Val==0 or Val=='false') -> findRes(getLeft(BddTree), Map);
     true -> error
  end;
findRes(_, _) -> error.

И ошибки оболочки -

exf.erl:183: syntax error before: '=='
exf.erl:180: function findRes/2 undefined
exf.erl:21: Warning: function getRight/1 is unused
exf.erl:22: Warning: function getLeft/1 is unused
error

1 Ответ

2 голосов
/ 02 мая 2020

При наличии нескольких условий необходимо сгруппировать операнды оператора or в скобках:

1> false or false.
false

2> false == true or false == true.
* 1: syntax error before: '=='

2> (false == true) or (false == true).
false

Также maps:get/1 (функция get в модуле maps, которая принимает 1 параметр), что Вы использовали:

maps:get( getName(BddTree) )

не существует! Но вы можете использовать maps:get/2 или maps:get/3.

Большую часть времени вы можете использовать выражение case вместо if выражения.
Также иногда лучше использовать оператор orlese вместо or.
Лучше не справиться с чем угодно! вместо того, чтобы обрабатывать 0 и 1 и логические типы, вы можете использовать один из них и удалить ненужные проверки.
По соглашению в Erlang лучше записывать имена функций и записей в Snake_case .

Кстати, ваша findRes/2 функция будет выглядеть так:

%%% I don't know what work you expect from this function so if it's not working
%%% just like your own, try to fix it!  

% findRes -> find_res
find_res(BddTree, Map) when is_record(BddTree, node) ->
  % Sounds like BddTree is a record. If by `get_name/1` you just want to
  % access one of it's elements, you can simply write BddTree#node.<ELEMENT_NAME>
  % getName -> get_name
  case get_name(BddTree) of
    % you don't have to use ' character for atoms:
    Name when Name == one orelse Name == zero ->
      % I thinkd you've missed `Map`:
      maps:get(get_name(BddTree), Map);
    _ -> 
      % I do not use 0 and 1 and just use boolean type:
      find_res(
        % I thinkd you've missed `Map`:
        case maps:get(get_name(BddTree), Map) of
          Val when Val -> % when Val == true
            % getRight -> get_right
            get_right(BddTree);
          _ -> % Assume false
            get_left(BddTree)
        end,
        Map
      )
  end;

find_res(_, _) -> error.

И давайте посмотрим на приведенный выше код без комментариев:

find_res(BddTree, Map) when is_record(BddTree, node) ->
  case get_name(BddTree) of
    Name when Name == one orelse Name == zero ->
      maps:get(get_name(BddTree), Map);
    _ -> 
      find_res(
        case maps:get(get_name(BddTree), Map) of
          Val when Val -> % when Val == true
            get_right(BddTree);
          _ ->
            get_left(BddTree)
        end,
        Map
      )
  end;
find_res(_, _) -> error.
...