4

It would be convenient to have a function VarsfromLogical which out of {a+b>c,c+d==a} outputs {a,b,c,d}

Incidentally, I use this for detecting the variables for FindInstance[expr,vars], and it might have been convenient for beginners if Mathematica would have offered also the syntax FindInstance[expr], because the vars are uniquely determined by the expr , and so there is no need to be explicit about them. Anyway, this may be achieved via the answers to the similar question Extracting variables from an expression or by some other instructive answers like Union[Cases[list, _Symbol, ∞]], Variables[Level[list, {-1}]] and p = Position[list, _Symbol, Heads -> False]; Extract[p] @ list Remains the question of why these lovely solutions are necessary at all in a FindInstance

florin
  • 1,798
  • 7
  • 12
  • 1
    This seems the same question: https://mathematica.stackexchange.com/questions/21257/extracting-variables-from-an-expression – Goofy Feb 10 '24 at 19:45
  • 1
    For instance Reduce`FreeVariables[{a + b > 0, c + d == a}] works (from an answer to the linked question). – Goofy Feb 10 '24 at 19:47
  • Indeed, one of the answers DeleteDuplicates@Cases[list, _Symbol, Infinity] does the job, together with all the other variants mentioned. Incidentally, I use this for detecting the variables for FindInstance[expr,vars], and it seems convenient for beginners if Mathematica would have offered also the syntax FindInstance[expr], because the vars are uniquely determined by the expr – florin Feb 10 '24 at 22:26

4 Answers4

5
list = {a + b > 0, c + d == 0};

p = Position[list, _Symbol, Heads -> False]

{{1, 1, 1}, {1, 1, 2}, {2, 1, 1}, {2, 1, 2}}

Extract[p] @ list

{a, b, c, d}

eldo
  • 67,911
  • 5
  • 60
  • 168
  • 1
    Beautiful! 4 answers showing the beauty of Mathematica:) – florin Feb 10 '24 at 18:04
  • 1
    Mikado's and my solution also work with deeply nested lists like list = {{a + b > 0, c + d == {{g + h}}}}. You don't have to worry about level-specifications. – eldo Feb 10 '24 at 18:10
  • Thanks, I see! I think I have maybe digested all the solutions, except that I would have written yours in a simpler syntax, as Extract[list, p] ; I still don't understand the point in having the alternative syntax using the prefix operator @ – florin Feb 10 '24 at 19:23
4
Union[Cases[list, _Symbol, ∞]]
mikado
  • 16,741
  • 2
  • 20
  • 54
  • This works also without Union, just Cases[list, _Symbol, [Infinity]], and also Cases[list, _Symbol, 3] – florin Feb 10 '24 at 19:05
  • 1
    @florin What does Cases[{a + b > 0, c + d == a}, _Symbol, Infinity] return for you? Also Union@Cases[{a + b > 0, c + d == a}, _Symbol, {-1}] might be better than using the level spec 3 (if you want to avoid Infinity). – Goofy Feb 10 '24 at 19:42
  • Both Cases[{a + b > 0, c + d == a}, _Symbol, Infinity] and Cases[{a + b > 0, c + d == a}, _Symbol, {-1}] output {a, b, c, d, a} on my 13.3 Oops, the a appears twice if I don't use also Union, or Variables, so these are necessary – florin Feb 10 '24 at 22:17
2
Variables@list[[All, 1]]

{a, b, c, d}


For a more general case:

list = {a + b > 0, c + d == g + h}
v1 = Variables@list[[All, 1]]
v2 = Variables@list[[All, 2]]
Union[v1, v2]

{a, b, c, d, g, h}

Syed
  • 52,495
  • 4
  • 30
  • 85
  • 1
    Variables[Level[list, {-1}]] is very robust – Bob Hanlon Feb 10 '24 at 18:28
  • As an aside, Level[list, {-1}] works also. Another issue is to understand the command Level, which seems rather sophisticated, and in particular the option -1. Thanks a lot anyway, I'm using this in a FindInstance for a list of many conditions, some nested, and it works! – florin Feb 10 '24 at 19:40
2
{a + b > 0, c + d == 0};
Variables[List @@@ %]

{a, b, c, d}
azerbajdzan
  • 15,863
  • 1
  • 16
  • 48