This will return all symbols at level -1
that are not heads and not numeric:
vars[expr_] := Union@Cases[expr, s_Symbol /; Not@NumericQ[s], {-1}]
vars[{x >= 0, y >= 0, z >= 0, 2 x >= y, 2 z >= y, 2 x + y <= 4, 2 z + y <= 4}]
(* {x,y,z} *)
Why not heads and not numeric? So vars[Sin[x] + Pi]
will give only x
but not Sin
or Pi
.
Be cautious when using this solution. I'm sure it wouldn't be hard to find cases when it returns symbols it shouldn't. It also doesn't handle non-symbol variables such as x[1]
in x[1]^2+1
, or subscripted ones such as
$x_1$. Variables
does handle these. But variables only handles polynomials, e.g. Variables[Sin[x]]
--> {Sin[x]}
.