Q:

erlang "illegal guard expression" while using function in Guards

I have the following code. I am checking 3 conditions. You can see for the first condition I stored the output of xml:get_tag_attr_s(...) in a variable and then used the variable within the if block. My problem is I get error illegal guard expression, if I try to do the above process in one line like I did for the other two conditions.
Also, I am getting variable '_' is unbound from the default condition. It supposed to be the same thing. 
Can somebody please explain the issue? 
validate_xmpp(Packet) ->
      Type = xml:get_tag_attr_s(list_to_binary("type"), Packet),
      if
          (Type /= <<"chat">> ->
              {error, "Message type is not chat"};
          xml:get_path_s(Packet, [{elem, list_to_binary("body")}, cdata]) /= <<"">> ->
              {error, "No or empty body"};
          exml_query:path(Packet, [{element,<<"received">>},{attr,<<"xmlns">>}]) == <<"urn:xmpp:receipts">> ->
              {error, "delivery-receipts should be ignored"};
          _->
              {ok, xml:get_tag_attr_s(list_to_binary("from"), Packet)}
      end.

A:

Erlang allows only these to be guards:

The atom true
Other constants (terms and bound variables), all regarded as false
Calls to the BIFs (built-in functions) specified in table Type Test BIFs
Term comparisons
Arithmetic expressions
Boolean expressions
Short-circuit expressions (andalso and orelse)

For more info take a look http://www.erlang.org/doc/reference_manual/expressions.html#id83606
Instead of _ use true.  You cannot use _ in if, only in case statements, and also take a look at the docs.

A:

isPrime(A,B) when B>math:sqrt(A) -> true;

That results in an illegal guard error.  
On a first reading, it looks like the guard contains a "term comparison":
>

and an "arithmetic expression":
math:sqrt(A)

Futhermore, if you play around with the code, you will see that the guard:
B > A+2 

is legal.  So what's the difference between the "arithmetic expression" math:sqrt(A) and A+2?
The Erlang docs define an "arithmetic expression" as: `
+   
- 
*
/
div
rem
bnot
band
bor
bxor
bsl
bsr

Notably, math:sqrt() is not in the list of "arithmetic expressions".  Therefore, math:sqrt(A) is a "function call" rather than an "arithmetic expression", and you can only call a certain limited number of functions in a guard, namely the "type test BIF's" listed here, such as:
is_integer/1
is_float/1
is_binary/1
is_list/1
is_map/1
is_function/1
etc.

