Search in sources :

Example 11 with TupleType

use of com.sri.ai.expresso.type.TupleType in project aic-expresso by aic-sri-international.

the class GrinderUtil method getTypeExpression.

/**
	 * Returns the type of given expression according to registry.
	 */
public static Expression getTypeExpression(Expression expression, Registry registry) {
    Expression result;
    if (FormulaUtil.isApplicationOfBooleanConnective(expression)) {
        result = makeSymbol("Boolean");
    } else if (expression.getSyntacticFormType().equals(FunctionApplication.SYNTACTIC_FORM_TYPE) && list(SUM, PRODUCT, MAX).contains(expression.getFunctor().toString())) {
        Expression argument = expression.get(0);
        if (argument.getSyntacticFormType().equals(IntensionalSet.SYNTACTIC_FORM_TYPE)) {
            IntensionalSet intensionalSetArgument = (IntensionalSet) argument;
            Expression head = intensionalSetArgument.getHead();
            // NOTE: Need to extend the registry as the index expressions in the quantifier may
            // declare new types (i.e. function types).
            Registry headRegistry = registry.extendWith(intensionalSetArgument.getIndexExpressions());
            result = getTypeExpression(head, headRegistry);
        } else if (argument.getSyntacticFormType().equals(ExtensionalSets.SYNTACTIC_FORM_TYPE)) {
            List<Expression> arguments = ((AbstractExtensionalSet) argument).getElementsDefinitions();
            result = getTypeOfCollectionOfNumericExpressionsWithDefaultInteger(arguments, registry);
        } else if (expression.hasFunctor(MAX)) {
            // MAX can also be applied to a bunch of numbers
            result = getTypeOfCollectionOfNumericExpressionsWithDefaultInteger(expression.getArguments(), registry);
        } else {
            throw new Error(expression.getFunctor() + " defined for sets only but got " + expression.get(0));
        }
    } else if (Equality.isEquality(expression) || Disequality.isDisequality(expression)) {
        result = makeSymbol("Boolean");
    } else if (expression.equals(FunctorConstants.REAL_INTERVAL_CLOSED_CLOSED) || expression.equals(FunctorConstants.REAL_INTERVAL_CLOSED_OPEN) || expression.equals(FunctorConstants.REAL_INTERVAL_OPEN_CLOSED) || expression.equals(FunctorConstants.REAL_INTERVAL_OPEN_OPEN)) {
        result = FunctionType.make(parse("Set"), parse("Number"), parse("Number"));
    } else if (IfThenElse.isIfThenElse(expression)) {
        Expression thenType = getTypeExpression(IfThenElse.thenBranch(expression), registry);
        Expression elseType = getTypeExpression(IfThenElse.elseBranch(expression), registry);
        if (thenType != null && elseType != null && (thenType.equals("Number") && isIntegerOrReal(elseType) || isIntegerOrReal(thenType) && elseType.equals("Number"))) {
            result = makeSymbol("Number");
        } else if (thenType != null && elseType != null && (thenType.equals("Integer") && elseType.equals("Real") || thenType.equals("Real") && elseType.equals("Integer"))) {
            result = makeSymbol("Real");
        } else if (thenType != null && (elseType == null || thenType.equals(elseType))) {
            result = thenType;
        } else if (elseType != null && (thenType == null || elseType.equals(thenType))) {
            result = elseType;
        } else if (thenType == null) {
            throw new Error("Could not determine the types of then and else branches of '" + expression + "'.");
        } else if (thenType.equals("Integer") && elseType.hasFunctor(INTEGER_INTERVAL)) {
            // TODO: I know, I know, this treatment of integers and interval is terrible... will fix at some point
            result = thenType;
        } else if (thenType.hasFunctor(INTEGER_INTERVAL) && elseType.equals("Integer")) {
            result = elseType;
        } else if (thenType.hasFunctor(INTEGER_INTERVAL) && elseType.hasFunctor(INTEGER_INTERVAL)) {
            IntegerInterval thenInterval = (IntegerInterval) thenType;
            IntegerInterval elseInterval = (IntegerInterval) elseType;
            Expression minimumLowerBound = LessThan.simplify(apply(LESS_THAN, thenInterval.getNonStrictLowerBound(), elseInterval.getNonStrictLowerBound()), registry).booleanValue() ? thenInterval.getNonStrictLowerBound() : elseInterval.getNonStrictLowerBound();
            Expression maximumUpperBound = GreaterThan.simplify(apply(GREATER_THAN, thenInterval.getNonStrictUpperBound(), elseInterval.getNonStrictUpperBound()), registry).booleanValue() ? thenInterval.getNonStrictUpperBound() : elseInterval.getNonStrictUpperBound();
            if (minimumLowerBound.equals(MINUS_INFINITY) && maximumUpperBound.equals(INFINITY)) {
                result = makeSymbol("Integer");
            } else {
                result = apply(INTEGER_INTERVAL, minimumLowerBound, maximumUpperBound);
            }
        } else {
            throw new Error("'" + expression + "' then and else branches have different types (" + thenType + " and " + elseType + " respectively).");
        }
    } else if (isCardinalityExpression(expression)) {
        result = makeSymbol("Integer");
    } else if (isNumericFunctionApplication(expression)) {
        List<Expression> argumentTypes = mapIntoList(expression.getArguments(), e -> getTypeExpression(e, registry));
        int firstNullArgumentTypeIndexIfAny = Util.getIndexOfFirstSatisfyingPredicateOrMinusOne(argumentTypes, t -> t == null);
        if (firstNullArgumentTypeIndexIfAny != -1) {
            throw new Error("Cannot determine type of " + expression.getArguments().get(firstNullArgumentTypeIndexIfAny) + ", which is needed for determining type of " + expression);
        }
        /**
			 * commonDomain is the co-domain shared by all argument function types, or empty tuple for arguments that are not function-typed.
			 * Therefore, if no argument is function-typed, it will be equal to the empty tuple.
			 */
        Expression commonDomain = getCommonDomainIncludingConversionOfNonFunctionTypesToNullaryFunctions(argumentTypes, registry);
        if (commonDomain == null) {
            throw new Error("Operator " + expression.getFunctor() + " applied to arguments of non-compatible types: " + expression + ", types of arguments are " + argumentTypes);
        }
        boolean noArgumentIsFunctionTyped = commonDomain.equals(EMPTY_TUPLE) && !thereExists(argumentTypes, t -> t.hasFunctor(FunctorConstants.FUNCTION_TYPE));
        Expression resultCoDomain;
        if (thereExists(argumentTypes, t -> Util.equals(getCoDomainOrItself(t), "Number"))) {
            resultCoDomain = makeSymbol("Number");
        } else if (thereExists(argumentTypes, t -> Util.equals(getCoDomainOrItself(t), "Real"))) {
            resultCoDomain = makeSymbol("Real");
        } else if (thereExists(argumentTypes, t -> isRealInterval(getCoDomainOrItself(t)))) {
            resultCoDomain = makeSymbol("Real");
        } else {
            resultCoDomain = makeSymbol("Integer");
        }
        if (noArgumentIsFunctionTyped) {
            result = resultCoDomain;
        } else {
            result = apply(FUNCTION_TYPE, commonDomain, resultCoDomain);
        }
    } else if (expression.hasFunctor(FunctorConstants.INTEGER_INTERVAL) || expression.hasFunctor(FunctorConstants.REAL_INTERVAL_CLOSED_CLOSED) || expression.hasFunctor(FunctorConstants.REAL_INTERVAL_OPEN_CLOSED) || expression.hasFunctor(FunctorConstants.REAL_INTERVAL_CLOSED_OPEN) || expression.hasFunctor(FunctorConstants.REAL_INTERVAL_OPEN_OPEN)) {
        result = makeSymbol("Set");
    } else if (isComparisonFunctionApplication(expression)) {
        result = makeSymbol("Boolean");
    } else if (expression.hasFunctor(FunctorConstants.FUNCTION_TYPE)) {
        // very vague type for now
        result = apply(FUNCTION_TYPE, makeSymbol("Set"), makeSymbol("Set"));
    } else if (Sets.isIntensionalMultiSet(expression)) {
        IntensionalSet set = (IntensionalSet) expression;
        // NOTE: Need to extend the registry as the index expressions in the quantifier may
        // declare new types (i.e. function types).
        Registry headRegistry = registry.extendWith(set.getIndexExpressions());
        Expression headType = getTypeExpression(set.getHead(), headRegistry);
        result = new DefaultIntensionalMultiSet(list(), headType, TRUE);
    } else if (Sets.isExtensionalSet(expression)) {
        // very vague type for now
        result = apply(FUNCTION_TYPE, makeSymbol("Set"));
    } else if (expression.hasFunctor(FunctorConstants.INTERSECTION) || expression.hasFunctor(FunctorConstants.UNION) || expression.hasFunctor(FunctorConstants.INTENSIONAL_UNION)) {
        // very vague type for now
        result = apply(FUNCTION_TYPE, makeSymbol("Set"));
    } else if (expression.getSyntacticFormType().equals(Symbol.SYNTACTIC_FORM_TYPE)) {
        if (expression.getValue() instanceof Integer) {
            result = makeSymbol("Integer");
        } else if (expression.getValue() instanceof Double) {
            result = makeSymbol("Real");
        } else if (expression.getValue() instanceof Rational) {
            Rational rational = (Rational) expression.getValue();
            boolean isInteger = rational.isInteger();
            result = makeSymbol(isInteger ? "Integer" : "Real");
        } else if (expression.getValue() instanceof Number) {
            result = makeSymbol("Number");
        } else if (expression.getValue() instanceof String && expression.isStringLiteral()) {
            result = makeSymbol("String");
        } else if (expression.getValue() instanceof Boolean) {
            result = makeSymbol("Boolean");
        } else if (expression.equals(Expressions.INFINITY) || expression.equals(Expressions.MINUS_INFINITY)) {
            result = makeSymbol("Number");
        } else {
            result = registry.getTypeOfRegisteredSymbol(expression);
            if (result == null) {
                Type type = getFirstSatisfyingPredicateOrNull(registry.getTypes(), t -> t.contains(expression));
                if (type != null) {
                    result = parse(type.getName());
                }
            }
        }
    } else if (expression.hasFunctor(FunctorConstants.GET) && expression.numberOfArguments() == 2 && Expressions.isNumber(expression.get(1))) {
        Expression argType = getTypeExpression(expression.get(0), registry);
        if (TupleType.isTupleType(argType)) {
            TupleType tupleType = (TupleType) GrinderUtil.fromTypeExpressionToItsIntrinsicMeaning(argType, registry);
            result = parse(tupleType.getElementTypes().get(expression.get(1).intValue() - 1).toString());
        } else {
            throw new Error("get type from tuple for '" + expression + "' currently not supported.");
        }
    } else if (expression.hasFunctor(FunctorConstants.TUPLE_TYPE)) {
        // Is a type expression already.
        result = expression;
    } else if (expression.getSyntacticFormType().equals(FunctionApplication.SYNTACTIC_FORM_TYPE)) {
        Expression functionType = getTypeExpression(expression.getFunctor(), registry);
        if (functionType == null) {
            throw new Error("Type of '" + expression.getFunctor() + "' required, but unknown to registry.");
        }
        Expression coDomain = FunctionType.getCodomain(functionType);
        List<Expression> argumentsTypesList = FunctionType.getArgumentList(functionType);
        if (expression.getArguments().size() != argumentsTypesList.size()) {
            throw new Error("Function " + expression.getFunctor() + " is of type " + functionType + " but has incorrect number of arguments = " + expression.getArguments());
        }
        for (int idx = 0; idx < expression.getArguments().size(); idx++) {
            Expression arg = expression.get(idx);
            Expression argExprType = argumentsTypesList.get(idx);
            Type argType = registry.getType(argExprType);
            if (!isSubtypeOf(arg, argType, registry)) {
                throw new Error("Function " + expression.getFunctor() + " is of type " + functionType + " but has arguments that are not legal subtypes [#" + idx + "] = " + expression.getArguments());
            }
        }
        result = coDomain;
    } else if (Tuple.isTuple(expression)) {
        List<Expression> elementTypes = expression.getArguments().stream().map(element -> getTypeExpression(element, registry)).collect(Collectors.toList());
        result = TupleType.make(elementTypes);
    } else if (expression instanceof QuantifiedExpressionWithABody) {
        QuantifiedExpressionWithABody quantifiedExpressionWithABody = (QuantifiedExpressionWithABody) expression;
        // NOTE: Need to extend the registry as the index expressions in the quantifier may
        // declare new types (i.e. function types).
        Registry quantifiedExpressionWithABodyRegistry = registry.extendWith(quantifiedExpressionWithABody.getIndexExpressions());
        result = getTypeExpression(quantifiedExpressionWithABody.getBody(), quantifiedExpressionWithABodyRegistry);
    } else if (expression instanceof LambdaExpression) {
        LambdaExpression lambdaExpression = (LambdaExpression) expression;
        Collection<Expression> domain = IndexExpressions.getIndexDomainsOfQuantifiedExpression(lambdaExpression);
        IndexExpressionsSet indexExpressions = lambdaExpression.getIndexExpressions();
        Registry lambdaExpressionWithABodyRegistry = registry.extendWith(indexExpressions);
        Expression coDomain = getTypeExpression(lambdaExpression.getBody(), lambdaExpressionWithABodyRegistry);
        result = Expressions.apply(FUNCTION_TYPE, domain, coDomain);
    } else if (expression instanceof AbstractExpressionWrapper) {
        Expression innerExpression = ((AbstractExpressionWrapper) expression).getInnerExpression();
        result = getTypeExpression(innerExpression, registry);
    } else {
        throw new Error("GrinderUtil.getType does not yet know how to determine the type of this sort of expression: " + expression);
    }
    return result;
}
Also used : SUM(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.SUM) CountingFormula(com.sri.ai.expresso.api.CountingFormula) LESS_THAN_OR_EQUAL_TO(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.LESS_THAN_OR_EQUAL_TO) FALSE(com.sri.ai.expresso.helper.Expressions.FALSE) Expressions(com.sri.ai.expresso.helper.Expressions) Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) Util.getFirstSatisfyingPredicateOrNull(com.sri.ai.util.Util.getFirstSatisfyingPredicateOrNull) GreaterThan(com.sri.ai.grinder.sgdpllt.library.number.GreaterThan) ExtensionalIndexExpressionsSet(com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet) Symbol(com.sri.ai.expresso.api.Symbol) Map(java.util.Map) Util.thereExists(com.sri.ai.util.Util.thereExists) Sets(com.sri.ai.grinder.sgdpllt.library.set.Sets) Function(com.google.common.base.Function) DefaultIntensionalMultiSet(com.sri.ai.expresso.core.DefaultIntensionalMultiSet) AbstractExtensionalSet(com.sri.ai.expresso.core.AbstractExtensionalSet) Collection(java.util.Collection) Util.list(com.sri.ai.util.Util.list) RealInterval(com.sri.ai.expresso.type.RealInterval) Set(java.util.Set) Util.mapIntoList(com.sri.ai.util.Util.mapIntoList) IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) GREATER_THAN_OR_EQUAL_TO(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.GREATER_THAN_OR_EQUAL_TO) Collectors(java.util.stream.Collectors) IfThenElse(com.sri.ai.grinder.sgdpllt.library.controlflow.IfThenElse) QuantifiedExpressionWithABody(com.sri.ai.expresso.api.QuantifiedExpressionWithABody) IntegerExpressoType(com.sri.ai.expresso.type.IntegerExpressoType) Util.getFirstOrNull(com.sri.ai.util.Util.getFirstOrNull) List(java.util.List) IndexExpressions(com.sri.ai.grinder.sgdpllt.library.indexexpression.IndexExpressions) Predicate(com.google.common.base.Predicate) CARDINALITY(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.CARDINALITY) FUNCTION_TYPE(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.FUNCTION_TYPE) TIMES(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.TIMES) TRUE(com.sri.ai.expresso.helper.Expressions.TRUE) FunctorConstants(com.sri.ai.grinder.sgdpllt.library.FunctorConstants) GREATER_THAN(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.GREATER_THAN) IntStream(java.util.stream.IntStream) Tuple(com.sri.ai.expresso.api.Tuple) Categorical(com.sri.ai.expresso.type.Categorical) INFINITY(com.sri.ai.expresso.helper.Expressions.INFINITY) Util.mapIntoArrayList(com.sri.ai.util.Util.mapIntoArrayList) IntegerInterval(com.sri.ai.expresso.type.IntegerInterval) Disequality(com.sri.ai.grinder.sgdpllt.library.Disequality) ArrayList(java.util.ArrayList) TupleType(com.sri.ai.expresso.type.TupleType) Expressions.apply(com.sri.ai.expresso.helper.Expressions.apply) FormulaUtil(com.sri.ai.grinder.sgdpllt.library.FormulaUtil) Expressions.parse(com.sri.ai.expresso.helper.Expressions.parse) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet) Registry(com.sri.ai.grinder.api.Registry) PLUS(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.PLUS) LessThan(com.sri.ai.grinder.sgdpllt.library.number.LessThan) DIVISION(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.DIVISION) INTEGER_INTERVAL(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.INTEGER_INTERVAL) LinkedList(java.util.LinkedList) Util.arrayList(com.sri.ai.util.Util.arrayList) Equality(com.sri.ai.grinder.sgdpllt.library.Equality) Util.ifAllTheSameOrNull(com.sri.ai.util.Util.ifAllTheSameOrNull) LambdaExpression(com.sri.ai.expresso.api.LambdaExpression) Type(com.sri.ai.expresso.api.Type) MAX(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.MAX) RealExpressoType(com.sri.ai.expresso.type.RealExpressoType) MINUS_INFINITY(com.sri.ai.expresso.helper.Expressions.MINUS_INFINITY) ExtensionalSets(com.sri.ai.grinder.sgdpllt.library.set.extensional.ExtensionalSets) PRODUCT(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.PRODUCT) DefaultUniversallyQuantifiedFormula(com.sri.ai.expresso.core.DefaultUniversallyQuantifiedFormula) Context(com.sri.ai.grinder.sgdpllt.api.Context) Integer.parseInt(java.lang.Integer.parseInt) Beta(com.google.common.annotations.Beta) AbstractExpressionWrapper(com.sri.ai.expresso.helper.AbstractExpressionWrapper) FunctionType(com.sri.ai.expresso.type.FunctionType) FunctionApplication(com.sri.ai.expresso.api.FunctionApplication) Expressions.makeSymbol(com.sri.ai.expresso.helper.Expressions.makeSymbol) FunctionIterator.functionIterator(com.sri.ai.util.collect.FunctionIterator.functionIterator) LESS_THAN(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.LESS_THAN) EXPONENTIATION(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.EXPONENTIATION) MINUS(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.MINUS) EMPTY_TUPLE(com.sri.ai.expresso.api.Tuple.EMPTY_TUPLE) Util(com.sri.ai.util.Util) AbstractExtensionalSet(com.sri.ai.expresso.core.AbstractExtensionalSet) Rational(com.sri.ai.util.math.Rational) DefaultIntensionalMultiSet(com.sri.ai.expresso.core.DefaultIntensionalMultiSet) IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) AbstractExpressionWrapper(com.sri.ai.expresso.helper.AbstractExpressionWrapper) TupleType(com.sri.ai.expresso.type.TupleType) Util.mapIntoList(com.sri.ai.util.Util.mapIntoList) List(java.util.List) Util.mapIntoArrayList(com.sri.ai.util.Util.mapIntoArrayList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) Util.arrayList(com.sri.ai.util.Util.arrayList) ExtensionalIndexExpressionsSet(com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet) IntegerInterval(com.sri.ai.expresso.type.IntegerInterval) Registry(com.sri.ai.grinder.api.Registry) IntegerExpressoType(com.sri.ai.expresso.type.IntegerExpressoType) TupleType(com.sri.ai.expresso.type.TupleType) Type(com.sri.ai.expresso.api.Type) RealExpressoType(com.sri.ai.expresso.type.RealExpressoType) FunctionType(com.sri.ai.expresso.type.FunctionType) QuantifiedExpressionWithABody(com.sri.ai.expresso.api.QuantifiedExpressionWithABody) Expression(com.sri.ai.expresso.api.Expression) LambdaExpression(com.sri.ai.expresso.api.LambdaExpression) Collection(java.util.Collection) LambdaExpression(com.sri.ai.expresso.api.LambdaExpression)

Example 12 with TupleType

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.getType(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;
}
Also used : Context(com.sri.ai.grinder.sgdpllt.api.Context) Rational(com.sri.ai.util.math.Rational) FunctionType(com.sri.ai.expresso.type.FunctionType) DefaultCountingFormula(com.sri.ai.expresso.core.DefaultCountingFormula) RealInterval(com.sri.ai.expresso.type.RealInterval) Type(com.sri.ai.expresso.api.Type) RealExpressoType(com.sri.ai.expresso.type.RealExpressoType) FunctionType(com.sri.ai.expresso.type.FunctionType) TupleType(com.sri.ai.expresso.type.TupleType) IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) Expression(com.sri.ai.expresso.api.Expression) RealExpressoType(com.sri.ai.expresso.type.RealExpressoType) TupleType(com.sri.ai.expresso.type.TupleType) ExtensionalIndexExpressionsSet(com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet) SingleVariableLinearRealArithmeticConstraint(com.sri.ai.grinder.sgdpllt.theory.linearrealarithmetic.SingleVariableLinearRealArithmeticConstraint) MeasureOfSingleVariableLinearRealArithmeticConstraintStepSolver(com.sri.ai.grinder.sgdpllt.theory.linearrealarithmetic.MeasureOfSingleVariableLinearRealArithmeticConstraintStepSolver)

Example 13 with TupleType

use of com.sri.ai.expresso.type.TupleType in project aic-expresso by aic-sri-international.

the class TupleValuedFreeVariablesSimplifier method constructComponentMap.

private static Map<Expression, List<Pair<Expression, Integer>>> constructComponentMap(Map<Expression, TupleType> freeVariablesOfTupleType, Expression expression, Context context) {
    Map<Expression, List<Pair<Expression, Integer>>> result = new LinkedHashMap<>();
    for (Map.Entry<Expression, TupleType> freeVariableOfTupleType : freeVariablesOfTupleType.entrySet()) {
        Expression freeVariable = freeVariableOfTupleType.getKey();
        TupleType freeVariableTupleType = freeVariableOfTupleType.getValue();
        List<Pair<Expression, Integer>> components = new ArrayList<>();
        int tupleArity = freeVariableTupleType.getArity();
        for (int i = 1; i <= tupleArity; i++) {
            String proposedComponentVariableName = freeVariable.toString() + i;
            Expression componentVariable = Expressions.makeUniqueVariable(proposedComponentVariableName, expression, context);
            components.add(new Pair<>(componentVariable, i));
        }
        result.put(freeVariable, components);
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Expression(com.sri.ai.expresso.api.Expression) TupleType(com.sri.ai.expresso.type.TupleType) ArrayList(java.util.ArrayList) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Pair(com.sri.ai.util.base.Pair)

Example 14 with TupleType

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;
}
Also used : BruteForceFunctionTheoryTestingSupport.getSmallCategoricalTestingType(com.sri.ai.grinder.sgdpllt.theory.function.BruteForceFunctionTheoryTestingSupport.getSmallCategoricalTestingType) Type(com.sri.ai.expresso.api.Type) TupleType(com.sri.ai.expresso.type.TupleType) Expression(com.sri.ai.expresso.api.Expression) ArrayList(java.util.ArrayList)

Example 15 with TupleType

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;
}
Also used : BruteForceFunctionTheoryTestingSupport.getSmallCategoricalTestingType(com.sri.ai.grinder.sgdpllt.theory.function.BruteForceFunctionTheoryTestingSupport.getSmallCategoricalTestingType) Type(com.sri.ai.expresso.api.Type) TupleType(com.sri.ai.expresso.type.TupleType) Expression(com.sri.ai.expresso.api.Expression) TupleType(com.sri.ai.expresso.type.TupleType)

Aggregations

TupleType (com.sri.ai.expresso.type.TupleType)23 Expression (com.sri.ai.expresso.api.Expression)17 Type (com.sri.ai.expresso.api.Type)13 IntegerInterval (com.sri.ai.expresso.type.IntegerInterval)11 FunctionType (com.sri.ai.expresso.type.FunctionType)10 ArrayList (java.util.ArrayList)9 Map (java.util.Map)9 RealExpressoType (com.sri.ai.expresso.type.RealExpressoType)8 RealInterval (com.sri.ai.expresso.type.RealInterval)8 List (java.util.List)7 Categorical (com.sri.ai.expresso.type.Categorical)6 IntegerExpressoType (com.sri.ai.expresso.type.IntegerExpressoType)6 Context (com.sri.ai.grinder.api.Context)6 Pair (com.sri.ai.util.base.Pair)6 LinkedHashMap (java.util.LinkedHashMap)6 IndexExpressionsSet (com.sri.ai.expresso.api.IndexExpressionsSet)5 IntensionalSet (com.sri.ai.expresso.api.IntensionalSet)5 ExtensionalIndexExpressionsSet (com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet)5 Expressions (com.sri.ai.expresso.helper.Expressions)5 Rational (com.sri.ai.util.math.Rational)5