use of com.sri.ai.expresso.type.TupleType in project aic-expresso by aic-sri-international.
the class TupleTheoryTestingSupport method makeTuple.
protected Expression makeTuple(TupleType tupleType) {
// Generate elements for the tuple
List<Expression> elements = new ArrayList<>();
for (Type elementType : tupleType.getElementTypes()) {
// If constants supported, use at random
if (elementType.isSampleUniquelyNamedConstantSupported() && getRandom().nextBoolean()) {
elements.add(elementType.sampleUniquelyNamedConstant(getRandom()));
} else {
String elementVariable = pickTestingVariableAtRandom(getElementVariableNamesAndTypesForTesting(), elementType, variableName -> true);
elements.add(parse(elementVariable));
}
}
Expression result = Expressions.makeTuple(elements.toArray(new Expression[elements.size()]));
return result;
}
use of com.sri.ai.expresso.type.TupleType in project aic-expresso by aic-sri-international.
the class TupleTheoryTestingSupport method makeRandomAtomOn.
@Override
public Expression makeRandomAtomOn(String mainVariable, Context context) {
Expression result;
// Construct an instance of the main tuple
Expression mainTuple;
Type mainType = getTestingVariableType(mainVariable);
if (mainType instanceof TupleType) {
mainTuple = makeSymbol(mainVariable);
} else {
TupleType mainTupleType = ensureTupleType(mainType);
mainTuple = makeTuple(mainTupleType);
}
// Pick another (or the same) variable having a compatible tuple type
String otherVariable = pickTestingVariableAtRandom(mainType, variableName -> true);
// Construct an instance of the other tuple
Type otherType = getTestingVariableType(otherVariable);
TupleType otherTupleType = ensureTupleType(otherType);
Expression otherTuple = makeTuple(otherTupleType);
// With it, form an equality or an inequality
if (getRandom().nextBoolean()) {
result = Equality.make(mainTuple, otherTuple);
} else {
result = Disequality.make(mainTuple, otherTuple);
}
return result;
}
use of com.sri.ai.expresso.type.TupleType 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.expresso.type.TupleType in project aic-expresso by aic-sri-international.
the class TupleValuedFreeVariablesSimplifier method extendContextWithComponentVariables.
private static Context extendContextWithComponentVariables(Context context, Map<Expression, TupleType> freeVariablesOfTupleType, Map<Expression, List<Pair<Expression, Integer>>> freeVariableComponentsMap) {
Map<String, String> mapFromSymbolNameToTypeName = new LinkedHashMap<>();
Set<Type> componentTypes = new LinkedHashSet<>();
for (Map.Entry<Expression, TupleType> freeVariableOfTupleType : freeVariablesOfTupleType.entrySet()) {
Expression freeVariable = freeVariableOfTupleType.getKey();
TupleType freeVariableTupleType = freeVariableOfTupleType.getValue();
componentTypes.addAll(freeVariableTupleType.getElementTypes());
List<Pair<Expression, Integer>> components = freeVariableComponentsMap.get(freeVariable);
for (Pair<Expression, Integer> freeVariableComponent : components) {
Expression freeVariableComponentVar = freeVariableComponent.first;
Type freeVariableComponentType = freeVariableTupleType.getElementTypes().get(freeVariableComponent.second - 1);
mapFromSymbolNameToTypeName.put(freeVariableComponentVar.toString(), freeVariableComponentType.getName());
}
}
Context result = (Context) GrinderUtil.extendRegistryWith(mapFromSymbolNameToTypeName, componentTypes, context);
return result;
}
use of com.sri.ai.expresso.type.TupleType in project aic-expresso by aic-sri-international.
the class TupleValuedFreeVariablesSimplifier method simplify.
public static Expression simplify(Expression expression, Context context) {
Expression result = expression;
// First see if we have any free variables.
Map<Expression, Expression> freeVariablesAndTypes = Expressions.freeVariablesAndTypes(expression, context);
if (freeVariablesAndTypes.size() > 0) {
// Retrieve those that are tuples
Map<Expression, TupleType> freeVariablesOfTupleType = freeVariablesAndTypes.entrySet().stream().filter(entry -> entry.getValue() != null && TupleType.isTupleType(entry.getValue())).collect(Collectors.toMap(e -> e.getKey(), e -> (TupleType) GrinderUtil.fromTypeExpressionToItsIntrinsicMeaning(e.getValue(), context)));
if (freeVariablesOfTupleType.size() > 0) {
final Map<Expression, List<Pair<Expression, Integer>>> freeVariableComponentsMap = constructComponentMap(freeVariablesOfTupleType, expression, context);
// Replace the free tuple variables with their componentised forms
// e.g. N --> (N1, N2)
Expression componentisedExpression = expression.replaceAllOccurrences(expr -> {
Expression replacement = expr;
List<Pair<Expression, Integer>> replacementComponents = freeVariableComponentsMap.get(expr);
if (replacementComponents != null) {
replacement = constructComponentTuple(replacementComponents);
}
return replacement;
}, context);
// Evaluate the expression with the un-componentized free tuple variables, within an extended
// context that knows about the newly componentized variables
Context contextExtendedWithComponentVariables = extendContextWithComponentVariables(context, freeVariablesOfTupleType, freeVariableComponentsMap);
Expression evaluatedResult = context.getTheory().evaluate(componentisedExpression, contextExtendedWithComponentVariables);
// Translate back the free variable components
// e.g:
// if N1 = 2 then 29 else 30
// ---->
// if get(N, 1) = 2 then 29 else 30
final Map<Expression, Pair<Expression, Integer>> componentToFreeVariableMap = createReverseLookupMap(freeVariableComponentsMap);
result = evaluatedResult.replaceAllOccurrences(expr -> {
Expression replacement = expr;
Pair<Expression, Integer> correspondingFreeVariableWithIndex = componentToFreeVariableMap.get(expr);
if (correspondingFreeVariableWithIndex != null) {
replacement = Expressions.apply(FunctorConstants.GET, correspondingFreeVariableWithIndex.first, correspondingFreeVariableWithIndex.second);
}
return replacement;
}, contextExtendedWithComponentVariables);
}
}
return result;
}
Aggregations