# How do I apply assumptions to a module (or any CompoundExpression)?

Edit: I am looking for a way to apply assumptions to all expressions contained in a compound expression. For example,

f[x_] := CompoundExpression[Clear[n], If[x > 0, n = 1, n = 2],
Array[#1 &, n]];


Output of this function is supposed to be an array of length either 1 or 2, and that is exactly what happens, when a numeric value is passed to the function.

Now I want to do the same, but without assigning a numeric value to x. I would use assumption, that x>0, and try to execute the function. I get output:

 Array[#1 &, n]


instead of array {1}, that I would expect. I have tried the following:

Refine[f[x],{x>0}]
Assuming[x>0,Refine[f[x]]]


and even

\$Assumptions=x>0
Refine[f[x]]


But with no success.

Original text: I am trying to write a function, which performs several calculations, say:

f[a_, b_] := Module[{x},
(*some irrelevant code omitted*)
Print[If[a > b, "a", "b"]];
(*more code omitted*)
If[a>b,a,b]];


And everything runs smoothly if the two variables (a,b) are assigned a numerical value:

f[1,2]


gives output

b
2


Now I want to use this function in a symbolic calculation. And this is where my problem appears. I am trying to apply assumptions to help comparing the two values:

Clear[a, b];
Refine[f[a, b], {a > b}]


And I would expect to get output:

a
a


, but what I get instead is:

If[a>b,a,b]
a


My question is: how do I apply the assumptions to that function properly?

• Welcome to Mathematica.SE! I suggest that: 1) You take the introductory Tour now! 2) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! 3) As you receive help, try to give it too, by answering questions in your area of expertise. Commented Jan 2, 2015 at 22:22
• Refine is applied to the return value of f[a,b]. The Print statement has already happened at that point. Do you want a function that will go through the statements in the definition of f and refine each one? And then execute the refined code? Or ignore all the code except the Print statement and the return value? Commented Jan 2, 2015 at 23:24
• Hi, Michael! Yes, I am looking for a function that goes through the definition of my function and refines each statement. Commented Jan 2, 2015 at 23:31

You could replace all expressions in the compound expression by expressions refined by assumed predicates:

SetAttributes[refine,HoldFirst];
refine[expr_,pred_]:=Replace[Unevaluated@expr,x_:>Refine[x,pred],1]
refine[CompoundExpression[Clear[n],If[x>0,n=1,n=2],Array[#1&,n]],x>0]


This only replaces expressions at the 1st level inside CompoundExpression, so it will not do what you want with Print[If[a > b, "a", "b"]]. For that, you would need the replacement to give Print[Refine[If[a > b, "a", "b"], a>b]], which would require replacing up to the 2nd level.

I tried modifying refine to do so, but immediately ran into problems with unwanted replacements, e.g. Clear[n] being replaced by Clear[Refine[n, x>0]]. You might think to use something like RuleCondition to evaluate Refine wherever it's used, but then the expression being refined will also be evaluated, e.g. if n=1, Clear[Evaluate@Refine[n, x>0]] becomes Clear[1].

Lacking a better solution, I have restricted replacements to only expressions containing symbols in the predicates:

refine[expr_,pred_]:=Replace[Unevaluated@expr,x_/;
MemberQ[Unevaluated@x,Alternatives@@Cases[pred,_Symbol,Infinity],Infinity]:>
Refine[x,pred],Infinity]


which works on expressions at any level (except the 0th). This works with the CompoundExpression example, and also in the module from the original:

Module[{x},refine[Print[If[a>b,"a","b"]];If[a>b,a,b],a>b]]


However I can't vouch for its robustness in general, because even among only expressions containing symbols in the predicates, some replacements may cause problems.