use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.
the class Measure method get.
public static Rational get(Expression intensionalSetExpression, Context context) {
Rational result;
if (Sets.isIntensionalSet(intensionalSetExpression)) {
IntensionalSet intensionalSet = (IntensionalSet) intensionalSetExpression;
IndexExpressionsSet indexExpressionsSet = intensionalSet.getIndexExpressions();
List<Expression> indices = IndexExpressions.getIndices(indexExpressionsSet);
if (indices.size() == 1) {
Expression evaluatedResult;
Expression intensionalSetIndex = indices.get(0);
Expression intensionalSetHead = intensionalSet.getHead();
if (!intensionalSetHead.equals(intensionalSetIndex)) {
throw new UnsupportedOperationException("Index and Head must be the same to calculate the meaure of an Intensional : " + intensionalSet);
}
Expression intensionalSetCondition = intensionalSet.getCondition();
Context intensionalSetContext = context.extendWith(indexExpressionsSet);
Type indexType = GrinderUtil.getTypeOfExpression(intensionalSetIndex, intensionalSetContext);
if (intensionalSetCondition.equals(false)) {
// short circuit known empty sets up front.
evaluatedResult = Expressions.ZERO;
} else if (indexType instanceof RealExpressoType || indexType instanceof RealInterval) {
// NOTE : For Reals can always assume the condition is of this type.
SingleVariableLinearRealArithmeticConstraint svConstraint = (SingleVariableLinearRealArithmeticConstraint) intensionalSetCondition;
MeasureOfSingleVariableLinearRealArithmeticConstraintStepSolver realSolver = new MeasureOfSingleVariableLinearRealArithmeticConstraintStepSolver(svConstraint);
evaluatedResult = realSolver.solve(intensionalSetContext);
} else if (indexType instanceof FunctionType) {
if (!intensionalSetCondition.equals(true)) {
throw new UnsupportedOperationException("Measure of intensional set with a function type domain currently do not support conditions: " + intensionalSet);
}
// measure(co-domain)^measure(domain)
FunctionType indexFunctionType = (FunctionType) indexType;
Expression condomainIntensionalSet = constructComponentIntensionalSet(indexFunctionType.getCodomain(), intensionalSet, ZERO, intensionalSetContext);
Rational codomainMeasure = get(condomainIntensionalSet, intensionalSetContext);
Rational domainMeasure = Rational.ONE;
for (Type argDomainType : indexFunctionType.getArgumentTypes()) {
Expression argDomainIntensionalSet = constructComponentIntensionalSet(argDomainType, intensionalSet, ZERO, intensionalSetContext);
Rational argMeasure = get(argDomainIntensionalSet, intensionalSetContext);
domainMeasure = domainMeasure.multiply(argMeasure);
}
evaluatedResult = Expressions.makeSymbol(codomainMeasure.pow(domainMeasure.intValueExact()));
} else if (indexType instanceof TupleType) {
if (!intensionalSetCondition.equals(true)) {
throw new UnsupportedOperationException("Measure of intensional set with a tuple type domain currently do not support conditions: " + intensionalSet);
}
// (element_1, ..., element_n) = measure(element_1) * ... * measure(element_n)
TupleType indexTupleType = (TupleType) indexType;
Rational elementMeasuresProduct = Rational.ONE;
for (Type elementType : indexTupleType.getElementTypes()) {
Expression elementDomainIntensionalSet = constructComponentIntensionalSet(elementType, intensionalSet, ZERO, intensionalSetContext);
Rational elementMeasure = get(elementDomainIntensionalSet, intensionalSetContext);
elementMeasuresProduct = elementMeasuresProduct.multiply(elementMeasure);
}
evaluatedResult = Expressions.makeSymbol(elementMeasuresProduct);
} else {
Expression countingFormula = new DefaultCountingFormula(indexExpressionsSet, intensionalSet.getCondition());
evaluatedResult = context.getTheory().evaluate(countingFormula, context);
}
if (Expressions.isNumber(evaluatedResult)) {
result = evaluatedResult.rationalValue();
} else {
throw new UnsupportedOperationException("Unable to compute a finite measure for: " + intensionalSet + ", got : " + evaluatedResult);
}
} else {
throw new UnsupportedOperationException("Currently only support the measure of single indexed intensional sets: " + intensionalSet);
}
} else {
throw new IllegalArgumentException("Not an intensional set: " + intensionalSetExpression);
}
return result;
}
use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.
the class DefaultSyntaxLeaf method getRestrictedPrecisionNumberRepresentation.
private String getRestrictedPrecisionNumberRepresentation() {
String result;
Rational rationalValue = (Rational) valueOrRootSyntaxTree;
if (isDisplayNumericsExactlyForSymbols() && exactDecimalRepresentationMayExceedAllowedPrecision(rationalValue)) {
result = getExactRepresentationEvenIfThatMeansARatio(rationalValue);
} else {
result = getDecimalRepresentation(rationalValue);
}
return result;
}
use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.
the class DefaultSyntaxLeaf method exactDecimalRepresentationMayExceedAllowedPrecision.
private boolean exactDecimalRepresentationMayExceedAllowedPrecision(Rational rationalValue) {
boolean decimalExpansionIsKnownToBeFinite = isKnownToBePowerOf2And5Only(new Rational(rationalValue.getDenominator()));
boolean decimalExpansionMayBeInfinite = !decimalExpansionIsKnownToBeFinite;
return decimalExpansionMayBeInfinite;
}
use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.
the class DefaultSyntaxLeaf method removeAllFactorsEqualTo.
private Rational removeAllFactorsEqualTo(Rational rationalValue, int factor) {
boolean changed;
do {
Rational fraction = rationalValue.divide(factor);
if (fraction.isInteger()) {
rationalValue = fraction;
changed = true;
} else {
changed = false;
}
} while (changed);
return rationalValue;
}
use of com.sri.ai.util.math.Rational in project aic-expresso by aic-sri-international.
the class DefaultSymbolTest method testScientificNotationTriggeredByNumberOfDecimalPlaces.
@Test
public void testScientificNotationTriggeredByNumberOfDecimalPlaces() {
ExpressoConfiguration.setDisplayNumericsMostDecimalPlacesInApproximateRepresentationOfNumericalSymbols(10);
ExpressoConfiguration.setDisplayNumericsGreatestInitialNonZeroDecimalPlacePositionBeforeSwitchingToScientificNotation(4);
Assert.assertEquals("0.001", Expressions.makeSymbol(new Rational(1, 1000)).toString());
Assert.assertEquals("0.0001", Expressions.makeSymbol(new Rational(1, 10000)).toString());
Assert.assertEquals("1E-5", Expressions.makeSymbol(new Rational(1, 100000)).toString());
Assert.assertEquals("1E-6", Expressions.makeSymbol(new Rational(1, 1000000)).toString());
ExpressoConfiguration.setDisplayNumericsMostDecimalPlacesInApproximateRepresentationOfNumericalSymbols(3);
ExpressoConfiguration.setDisplayNumericsGreatestInitialNonZeroDecimalPlacePositionBeforeSwitchingToScientificNotation(12);
Assert.assertEquals("0.001", Expressions.makeSymbol(new Rational(1, 1000)).toString());
Assert.assertEquals("1E-4", Expressions.makeSymbol(new Rational(1, 10000)).toString());
Assert.assertEquals("1E-5", Expressions.makeSymbol(new Rational(1, 100000)).toString());
Assert.assertEquals("1E-6", Expressions.makeSymbol(new Rational(1, 1000000)).toString());
}
Aggregations