Search in sources :

Example 21 with IntensionalSet

use of com.sri.ai.expresso.api.IntensionalSet in project aic-expresso by aic-sri-international.

the class InversionPerformanceEvaluationTest method computeSize.

private Rational computeSize(Expression functionOnIntensionalSet, Rational resultSoFar, Context context) {
    IntensionalSet intensionalSet = (IntensionalSet) functionOnIntensionalSet.get(0);
    IndexExpressionsSet indexExpressionsSet = intensionalSet.getIndexExpressions();
    List<Expression> indices = IndexExpressions.getIndices(indexExpressionsSet);
    if (indices.size() != 1) {
        throw new UnsupportedOperationException("Currently only support singular indices");
    }
    Expression index = indices.get(0);
    Context intensionalSetContext = context.extendWith(indexExpressionsSet);
    Type type = GrinderUtil.getTypeOfExpression(index, intensionalSetContext);
    Rational result = resultSoFar.multiply(type.cardinality().rationalValue());
    Expression head = intensionalSet.getHead();
    if (Expressions.isFunctionApplicationWithArguments(head) && Sets.isIntensionalSet(head.get(0))) {
        result = computeSize(head, result, intensionalSetContext);
    }
    return result;
}
Also used : TrueContext(com.sri.ai.grinder.core.TrueContext) Context(com.sri.ai.grinder.api.Context) Type(com.sri.ai.expresso.api.Type) IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet)

Example 22 with IntensionalSet

use of com.sri.ai.expresso.api.IntensionalSet in project aic-expresso by aic-sri-international.

the class AbstractIntensionalSet method replaceSymbol.

@Override
public Expression replaceSymbol(Expression symbol, Expression newSymbol, Registry registry) {
    IntensionalSet result = this;
    IndexExpressionsSet newIndexExpressions = getIndexExpressions().replaceSymbol(symbol, newSymbol, registry);
    Expression newHead = getHead().replaceSymbol(symbol, newSymbol, registry);
    Expression newCondition = getCondition().replaceSymbol(symbol, newSymbol, registry);
    result = replaceIfNeeded(newIndexExpressions, newHead, newCondition);
    return result;
}
Also used : IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) Expression(com.sri.ai.expresso.api.Expression) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet)

Example 23 with IntensionalSet

use of com.sri.ai.expresso.api.IntensionalSet 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 24 with IntensionalSet

use of com.sri.ai.expresso.api.IntensionalSet in project aic-expresso by aic-sri-international.

the class IntersectionIntensionalSetsSimplifier method simplify.

public static Expression simplify(Expression expression, Context context) {
    Expression result = expression;
    if (expression.hasFunctor(FunctorConstants.INTERSECTION)) {
        List<Expression> intensionalMultiSetArgs = new ArrayList<>();
        List<Expression> nonIntensionalMultiSetArgs = new ArrayList<>();
        for (Expression arg : expression.getArguments()) {
            if (Sets.isIntensionalMultiSet(arg)) {
                intensionalMultiSetArgs.add(arg);
            } else {
                nonIntensionalMultiSetArgs.add(arg);
            }
        }
        if (intensionalMultiSetArgs.size() > 1) {
            boolean resultIsEmptySet = false;
            IntensionalSet intersectedMultiSet = (IntensionalSet) intensionalMultiSetArgs.get(0);
            for (int i = 1; i < intensionalMultiSetArgs.size() && !resultIsEmptySet; i++) {
                IntensionalSet otherMultiSet = standardizeApartIntensionalSets((IntensionalSet) intensionalMultiSetArgs.get(i), intersectedMultiSet, context);
                // {{ (on I1) H1 : C1 }} intersection {{ (on I2) H2 : C2 }}
                // ---->
                // {{ (on I1) H1 : C1 and evaluate(there exists I2 : C2 and H2 = H1) }}				
                IndexExpressionsSet i1 = intersectedMultiSet.getIndexExpressions();
                IndexExpressionsSet i2 = otherMultiSet.getIndexExpressions();
                Expression h1 = intersectedMultiSet.getHead();
                Expression h2 = otherMultiSet.getHead();
                Expression c1 = intersectedMultiSet.getCondition();
                Expression c2 = otherMultiSet.getCondition();
                Expression thereExists = ThereExists.make(i2, And.make(c2, Equality.make(h2, h1)));
                Context i1ExtendedContext = context.extendWith(i1);
                Expression thereExistsEvaluated = context.getTheory().evaluate(thereExists, i1ExtendedContext);
                if (thereExistsEvaluated.equals(false)) {
                    // They don't intersect, which means you have an empty
                    // set in the intersection, which means the whole thing
                    // results in the empty set.
                    resultIsEmptySet = true;
                } else if (!thereExistsEvaluated.equals(true)) {
                    // If we have a condition, other than false and true
                    // we will want to extend the current result by the condition
                    Expression extendedCondition = And.make(c1, thereExistsEvaluated);
                    intersectedMultiSet = (IntensionalSet) IntensionalSet.intensionalMultiSet(i1, h1, extendedCondition);
                    // Ensure we don't have a false condition.
                    Expression simplifiedIntersectedMultiSet = context.getTheory().evaluate(intersectedMultiSet, context);
                    if (Sets.isEmptySet(simplifiedIntersectedMultiSet)) {
                        resultIsEmptySet = true;
                    }
                }
            }
            if (resultIsEmptySet) {
                result = Sets.EMPTY_SET;
            } else if (nonIntensionalMultiSetArgs.size() > 0) {
                List<Expression> intersectedArgs = new ArrayList<>();
                intersectedArgs.add(intersectedMultiSet);
                intersectedArgs.addAll(nonIntensionalMultiSetArgs);
                result = Sets.makeIntersection(intersectedArgs.toArray(new Expression[intersectedArgs.size()]));
            } else {
                result = intersectedMultiSet;
            }
        }
    }
    return result;
}
Also used : Context(com.sri.ai.grinder.sgdpllt.api.Context) IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) Expression(com.sri.ai.expresso.api.Expression) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet)

Example 25 with IntensionalSet

use of com.sri.ai.expresso.api.IntensionalSet in project aic-expresso by aic-sri-international.

the class IntensionalUnionIntersectionEqualToEmptySetSimplifier method simplify.

public static Expression simplify(Expression expression, Context context) {
    Expression result = expression;
    if (Equality.isEquality(expression) && expression.numberOfArguments() == 2) {
        Expression intersection = null;
        Expression emptySet = null;
        for (Expression arg : expression.getArguments()) {
            if (Expressions.hasFunctor(arg, FunctorConstants.INTERSECTION)) {
                intersection = arg;
            } else if (Sets.isEmptySet(arg)) {
                emptySet = arg;
            }
        }
        if (intersection != null && emptySet != null) {
            // (&cup;<sub>i &isin; D:C</sub>&Phi;) &cap; (&cup;<sub>i' &isin; D':C'</sub>&Phi;') = &empty;
            if (intersection.getArguments().stream().allMatch(Sets::isIntensionalUnion)) {
                List<Expression> forAlls = new ArrayList<>();
                List<Expression> phis = new ArrayList<>();
                // &forall; i &isin; D : C &rArr; &forall; i' &isin; D' : C' &rArr;  (&Phi; &cap; &Phi;' = &empty;)
                for (Expression intensionalUnion : intersection.getArguments()) {
                    IntensionalSet intensionalSet = (IntensionalSet) intensionalUnion.get(0);
                    Expression[] forAllAndPhi = intensionalSetToForAllAndPhi(intensionalSet, forAlls, context);
                    Expression forAll = forAllAndPhi[0];
                    Expression phi = forAllAndPhi[1];
                    handleNestedForAlls(forAll, forAlls);
                    phis.add(phi);
                }
                result = Equality.make(Expressions.apply(FunctorConstants.INTERSECTION, phis), emptySet);
                for (int i = forAlls.size() - 1; i >= 0; i--) {
                    Expression forAll = forAlls.get(i);
                    Expression body = Implication.make(ForAll.getBody(forAll), result);
                    result = ForAll.make(ForAll.getIndexExpression(forAll), body);
                }
            }
        }
    }
    return result;
}
Also used : IntensionalSet(com.sri.ai.expresso.api.IntensionalSet) Expression(com.sri.ai.expresso.api.Expression) Sets(com.sri.ai.grinder.sgdpllt.library.set.Sets) ArrayList(java.util.ArrayList)

Aggregations

Expression (com.sri.ai.expresso.api.Expression)46 IntensionalSet (com.sri.ai.expresso.api.IntensionalSet)46 IndexExpressionsSet (com.sri.ai.expresso.api.IndexExpressionsSet)24 ExtensionalIndexExpressionsSet (com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet)15 ArrayList (java.util.ArrayList)12 Type (com.sri.ai.expresso.api.Type)11 Context (com.sri.ai.grinder.api.Context)9 Context (com.sri.ai.grinder.sgdpllt.api.Context)9 RealExpressoType (com.sri.ai.expresso.type.RealExpressoType)8 RealInterval (com.sri.ai.expresso.type.RealInterval)8 Rational (com.sri.ai.util.math.Rational)8 TrueContext (com.sri.ai.grinder.core.TrueContext)5 List (java.util.List)5 CountingFormula (com.sri.ai.expresso.api.CountingFormula)4 FunctionType (com.sri.ai.expresso.type.FunctionType)4 IntegerExpressoType (com.sri.ai.expresso.type.IntegerExpressoType)4 IntegerInterval (com.sri.ai.expresso.type.IntegerInterval)4 TupleType (com.sri.ai.expresso.type.TupleType)4 TrueContext (com.sri.ai.grinder.sgdpllt.core.TrueContext)3 Beta (com.google.common.annotations.Beta)2