Search in sources :

Example 26 with Pair

use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.

the class PolynomialSummation method sum.

/**
 * Compute the sum for the summation of a polynomial.
 *
 * @param indexOfSummation
 *        the index variable of the summation.
 * @param lowerBoundExclusive
 *        the lower bound of the summation.
 * @param upperBoundInclusive
 *        the upper bound of the summation.
 * @param summand
 *        the polynomial to be summed.
 * @return the sum of the given summation.
 */
public static Polynomial sum(Expression indexOfSummation, Expression lowerBoundExclusive, Expression upperBoundInclusive, Polynomial summand) {
    Polynomial result;
    List<Expression> indexVariable = Arrays.asList(indexOfSummation);
    Polynomial summandAsPolynomialOfIndex = DefaultPolynomial.make(summand, indexVariable);
    int n = summandAsPolynomialOfIndex.degree();
    // 
    // collect the t coefficients
    List<Expression> tCoefficients = new ArrayList<>(n);
    for (int i = 0; i <= n; i++) {
        tCoefficients.add(Expressions.ZERO);
    }
    for (int i = 0; i < summandAsPolynomialOfIndex.numberOfTerms(); i++) {
        Monomial term = summandAsPolynomialOfIndex.getMonomials().get(i);
        tCoefficients.set(term.getPowerOfFactor(indexOfSummation).intValue(), term.getCoefficient(indexVariable));
    }
    // 
    // compute polynomials R_i(x) = (x + l)^i for each i
    Expression indexOfSummationPlusLowerBound = new DefaultFunctionApplication(PLUS_FUNCTOR, Arrays.asList(indexOfSummation, lowerBoundExclusive));
    Polynomial indexOfSummationPlusLowerBoundPolynomial = DefaultPolynomial.make(indexOfSummationPlusLowerBound, indexVariable);
    List<Polynomial> rPolynomials = new ArrayList<>(n);
    rPolynomials.add(DefaultPolynomial.make(Expressions.ONE, indexVariable));
    rPolynomials.add(indexOfSummationPlusLowerBoundPolynomial);
    for (int i = 2; i <= n; i++) {
        rPolynomials.add(rPolynomials.get(i - 1).times(indexOfSummationPlusLowerBoundPolynomial));
    }
    Map<Pair<Integer, Integer>, Expression> indexedRCoefficient = new LinkedHashMap<>();
    for (int i = 0; i <= n; i++) {
        Polynomial rPolynomial = rPolynomials.get(i);
        for (int q = 0; q <= i; q++) {
            Pair<Integer, Integer> indexKey = new Pair<>(i, q);
            Monomial rqxq = rPolynomial.getMapFromSignatureToMonomial().get(Arrays.asList(new Rational(q)));
            if (rqxq == null) {
                indexedRCoefficient.put(indexKey, Expressions.ZERO);
            } else {
                indexedRCoefficient.put(indexKey, rqxq.getCoefficient(indexVariable));
            }
        }
    }
    // 
    // compute "constants" (may contain variables other than x)
    // s_i,q,j =   t_i*R_{i,q}/(q+1) (-1)^j choose(q+1,j) B_j
    // where R_{i,q}(x) is the coefficient in R_i(x) multiplying x^q.
    Map<Triple<Integer, Integer, Integer>, Polynomial> sConstants = new LinkedHashMap<>();
    for (int i = 0; i <= n; i++) {
        Expression ti = tCoefficients.get(i);
        for (int q = 0; q <= i; q++) {
            Expression riq = indexedRCoefficient.get(new Pair<>(i, q));
            Expression tiByriq = new DefaultFunctionApplication(TIMES_FUNCTOR, Arrays.asList(ti, riq));
            for (int j = 0; j <= q; j++) {
                Triple<Integer, Integer, Integer> indexKey = new Triple<>(i, q, j);
                Expression qPlus1 = Expressions.makeSymbol(q + 1);
                Expression minus1PowerJ = Expressions.makeSymbol(j % 2 == 0 ? 1 : -1);
                Expression chooseQplus1J = Expressions.makeSymbol(Util.binomialCoefficient(q + 1, j));
                Expression bernoulliJ = Expressions.makeSymbol(BernoulliNumber.computeFirst(j));
                Expression sConstant = new DefaultFunctionApplication(TIMES_FUNCTOR, Arrays.asList(new DefaultFunctionApplication(DIVISION_FUNCTOR, Arrays.asList(tiByriq, qPlus1)), minus1PowerJ, chooseQplus1J, bernoulliJ));
                sConstants.put(indexKey, DefaultPolynomial.make(sConstant, indexVariable));
            }
        }
    }
    // 
    // compute polynomials, for each q, j,   V_{q + 1 -j}  = (u - l)^{q + 1 - j}
    Expression upperBoundMinusLowerBound = new DefaultFunctionApplication(MINUS_FUNCTOR, Arrays.asList(upperBoundInclusive, lowerBoundExclusive));
    Polynomial upperBoundMinusLowerBoundPolynomial = DefaultPolynomial.make(upperBoundMinusLowerBound, indexVariable);
    Map<Integer, Polynomial> vValues = new LinkedHashMap<>();
    for (int q = 0; q <= n; q++) {
        for (int j = 0; j <= q; j++) {
            Integer exponent = q + 1 - j;
            if (!vValues.containsKey(exponent)) {
                vValues.put(exponent, upperBoundMinusLowerBoundPolynomial.exponentiate(exponent));
            }
        }
    }
    // 
    // Compute the w values and construct the final result.
    Polynomial ws = DefaultPolynomial.make(Expressions.ZERO, indexVariable);
    for (int i = 0; i <= n; i++) {
        for (int q = 0; q <= i; q++) {
            for (int j = 0; j <= q; j++) {
                Triple<Integer, Integer, Integer> sConstantKey = new Triple<>(i, q, j);
                Integer valueKey = q + 1 - j;
                Polynomial sConstant = sConstants.get(sConstantKey);
                Polynomial vValue = vValues.get(valueKey);
                Polynomial w = sConstant.times(vValue);
                ws = ws.add(w);
            }
        }
    }
    List<Expression> generalizedVariables = DefaultPolynomial.extractGeneralizedVariables(ws);
    if (generalizedVariables.size() > 0) {
        // Simplify in the context of the contained generalized variables
        // and then return as a single constant factor (i.e. the index variable should not be present).
        ws = DefaultPolynomial.make(ws, generalizedVariables);
    }
    result = DefaultPolynomial.make(ws, indexVariable);
    return result;
}
Also used : Polynomial(com.sri.ai.grinder.polynomial.api.Polynomial) Rational(com.sri.ai.util.math.Rational) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Triple(com.sri.ai.util.base.Triple) Expression(com.sri.ai.expresso.api.Expression) Monomial(com.sri.ai.grinder.polynomial.api.Monomial) DefaultFunctionApplication(com.sri.ai.expresso.core.DefaultFunctionApplication) Pair(com.sri.ai.util.base.Pair)

Example 27 with Pair

use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.

the class AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver method makeUpperBoundsAndStrictness.

/**
 * A method setting {@link #upperBoundsIncludingImplicitOnes} and {@link #fromUpperBoundsIncludingImplicitOnesToStrictness}
 * from constraint and variable's type.
 * @param context
 */
protected void makeUpperBoundsAndStrictness(Context context) {
    AbstractSingleVariableConstraint abstractSingleVariableConstraint = (AbstractSingleVariableConstraint) constraint;
    FunctionIterator<Expression, Pair<Expression, Boolean>> upperBoundsFromPositiveNormalizedAtomsIterator = functionIterator(predicateIterator(abstractSingleVariableConstraint.getPositiveNormalizedAtoms(), e -> e.hasFunctor(LESS_THAN)), // strict
    e -> processExplicitUpperBoundAndStrictnessPair(e.get(1), true, context));
    FunctionIterator<Expression, Pair<Expression, Boolean>> upperBoundsFromNegativeNormalizedAtomsIterator = functionIterator(predicateIterator(abstractSingleVariableConstraint.getNegativeNormalizedAtoms(), // not (X > Y) <=> X <= Y, so Y is a non-strict upper bound
    e -> e.hasFunctor(GREATER_THAN)), // non-strict
    e -> processExplicitUpperBoundAndStrictnessPair(e.get(1), false, context));
    Pair<Expression, Boolean> typeUpperBound = getTypeUpperBoundAndStrictness(context);
    Iterator<Pair<Expression, Boolean>> upperBoundsAndStrictnessIterator = new NestedIterator<>(upperBoundsFromPositiveNormalizedAtomsIterator, upperBoundsFromNegativeNormalizedAtomsIterator, typeUpperBound);
    upperBoundsIncludingImplicitOnes = arrayList();
    fromUpperBoundsIncludingImplicitOnesToStrictness = map();
    for (Pair<Expression, Boolean> boundAndStrictness : in(upperBoundsAndStrictnessIterator)) {
        Expression bound = boundAndStrictness.first;
        upperBoundsIncludingImplicitOnes.add(bound);
        Boolean strictness = boundAndStrictness.second;
        Boolean previousStrictness = fromUpperBoundsIncludingImplicitOnesToStrictness.get(bound);
        if (previousStrictness == null || (!previousStrictness && strictness)) {
            // if no strictness information so far, store current one; otherwise, only need to change it if previous occurrences were non-strict and this one is strict
            fromUpperBoundsIncludingImplicitOnesToStrictness.put(bound, strictness);
        }
    }
}
Also used : AbstractExpressionWithPropagatedLiteralsStepSolver(com.sri.ai.grinder.core.solver.AbstractExpressionWithPropagatedLiteralsStepSolver) Expressions(com.sri.ai.expresso.helper.Expressions) NestedIterator(com.sri.ai.util.collect.NestedIterator) INFINITY(com.sri.ai.expresso.helper.Expressions.INFINITY) PairOf(com.sri.ai.util.base.PairOf) Expression(com.sri.ai.expresso.api.Expression) EQUALITY(com.sri.ai.grinder.library.FunctorConstants.EQUALITY) CartesianProductIterator(com.sri.ai.util.collect.CartesianProductIterator) PairOf.makePairOf(com.sri.ai.util.base.PairOf.makePairOf) ArrayList(java.util.ArrayList) Util.in(com.sri.ai.util.Util.in) Util.map(com.sri.ai.util.Util.map) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver) AbstractSingleVariableConstraint(com.sri.ai.grinder.core.constraint.AbstractSingleVariableConstraint) Symbol(com.sri.ai.expresso.api.Symbol) Equality(com.sri.ai.grinder.library.Equality) Expressions.apply(com.sri.ai.expresso.helper.Expressions.apply) TrueContext(com.sri.ai.grinder.core.TrueContext) ConstantExpressionStepSolver(com.sri.ai.grinder.theory.base.ConstantExpressionStepSolver) Map(java.util.Map) AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver(com.sri.ai.grinder.theory.differencearithmetic.AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver) Context(com.sri.ai.grinder.api.Context) Pair.pair(com.sri.ai.util.base.Pair.pair) ConstantStepSolver(com.sri.ai.grinder.theory.base.ConstantStepSolver) Util.arrayList(com.sri.ai.util.Util.arrayList) FunctionIterator(com.sri.ai.util.collect.FunctionIterator) Pair(com.sri.ai.util.base.Pair) PredicateIterator.predicateIterator(com.sri.ai.util.collect.PredicateIterator.predicateIterator) Util.arrayListFrom(com.sri.ai.util.Util.arrayListFrom) LiteralStepSolver(com.sri.ai.grinder.theory.base.LiteralStepSolver) LESS_THAN_OR_EQUAL_TO(com.sri.ai.grinder.library.FunctorConstants.LESS_THAN_OR_EQUAL_TO) Function(com.google.common.base.Function) Iterator(java.util.Iterator) Util.iterator(com.sri.ai.util.Util.iterator) Util.list(com.sri.ai.util.Util.list) MINUS_INFINITY(com.sri.ai.expresso.helper.Expressions.MINUS_INFINITY) MaximumExpressionStepSolver(com.sri.ai.grinder.helper.MaximumExpressionStepSolver) GREATER_THAN(com.sri.ai.grinder.library.FunctorConstants.GREATER_THAN) Beta(com.google.common.annotations.Beta) GREATER_THAN_OR_EQUAL_TO(com.sri.ai.grinder.library.FunctorConstants.GREATER_THAN_OR_EQUAL_TO) StepSolver(com.sri.ai.grinder.api.StepSolver) Expressions.makeSymbol(com.sri.ai.expresso.helper.Expressions.makeSymbol) FunctionIterator.functionIterator(com.sri.ai.util.collect.FunctionIterator.functionIterator) LESS_THAN(com.sri.ai.grinder.library.FunctorConstants.LESS_THAN) Util(com.sri.ai.util.Util) FunctorConstants(com.sri.ai.grinder.library.FunctorConstants) PairOfElementsInListIterator(com.sri.ai.util.collect.PairOfElementsInListIterator) Expression(com.sri.ai.expresso.api.Expression) NestedIterator(com.sri.ai.util.collect.NestedIterator) AbstractSingleVariableConstraint(com.sri.ai.grinder.core.constraint.AbstractSingleVariableConstraint) Pair(com.sri.ai.util.base.Pair)

Example 28 with Pair

use of com.sri.ai.util.base.Pair 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;
}
Also used : Type(com.sri.ai.expresso.api.Type) Expressions(com.sri.ai.expresso.helper.Expressions) Set(java.util.Set) Expression(com.sri.ai.expresso.api.Expression) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) GrinderUtil(com.sri.ai.grinder.helper.GrinderUtil) List(java.util.List) TupleType(com.sri.ai.expresso.type.TupleType) Map(java.util.Map) Simplifier(com.sri.ai.grinder.rewriter.api.Simplifier) Context(com.sri.ai.grinder.api.Context) FunctorConstants(com.sri.ai.grinder.library.FunctorConstants) LinkedHashSet(java.util.LinkedHashSet) Pair(com.sri.ai.util.base.Pair) Context(com.sri.ai.grinder.api.Context) Expression(com.sri.ai.expresso.api.Expression) TupleType(com.sri.ai.expresso.type.TupleType) ArrayList(java.util.ArrayList) List(java.util.List) Pair(com.sri.ai.util.base.Pair)

Example 29 with Pair

use of com.sri.ai.util.base.Pair 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 30 with Pair

use of com.sri.ai.util.base.Pair in project aic-expresso by aic-sri-international.

the class ModelGenerator method maxMinProbability.

public static Pair<Double, Double> maxMinProbability(Bound b, Model m) {
    Context context = m.getContext();
    Theory theory = m.getTheory();
    Expression query = m.getQuery().getValue();
    Type type = context.getTypeOfRegisteredSymbol(query);
    if (type.getName().equals("Boolean")) {
        double maxProbabilityOfTrue = -1;
        double minProbabilityOfTrue = 10;
        if (b.isExtensionalBound()) {
            DefaultExtensionalBound extensionalBound = (DefaultExtensionalBound) b;
            List<Expression> listOfElements = extensionalBound.getArguments();
            for (Expression distribution : listOfElements) {
                // replace and evaluate
                Expression replacingQueryByTrue = distribution.replaceAllOccurrences(query, parse("true"), context);
                Expression evaluating = theory.evaluate(replacingQueryByTrue, context);
                // convert to double
                double value = evaluating.doubleValue();
                // update max and min
                if (value > maxProbabilityOfTrue) {
                    maxProbabilityOfTrue = value;
                }
                if (value < minProbabilityOfTrue) {
                    minProbabilityOfTrue = value;
                }
            }
            Pair<Double, Double> result = new Pair<>(minProbabilityOfTrue, maxProbabilityOfTrue);
            return result;
        } else if (b.isIntensionalBound()) {
        }
    }
    return null;
}
Also used : Context(com.sri.ai.grinder.api.Context) Type(com.sri.ai.expresso.api.Type) Theory(com.sri.ai.grinder.api.Theory) Expression(com.sri.ai.expresso.api.Expression) DefaultExtensionalBound(com.sri.ai.grinder.library.bounds.DefaultExtensionalBound) Pair(com.sri.ai.util.base.Pair)

Aggregations

Pair (com.sri.ai.util.base.Pair)32 Expression (com.sri.ai.expresso.api.Expression)29 ArrayList (java.util.ArrayList)20 Map (java.util.Map)17 LinkedHashMap (java.util.LinkedHashMap)12 Type (com.sri.ai.expresso.api.Type)10 List (java.util.List)10 Expressions (com.sri.ai.expresso.helper.Expressions)9 TupleType (com.sri.ai.expresso.type.TupleType)8 Context (com.sri.ai.grinder.api.Context)8 Context (com.sri.ai.grinder.sgdpllt.api.Context)6 LinkedHashSet (java.util.LinkedHashSet)6 Beta (com.google.common.annotations.Beta)5 Expressions.apply (com.sri.ai.expresso.helper.Expressions.apply)5 Expressions.makeSymbol (com.sri.ai.expresso.helper.Expressions.makeSymbol)5 Util.map (com.sri.ai.util.Util.map)5 Function (com.google.common.base.Function)4 Symbol (com.sri.ai.expresso.api.Symbol)4 INFINITY (com.sri.ai.expresso.helper.Expressions.INFINITY)4 MINUS_INFINITY (com.sri.ai.expresso.helper.Expressions.MINUS_INFINITY)4