# Assigning domain and/or value restrictions to multiple variables at once

Suppose I want to assign value and/or domain restrictions to a set of variables. As an example, let expr be some function of a, b, c, d, and e. Instead of writing, say:

Solve[expr == z,
-10<=a<=10 && -10<=b<=10 && -10<=c<=10 && -10<=d<=10 && -10<=e<=10 &&
a ∈ Integers && b ∈ Integers && c ∈ Integers && d ∈ Integers && e ∈ Integers,
{a,b,c,d,e}]

... is it possible to instead write that in a shorter form—specifically one that allows me to apply the restrictions to all the variables at once, so I don't have to repeat them for each variable? In other words, something like this (I'm just making this up for illustration):

Solve[expr == z,
-10<=(a|b|c|d|e)<=10 && (a|b|c|d|e) ∈ Integers, {a,b,c,d,e}]

Yes, I could shorten it by intead applying the general Integer domain restriction, but that's functionally different. Plus I often get better performance when I apply the restrictions to the variables individually.

• Something like And@@Thread[-10<{a,b,c,d}<=10]? Jul 24, 2023 at 8:31
• @LukasLang That works for the values, and I like its simplicity, but it doesn't seem to work for the Integers. Jul 24, 2023 at 18:06
• Your syntax of (a|b|c|d) ∈ Integers should already work, or not? Jul 24, 2023 at 21:04
• Hunh, it actually does..and I just found it in the documentation for Integers: (x1 | x2 | ...) ∈ Integers and {x1, x2, ... } ∈ Integers} test whether all xi are integers. I tried it on both my restrictions together, and it didn't work, but it appears it's just equalities & inequalities for which it doesn't function. Thus it seems your solution would be: Solve[expr == z && (a|b|c|d|e) ∈ Integers && And@@Thread[-10<{a,b,c,d,e}<=10], {a,b,c,d,e}]. Would you like to post this as an answer? Jul 24, 2023 at 22:43
• Actually, Solve[expr == z && {a,b,c,d,e} ∈ Integers && And@@Thread[-10<{a,b,c,d,e}<=10], {a,b,c,d,e}] would be even more efficient, since you'd just need to type the list of variables once, and could then copy-paste it into the other two locations. Jul 24, 2023 at 23:04

Using code from similar question in "Assume whatever makes it easier" command but making small changes

For first example

expr = z + a + b + Pi + m/Sin[a] + b[0]*Exp[h] + c + d + e + a;
vars = DeleteDuplicates@
Cases[expr, any_ /; Head[any] === Symbol &&
Not[MemberQ[Attributes[any], Constant]], Infinity]
assum1 = Element[#, Integers] & /@ vars
assum2 = Thread[10 <= vars <= 10]
assum3 = And @@ Join[assum1, assum2]

Now you can use the above in your command

Solve[expr == z && assum3, vars]

You can do similar thing to your second example.

As an alternative to Nasser's fancy answer, I'll post this for those who prefer a simpler approach. It's based on the comment from @Lukas Lang.

The following:

Solve[expr == z, -10<=a<=10 && -10<=b<=10 && -10<=c<=10 && -10<=d<=10
&& -10<=e<=10 && a ∈ Integers && b ∈ Integers
&& c ∈ Integers && d ∈ Integers && e ∈ Integers, {a,b,c,d,e}]

Can be expressed as:

&& {a,b,c,d,e} ∈ Integers, {a,b,c,d,e}]

Essentially, for domain restrictions, you can collect variables into a list and apply the restriction. This is officialy supported, as it can be found in the documentation, e.g.:

However, this syntax won't work with equalities or inequalities (e.g.,-10<={a,b,c,d,e}<=10), since that would constitute applying a scalar test to a vector. For those, the And@@Thread[...] syntax can be used.

This approach also works within Assumptions—these all give the same output:

Solve[a x^2 + 3 b x == 1 && a >= 1 && b <= 1 && x >= 1
&& a ∈ Integers && b ∈ Integers && x ∈ Integers, x]

Solve[a x^2 + 3 b x == 1 && And @@ Thread[{a, x} >= 1] && b <= 1
&& {a, b, x} ∈ Integers , x]

Solve[a x^2 + 3 b x == 1, x, Assumptions->And @@ Thread[{a, x} >= 1] && b <= 1
&& {a, b, x} ∈ Integers]