# Using results of Reduce

Suppose I have function f:

f[x_, y_] := 50000 + x 30000 + y 35000;


Now I want to find the x and y when f[]<=200000. I use Reduce:

Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8 , {x,y}, Integers]


The result is:

(x == 1 && y == 1) || (x == 1 && y == 2) || (x == 1 && y == 3) ||
(x == 2 && y == 1) || (x == 2 && y == 2) || (x == 3 && y == 1)


Now I would like to use these results back into f[] but it requires formatting. I use:

results = Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8,
{x, y},Integers] /.
Or[a__, b__] -> {a, b} /.
And[a_ == c_, b_ == d_] -> {c, d}


And I use:

f[#[[1]], #[[2]]] & /@ results


to get:

{115000, 150000, 185000, 145000, 180000, 175000}


I wonder if this is the right way to do this or if it can be done easier. It seems reduce can generate different (depending on the equations of course) formats of the results and this would mean that for every type of result new rules will be needed. Is this a fact of life?

• @rcollyer Thanks for editing. Still kind of struggling to get it nice..
– Lou
Feb 15, 2012 at 20:20

You may want to look at the documentation for ToRules. When applied to the output of Reduce you provided, the result is

Sequence[{x -> 1, y -> 1}, {x -> 1, y -> 2}, {x -> 1, y -> 3},
{x -> 2, y -> 1}, {x -> 2, y -> 2}, {x -> 3, y -> 1}]


If you want to substitute this back to f[x,y], put curly braces to turn the sequence into a list and use ReplaceAll:

f[x,y] /. {%}


This will give the desired output {115000, 150000, 185000, 145000, 180000, 175000}.

• +1, I was looking for ToRules and couldn't remember it. Feb 15, 2012 at 20:45
• @rcollyer Thanks for editing my answer. I was so excited that I could finally contribute something that it did not occur to me to provide links or use the code block. Feb 15, 2012 at 20:57
• Not a problem. It was a nice answer. Feb 15, 2012 at 21:10
• ToRules is great. I didn't know that! Feb 22, 2018 at 0:53

I'd do the following:

res = Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8, {x, y}, Integers];
vals = Apply[List, res[[All, All, 2]], {0, 1}]
(*
==> {{1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {3, 1}}
*)


which uses Part in the form res[[All,All,2]] to get only the numerical values, and then Apply to replace the Or and And in the logical construct with List. For the second part, I'd again use Apply in its second short form:

f @@@ vals

50000 + x*30000 + y*35000 /. FindInstance[50000 + x*30000 + y*35000 < 200000 &&
((x == 1 && y == 1) || (x == 1 && y == 2) || (x == 1 && y == 3) ||
(x == 2 && y == 1) || (x == 2 && y == 2) || (x == 3 && y == 1)), {x, y},
Integers, 6]


(* ==>

{115000, 150000, 185000, 145000, 180000, 175000}

*)

• What about when there are more results? It seems that I first need to know how many results there are. I mean the number 6 at the end. Is it better to use FindInstance for these type of equations?
– Lou
Feb 15, 2012 at 20:35
• You can put 137 or whatever instead of 6. The documentation says: FindInstance[expr,vars,dom,n] will return a shorter list if the total number of instances is less than n. Whether FindInstance is better: I do not know. Feb 16, 2012 at 9:09