How do I get Mathematica to return a function call (conditionally) unevaluated? I expect this may use the slightly-mysterious Hold function.
As a toy example, suppose I want to define AlgebraicQ such that AlgebraicQ[x] returns True or False when Element[x, Algebraics] evaluates to True or False, but otherwise to returns AlgebraicQ[x], just like the other predicate functions do. (I can't just ask if Element[x, Algebraics] == True, because this is itself unevaluated.)
Edit: The first thing that came to mind didn't work, as you can see: ![With the definition AlgebraicQ(a_) := Element(a, Algebraics), the function AlgebraicQ[Pi+E] returns Element(E+Pi, Algebraics) instead of the desired AlgebraicQ(Pi+E). Parens used in place of brackets because of platform limitations.](https://i.stack.imgur.com/j5VO2.png)
I had tried this before posting, but on a recommendation I tried again with a fresh kernel (pictured above) with the same results. I also tried
AlgebraicQ[a_] := True /; Element[x, Algebraics]
AlgebraicQ[a_] := False /; ! Element[x, Algebraics]
based on an earlier suggestion but this seems not to work at all.
based on Szabolcs' answer:
AlgebraicQ[a_] := With[{result = Element[a, Algebraics]},
result /; MatchQ[result, True | False]]
which tests as expected:
AlgebraicQ /@ {7, Pi, Pi + E}
Out[2]= {True, False, AlgebraicQ[E + Pi]}
Answer
Here's how this can be done:
ClearAll[algebraicQ]
algebraicQ[x_] := Module[{result},
result = Element[x, Algebraics];
result /; MatchQ[result, True | False]]
The key to these types of problems is usually a special use of Condition inside Block/Module/With which allows sharing localized variables between the condition and the body of Module.
At this point I should note that the convention seems to be that any function that ends in ...Q will always return either True or False. Consider EvenQ vs Positive. EvenQ[x], with x undefined, gives False. Positive[x] stays unevaluated. I know of only a very few edge cases which don't follow this. Naming this algebraicQ would violate that convention.
Comments
Post a Comment