Search in sources :

Example 1 with Triple

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

the class Context method extendWith.

/**
	 * Extends context with index expressions, taking into account that new contextual variables may collide with existing ones.
	 * In this case, it renames the incoming variables to unique identifiers and replaces them in the types of remaining
	 * index expressions. It also renames the variables in a given expressions supposed to be in their scope (for example,
	 * the head and condition of an intensionally defined set).
	 * Returns the new context and the index expressions and expression in scope after the renaming.
	 * @param indexExpressions
	 * @param expressionInScope
	 * @return the new context and the index expressions and expression in scope after the renaming
	 */
default default Triple<Context, ExtensionalIndexExpressionsSet, Expression> extendWith(ExtensionalIndexExpressionsSet indexExpressions, Expression expressionInScope) {
    Triple<Context, ExtensionalIndexExpressionsSet, Expression> result;
    if (thereExists(getIndices(indexExpressions), index -> this.containsSymbol(index))) {
        // OPTIMIZATION: only kick in this entire procedure when extending with symbol in the context (previous ones could have been dealt with normally).
        // the objects to be returned in the triple:
        Context newContext = this;
        ArrayList<Expression> newIndexExpressionsList = new ArrayList<>(indexExpressions.getList());
        Expression newExpressionInScope = expressionInScope;
        // Collects all existing symbols to be able to create unique symbols
        Set<Expression> alreadyDefined = Util.set();
        alreadyDefined.addAll(this.getSymbols());
        alreadyDefined.addAll(Expressions.freeSymbols(new DefaultTuple(newIndexExpressionsList), this));
        alreadyDefined.addAll(Expressions.freeSymbols(expressionInScope, this));
        Predicate<Expression> isAlreadyDefined = e -> alreadyDefined.contains(e);
        for (int i = 0; i != newIndexExpressionsList.size(); i++) {
            Expression indexExpression = newIndexExpressionsList.get(i);
            Symbol index = (Symbol) indexExpression.get(0);
            Expression type = indexExpression.get(1);
            PairOf<Expression> newIndexAndNewExpressionInScope = Expressions.standardizeApart(index, isAlreadyDefined, newExpressionInScope);
            Expression newIndex = newIndexAndNewExpressionInScope.first;
            newExpressionInScope = newIndexAndNewExpressionInScope.second;
            // type should not contain the index
            Expression newIndexExpression = apply(IN, newIndex, type);
            newIndexExpressionsList.set(i, newIndexExpression);
            alreadyDefined.add(newIndex);
            for (int j = i + 1; j != newIndexExpressionsList.size(); j++) {
                Expression anotherIndexExpression = newIndexExpressionsList.get(j);
                Expression anotherIndex = anotherIndexExpression.get(0);
                Expression anotherType = anotherIndexExpression.get(1);
                Expression newAnotherType = anotherType.replaceSymbol(index, newIndex, this);
                // anotherIndex is a symbols and does not contain index
                Expression newAnotherIndexExpression = apply(IN, anotherIndex, newAnotherType);
                newIndexExpressionsList.set(j, newAnotherIndexExpression);
            }
        }
        ExtensionalIndexExpressionsSet newIndexExpressions = new ExtensionalIndexExpressionsSet(newIndexExpressionsList);
        newContext = newContext.extendWith(newIndexExpressions);
        result = triple(newContext, newIndexExpressions, newExpressionInScope);
    } else {
        // no collision; usual extension and the expressions do not change.
        result = triple(extendWith(indexExpressions), indexExpressions, expressionInScope);
    }
    return result;
}
Also used : IN(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.IN) Type(com.sri.ai.expresso.api.Type) Triple(com.sri.ai.util.base.Triple) Collection(java.util.Collection) Expressions(com.sri.ai.expresso.helper.Expressions) Set(java.util.Set) PairOf(com.sri.ai.util.base.PairOf) Expression(com.sri.ai.expresso.api.Expression) Triple.triple(com.sri.ai.util.base.Triple.triple) DefaultTuple(com.sri.ai.expresso.core.DefaultTuple) ArrayList(java.util.ArrayList) Beta(com.google.common.annotations.Beta) ExtensionalIndexExpressionsSet(com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet) Symbol(com.sri.ai.expresso.api.Symbol) Expressions.apply(com.sri.ai.expresso.helper.Expressions.apply) Predicate(com.google.common.base.Predicate) Map(java.util.Map) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet) Registry(com.sri.ai.grinder.api.Registry) Util(com.sri.ai.util.Util) IndexExpressions.getIndices(com.sri.ai.grinder.sgdpllt.library.indexexpression.IndexExpressions.getIndices) Util.thereExists(com.sri.ai.util.Util.thereExists) Symbol(com.sri.ai.expresso.api.Symbol) ArrayList(java.util.ArrayList) DefaultTuple(com.sri.ai.expresso.core.DefaultTuple) ExtensionalIndexExpressionsSet(com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet) Expression(com.sri.ai.expresso.api.Expression)

Example 2 with Triple

use of com.sri.ai.util.base.Triple in project aic-praise by aic-sri-international.

the class HOGModelGrounding method createRandomVariableNameToTypeSizeAndUniqueConstantsMap.

//
// PRIVATE
//
private static Map<Expression, Triple<Expression, Integer, List<Expression>>> createRandomVariableNameToTypeSizeAndUniqueConstantsMap(FactorsAndTypes factorsAndTypes) {
    Map<Expression, Triple<Expression, Integer, List<Expression>>> result = new LinkedHashMap<>();
    factorsAndTypes.getMapFromRandomVariableNameToTypeName().entrySet().forEach(entry -> {
        Expression randomVariableName = Expressions.parse(entry.getKey());
        Expression type = Expressions.parse(entry.getValue());
        int size = 0;
        List<Expression> uniqueConstants = new ArrayList<>();
        if (Expressions.hasFunctor(type, FunctorConstants.FUNCTION_TYPE)) {
            throw new UnsupportedOperationException("Relational random variables, " + randomVariableName + ", are currently not supported.");
        } else if (Expressions.hasFunctor(type, HOGMSortDeclaration.IN_BUILT_INTEGER.getName()) && type.numberOfArguments() == 2) {
            size = (type.get(1).intValueExact() - type.get(0).intValueExact()) + 1;
        } else if (type.hasFunctor(FunctorConstants.INTEGER_INTERVAL) && type.numberOfArguments() == 2) {
            size = (type.get(1).intValueExact() - type.get(0).intValueExact()) + 1;
        } else {
            String sizeString = factorsAndTypes.getMapFromCategoricalTypeNameToSizeString().get(type);
            if (sizeString == null) {
                throw new IllegalArgumentException("Size of sort " + type + " is unknown");
            }
            size = Integer.parseInt(sizeString);
            factorsAndTypes.getMapFromUniquelyNamedConstantNameToTypeName().entrySet().stream().filter(uniqueConstantAndTypeEntry -> uniqueConstantAndTypeEntry.getValue().equals(entry.getValue())).forEach(uniqueConstantAndTypeEntry -> uniqueConstants.add(Expressions.parse(uniqueConstantAndTypeEntry.getKey())));
        }
        result.put(randomVariableName, new Triple<>(type, size, uniqueConstants));
    });
    return result;
}
Also used : Triple(com.sri.ai.util.base.Triple) IntStream(java.util.stream.IntStream) BinaryFunction(com.sri.ai.util.base.BinaryFunction) Triple(com.sri.ai.util.base.Triple) Expressions(com.sri.ai.expresso.helper.Expressions) Rational(com.sri.ai.util.math.Rational) Expression(com.sri.ai.expresso.api.Expression) FactorsAndTypes(com.sri.ai.praise.sgsolver.solver.FactorsAndTypes) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Symbol(com.sri.ai.expresso.api.Symbol) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InferenceForFactorGraphAndEvidence(com.sri.ai.praise.sgsolver.solver.InferenceForFactorGraphAndEvidence) Map(java.util.Map) BigInteger(java.math.BigInteger) HOGMSortDeclaration(com.sri.ai.praise.model.v1.HOGMSortDeclaration) Function(com.google.common.base.Function) TernaryProcedure(com.sri.ai.util.base.TernaryProcedure) MixedRadixNumber(com.sri.ai.util.math.MixedRadixNumber) Util.list(com.sri.ai.util.Util.list) Context(com.sri.ai.grinder.sgdpllt.api.Context) Theory(com.sri.ai.grinder.sgdpllt.api.Theory) Beta(com.google.common.annotations.Beta) List(java.util.List) ExpressionFactorsAndTypes(com.sri.ai.praise.sgsolver.solver.ExpressionFactorsAndTypes) Expressions.makeSymbol(com.sri.ai.expresso.helper.Expressions.makeSymbol) Util.myAssert(com.sri.ai.util.Util.myAssert) Expressions.isNumber(com.sri.ai.expresso.helper.Expressions.isNumber) Collections(java.util.Collections) FunctorConstants(com.sri.ai.grinder.sgdpllt.library.FunctorConstants) Expression(com.sri.ai.expresso.api.Expression) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with Triple

use of com.sri.ai.util.base.Triple in project aic-praise by aic-sri-international.

the class HOGModelGrounding method ground.

public static void ground(FactorsAndTypes factorsAndTypes, List<Expression> evidence, Listener listener) {
    if (factorsAndTypes.getMapFromNonUniquelyNamedConstantNameToTypeName().size() > 0) {
        throw new IllegalArgumentException("Constants cannot be grounded");
    }
    Map<Expression, Triple<Expression, Integer, List<Expression>>> randomVariableNameToTypeSizeAndUniqueConstants = createRandomVariableNameToTypeSizeAndUniqueConstantsMap(factorsAndTypes);
    Map<Expression, Integer> randomVariableIndexes = new LinkedHashMap<>();
    AtomicInteger atomicVariableIndex = new AtomicInteger(-1);
    listener.numberGroundVariables(randomVariableNameToTypeSizeAndUniqueConstants.size());
    randomVariableNameToTypeSizeAndUniqueConstants.entrySet().forEach(entry -> {
        randomVariableIndexes.put(entry.getKey(), atomicVariableIndex.addAndGet(1));
        listener.groundVariableCardinality(atomicVariableIndex.get(), entry.getValue().second);
    });
    Map<Expression, List<Expression>> typeToValues = createTypeToValuesMap(factorsAndTypes, randomVariableNameToTypeSizeAndUniqueConstants);
    Map<String, String> newUniqueConstantToTypeMap = createGroundedUniqueConstantToTypeMap(typeToValues);
    InferenceForFactorGraphAndEvidence inferencer = makeInferencer(factorsAndTypes, newUniqueConstantToTypeMap);
    Context context = inferencer.makeContextWithTypeInformation();
    listener.numberFactors(factorsAndTypes.getFactors().size());
    int factorIndex = 0;
    for (Expression factor : factorsAndTypes.getFactors()) {
        ArrayList<Expression> randomVariablesInFactor = new ArrayList<>(Expressions.getSubExpressionsSatisfying(factor, randomVariableNameToTypeSizeAndUniqueConstants::containsKey));
        if (randomVariablesInFactor.size() == 0) {
            throw new IllegalArgumentException("Factor contains no random variables: " + factor);
        }
        int[] participantVariableIndexes = new int[randomVariablesInFactor.size()];
        for (int i = 0; i < randomVariablesInFactor.size(); i++) {
            Expression randomVariable = randomVariablesInFactor.get(i);
            participantVariableIndexes[i] = randomVariableIndexes.get(randomVariable);
        }
        listener.factorParticipants(factorIndex, participantVariableIndexes);
        if (!useContextSensitiveGrounding) {
            fullGrounding(factor, randomVariablesInFactor, listener, randomVariableNameToTypeSizeAndUniqueConstants, typeToValues, inferencer, context);
        } else {
            contextSensitiveGrounding(factor, randomVariablesInFactor, listener, randomVariableNameToTypeSizeAndUniqueConstants, typeToValues, inferencer, context);
        }
        factorIndex++;
    }
    // Handle the evidence
    for (Expression evidenceAssignment : evidence) {
        if (Expressions.isFunctionApplicationWithArguments(evidenceAssignment)) {
            // TODO - add support for 'not <variable>' and 'variable = value' and 'value = variable'
            throw new UnsupportedOperationException("Function application of evidence currently not supported: " + evidenceAssignment);
        } else if (Expressions.isSymbol(evidenceAssignment)) {
            int evidenceVariableIndex = randomVariableIndexes.get(evidenceAssignment);
            int evidenceValueIndex = typeToValues.get(randomVariableNameToTypeSizeAndUniqueConstants.get(evidenceAssignment).first).indexOf(Expressions.TRUE);
            listener.evidence(evidenceVariableIndex, evidenceValueIndex);
        }
    }
    listener.groundingComplete();
}
Also used : Context(com.sri.ai.grinder.sgdpllt.api.Context) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Triple(com.sri.ai.util.base.Triple) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) InferenceForFactorGraphAndEvidence(com.sri.ai.praise.sgsolver.solver.InferenceForFactorGraphAndEvidence) Expression(com.sri.ai.expresso.api.Expression) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with Triple

use of com.sri.ai.util.base.Triple 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.getOrderedSummands().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.getSignatureTermMap().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)

Aggregations

Expression (com.sri.ai.expresso.api.Expression)4 Triple (com.sri.ai.util.base.Triple)4 ArrayList (java.util.ArrayList)4 LinkedHashMap (java.util.LinkedHashMap)3 Beta (com.google.common.annotations.Beta)2 Symbol (com.sri.ai.expresso.api.Symbol)2 Expressions (com.sri.ai.expresso.helper.Expressions)2 Context (com.sri.ai.grinder.sgdpllt.api.Context)2 InferenceForFactorGraphAndEvidence (com.sri.ai.praise.sgsolver.solver.InferenceForFactorGraphAndEvidence)2 Rational (com.sri.ai.util.math.Rational)2 BigInteger (java.math.BigInteger)2 Map (java.util.Map)2 Function (com.google.common.base.Function)1 Predicate (com.google.common.base.Predicate)1 IndexExpressionsSet (com.sri.ai.expresso.api.IndexExpressionsSet)1 Type (com.sri.ai.expresso.api.Type)1 DefaultFunctionApplication (com.sri.ai.expresso.core.DefaultFunctionApplication)1 DefaultTuple (com.sri.ai.expresso.core.DefaultTuple)1 ExtensionalIndexExpressionsSet (com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet)1 Expressions.apply (com.sri.ai.expresso.helper.Expressions.apply)1