It came down to using a combination of bizarroArithmetic and a list_checker. Before I had been checking each element of the set one at a time and it was causing trouble by claiming that even non-fractions were unsimplified when the answer was not working (see my first question in this thread).
Here is the checker I used for the solution set:
\{SECTION_ANS($solset->cmp(entry_type => "a solution",
list_checker => sub {
my ($correct,$student,$ansHash,$value) = @_;
my $n = scalar(@$student); # number of student answers
my $score = 0; # number of correct student answers
return 0 if $ansHash->{isPreview};
$student = $ansHash->{student_formula};
$correct = $ansHash->{correct_ans};
$student = Formula("$student"); $correct = Formula("$correct");
return 0 unless ($correct == $student);
Context()->flags->set(bizarroDiv=>1);
delete $correct->{test_values}, $student->{test_values};
my $OK = (($correct == $student) or ($student == $correct)) ;
Context()->flags->set(bizarroDiv=>0);
Value::Error("Your answer is correct, but please simplify it further.") unless $OK;
if ($OK) {$score = $n};
return $score;
}
))
To remind you, here is how I had defined the solutions $an1 and $an2 and $solset:
Context("LimitedFraction")->flags->set(reduceFractions => 0);
$an1 = Fraction(1,$a);
$an2 = Fraction($a,1);
Context("Inequalities-AllowStrings");
Context()->variables->are(n=>'Real');
Context()->strings->add("No solution"=>{NONE});
Parser::Number::NoDecimals;
Context()->operators->set(
'/' => {class => 'bizarro::BOP::divide', isCommand => 1},
'//' => {class => 'bizarro::BOP::divide', isCommand => 1},
' /' => {class => 'bizarro::BOP::divide', isCommand => 1},
'/ ' => {class => 'bizarro::BOP::divide', isCommand => 1},
);
Context()->flags->set(
reduceConstants=>0, # no decimals
reduceConstantFunctions=>0, # combine 4+5*2?
formatStudentAnswer=>'parsed', # no decimals
);
$solset = Compute("{$an1, $an2}");