Gustav, Good question.

The general principal is that validation should not depend (too much) no the actual answer, and should mostly be about syntax issues. That way validation doesn't vary (too much) from question to question. In my view, interface & "validity" should be a reasonably stable concept from the student's point of view.

There is a "same type" concept, which does of course depend on the actual answer, but this was mostly to ensure system stability. If the PRT expects an *equation* y=m*x+c and the student gives an *expression* e.g. m*x=c, then when the PRT take the right hand side, you get an error. Lots of assumptions about student's responses, and problems arrise from false assumptions, can be dealt with by having type at the validation level.

Ideally, we'd have a more subtle and sophisticated concept of type, e.g. %poly(Z; x), or %poly(Q; x,a), etc. This could then be used selectively to reject some things which can't possibly be correct. I think this might be difficult to author, and hard for students to understand.

To actually answer your question, have a look at Maxima's listofvars() function.

There are a couple of ways of using listofvars(ex). If you'd just like to know if a single variable appears in an expression use

member(p,listofvars(ans1));

To check if it depends on more than one variable in a single step, use sets. I'd do

AlgEquiv test on setify(listofvars(ans1)) with {x,a,b,c}.

for example, where the set {x,a,b,c} is the set of variables you want.

Chris