```
/* **********************************
*   ComputeQuality.java
*     ComputeQuality
* **********************************/

import edu.neu.ccs.demeterf.demfgen.lib.List;
import edu.neu.ccs.evergreen.ir.Relation;
import gen.*;

public class ComputeQuality{
/** Compute the quality of an assignment == satRatio(reduce(rm,a)) */
public static Quality quality(RawMaterial rm, Assignment a){
RawMaterial reduced =
a.literals.fold(new List.Fold<Literal,RawMaterial>(){
public RawMaterial fold(Literal lit, RawMaterial r){ return reduce(r, lit); }
},rm);
return new Quality(satisfiedRatio(reduced));
}
/** Reduce a given RawMaterial based on a single Literal assignment */
public static RawMaterial reduce(RawMaterial s, final Literal lit){
return new RawMaterial(new RawMaterialInstance(s.instance.cs.map(new List.Map<Constraint,Constraint>(){
public Constraint map(Constraint c){
int i = c.vs.index(lit.var);
if(i < 0 || (c.r.v == 255))return c;
return new Constraint(c.w, new RelationNr(new Relation(3, c.r.v)
.reduce(i, lit.value.sign())), c.vs);
}})));
}
/** Accumulation for the satisfaction ratio */
static class R{
double top, bot;
R(double t, double b){ top = t; bot = b; }
R add(int t, int b){ return new R(top+t, bot+b); }
double result(){ return bot==0.0?1.0:top/(double)bot; }
}
/** Calculate the satifaction ratio of a (reduced) RawMaterial */
public static double satisfiedRatio(RawMaterial rm){
return rm.instance.cs.fold(new List.Fold<Constraint,R>(){
public R fold(Constraint c, R r){ return r.add((c.r.v == 255)?c.w.v:0, c.w.v); }
}, new R(0,0)).result();
}
}
```