MonicFactory.java
package edu.udel.cis.vsl.tass.symbolic.monic;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import edu.udel.cis.vsl.tass.symbolic.NumericPrimitive;
import edu.udel.cis.vsl.tass.symbolic.IF.tree.NumericConcreteExpressionIF;
import edu.udel.cis.vsl.tass.symbolic.IF.type.SymbolicTypeIF;
import edu.udel.cis.vsl.tass.symbolic.cast.CastFactory;
import edu.udel.cis.vsl.tass.symbolic.concrete.ConcreteFactory;
import edu.udel.cis.vsl.tass.symbolic.expression.SymbolicExpression;
import edu.udel.cis.vsl.tass.symbolic.expression.SymbolicExpressionKey;
import edu.udel.cis.vsl.tass.symbolic.power.PowerExpression;
import edu.udel.cis.vsl.tass.symbolic.power.PowerExpressionFactory;
import edu.udel.cis.vsl.tass.symbolic.type.SymbolicTypeFactory;
public class MonicFactory {
private SymbolicTypeFactory typeFactory;
private CastFactory castFactory;
private PowerExpressionFactory powerExpressionFactory;
private ConcreteFactory concreteFactory;
private SymbolicTypeIF integerType, realType;
private Map<SymbolicExpressionKey<MonicMonomial>, MonicMonomial> map = new HashMap<SymbolicExpressionKey<MonicMonomial>, MonicMonomial>();
private MonicMonomial emptyIntMonic, emptyRealMonic;
private NumericConcreteExpressionIF oneIntConcrete;
public MonicFactory(SymbolicTypeFactory typeFactory,
CastFactory castFactory,
PowerExpressionFactory powerExpressionFactory,
ConcreteFactory concreteFactory) {
integerType = typeFactory.integerType();
realType = typeFactory.realType();
this.typeFactory = typeFactory;
this.castFactory = castFactory;
this.concreteFactory = concreteFactory;
this.powerExpressionFactory = powerExpressionFactory;
oneIntConcrete = concreteFactory.oneIntExpression();
emptyIntMonic = monic(integerType, new PowerExpression[] {});
emptyRealMonic = monic(realType, new PowerExpression[] {});
}
public MonicMonomial emptyIntMonic() {
return emptyIntMonic;
}
public MonicMonomial emptyRealMonic() {
return emptyRealMonic;
}
public SymbolicTypeFactory typeFactory() {
return typeFactory;
}
public PowerExpressionFactory powerExpressionFactory() {
return powerExpressionFactory;
}
public MonicMonomial monic(SymbolicTypeIF numericType,
PowerExpression[] factorPowers) {
return SymbolicExpression.flyweight(map, new MonicMonomial(numericType,
factorPowers));
}
public MonicMonomial monicMonomial(NumericPrimitive expression,
NumericConcreteExpressionIF exponent) {
SymbolicTypeIF type;
PowerExpression powerExpression = powerExpressionFactory
.powerExpression(expression, exponent);
assert expression != null;
type = expression.type();
if (type.isInteger()) {
return monic(integerType, new PowerExpression[] { powerExpression });
} else if (type.isReal()) {
return monic(realType, new PowerExpression[] { powerExpression });
} else {
throw new IllegalArgumentException(
"Expression not of numeric type: " + expression);
}
}
public MonicMonomial monicMonomial(NumericPrimitive expression) {
return monicMonomial(expression, oneIntConcrete);
}
public MonicMonomial multiply(MonicMonomial monic0, MonicMonomial monic1) {
PowerExpression[] factors0, factors1;
int numFactors0, numFactors1, index0 = 0, index1 = 0;
LinkedList<PowerExpression> factorList = new LinkedList<PowerExpression>();
assert monic0 != null;
assert monic1 != null;
assert monic0.type().equals(monic1.type());
factors0 = monic0.factorPowers();
factors1 = monic1.factorPowers();
numFactors0 = factors0.length;
numFactors1 = factors1.length;
while (index0 < numFactors0 && index1 < numFactors1) {
PowerExpression factorPower0 = factors0[index0];
PowerExpression factorPower1 = factors1[index1];
int compare = SymbolicExpression.compare(
(SymbolicExpression) factorPower0.base(),
(SymbolicExpression) factorPower1.base());
if (compare == 0) {
factorList.add(powerExpressionFactory.powerExpression(
factorPower0.base(), concreteFactory.add(factorPower0
.exponent(), factorPower1.exponent())));
index0++;
index1++;
} else if (compare > 0) {
factorList.add(factorPower1);
index1++;
} else {
factorList.add(factorPower0);
index0++;
}
}
while (index0 < numFactors0) {
factorList.add(factors0[index0]);
index0++;
}
while (index1 < numFactors1) {
factorList.add(factors1[index1]);
index1++;
}
return monic(monic0.type(), factorList
.toArray(new PowerExpression[factorList.size()]));
}
public MonicMonomial castToReal(MonicMonomial monic) {
PowerExpression[] factorPowers = monic.factorPowers();
int numFactors = factorPowers.length;
MonicMonomial result = emptyRealMonic;
for (int i = 0; i < numFactors; i++)
result = multiply(result, monicMonomial(castFactory
.realCast((NumericPrimitive) factorPowers[i].base()),
factorPowers[i].exponent()));
return result;
}
}