Search in sources :

Example 1 with ONE

use of java.math.BigInteger.ONE in project aic-praise by aic-sri-international.

the class TranslationOfTableToInequalities method constructGenericTableExpressionUsingInequalities.

/**
	 * Returns an {@link Expression} equivalent to a given {@link FunctionTable} but in the form of a decision tree
	 * (so hopefully more compact) using inequalities.
	 * @param functionTable
	 * @param solverListener if not null, invoked on solver used for compilation,
	 * before and after compilation is performed; returned solver from "before" invocation is used (it may be the same one used as argument, of course).
	 * @return
	 */
public static Expression constructGenericTableExpressionUsingInequalities(FunctionTable functionTable, Function<MultiIndexQuantifierEliminator, MultiIndexQuantifierEliminator> solverListener) {
    // the strategy in this method is the following:
    // we collect all the contiguous indices sub-sets of the function table sharing their function value.
    // They are kept in a map from each value to a list of indices sub-sets with that value.
    //
    // Then, we sort these groups of indices sub-sets by the sum of their sizes (number of entries), from smallest to largest.
    // This will help us later to create an expression that tests for the largest groups first.
    //
    // Finally, we create an if-then-else expression, starting from the leaf (least common value).
    // For each group of indices sub-sets with the same value, we obtain an inequalities expression describing
    // the conditions for a variable assignment to be in that indices sub-set of the function table.
    // Each portion generates a conjunction, and the group of portions generates a disjunction.
    //
    // The resulting if-then-else expression is linearly organized (only else clauses have nested if-then-else expressions).
    // A more balanced (and thus efficient) representation is obtained by compiling it using SGDPLL(T).
    Map<Double, List<FunctionTableIndicesSubSet>> functionValuesAndCorrespondingIndicesSubSet = map();
    Double currentSubSetFunctionValueIfAny = null;
    List<Integer> firstIndicesOfCurrentSubSetIfAny = null;
    List<Integer> previousIndices = null;
    List<Integer> indices = null;
    CartesianProductEnumeration<Integer> cartesianProduct = new CartesianProductEnumeration<>(UAIUtil.cardinalityValues(functionTable));
    while (cartesianProduct.hasMoreElements()) {
        previousIndices = indices;
        indices = new ArrayList<>(cartesianProduct.nextElement());
        Double functionValue = Math.round(functionTable.entryFor(indices) * 100) / 100.0;
        boolean hitNewFunctionValue = currentSubSetFunctionValueIfAny == null || !functionValue.equals(currentSubSetFunctionValueIfAny);
        if (hitNewFunctionValue) {
            storeIndicesSubSetOnAllVariables(functionTable, firstIndicesOfCurrentSubSetIfAny, previousIndices, currentSubSetFunctionValueIfAny, functionValuesAndCorrespondingIndicesSubSet);
            // get information for next indices sub-set
            currentSubSetFunctionValueIfAny = functionValue;
            firstIndicesOfCurrentSubSetIfAny = indices;
        }
    }
    previousIndices = indices;
    storeIndicesSubSetOnAllVariables(functionTable, firstIndicesOfCurrentSubSetIfAny, previousIndices, currentSubSetFunctionValueIfAny, functionValuesAndCorrespondingIndicesSubSet);
    // we sort (by using TreeMap) lists of indices sub-set with the same function value from those with smaller to greater sizes,
    // and form the final expression backwards, thus prioritizing larger sub-sets
    // whose conditions will be more often satisfied and leading to greater simplifications during inference.
    List<Pair<BigInteger, List<FunctionTableIndicesSubSet>>> listOfPairsOfSizeAndListsOfIndicesSubSetsWithSameFunctionValue = new ArrayList<>(functionValuesAndCorrespondingIndicesSubSet.size());
    for (Map.Entry<Double, List<FunctionTableIndicesSubSet>> functionValueAndIndicesSubSet : functionValuesAndCorrespondingIndicesSubSet.entrySet()) {
        List<FunctionTableIndicesSubSet> indicesSubSetsWithSameFunctionValue = functionValueAndIndicesSubSet.getValue();
        BigInteger sumOfSizes = BigInteger.ZERO;
        for (FunctionTableIndicesSubSet indicesSubSet : indicesSubSetsWithSameFunctionValue) {
            sumOfSizes = sumOfSizes.add(indicesSubSet.size());
        }
        listOfPairsOfSizeAndListsOfIndicesSubSetsWithSameFunctionValue.add(Pair.make(sumOfSizes, indicesSubSetsWithSameFunctionValue));
    }
    Collections.sort(listOfPairsOfSizeAndListsOfIndicesSubSetsWithSameFunctionValue, (Comparator<? super Pair<BigInteger, List<FunctionTableIndicesSubSet>>>) (p1, p2) -> p1.first.compareTo(p2.first));
    List<List<FunctionTableIndicesSubSet>> listsOfIndicesSubSetsWithSameFunctionValue = mapIntoList(listOfPairsOfSizeAndListsOfIndicesSubSetsWithSameFunctionValue, p -> p.second);
    Iterator<List<FunctionTableIndicesSubSet>> listsOfIndicesSubSetsWithSameFunctionValueIterator = listsOfIndicesSubSetsWithSameFunctionValue.iterator();
    List<FunctionTableIndicesSubSet> firstListOfIndicesSubSets = listsOfIndicesSubSetsWithSameFunctionValueIterator.next();
    Double valueOfFirstListOfIndicesSubSets = getFirstOrNull(firstListOfIndicesSubSets).getFunctionValue();
    Expression currentExpression = makeSymbol(valueOfFirstListOfIndicesSubSets);
    while (listsOfIndicesSubSetsWithSameFunctionValueIterator.hasNext()) {
        List<FunctionTableIndicesSubSet> indicesSubSetsWithSameFunctionValue = listsOfIndicesSubSetsWithSameFunctionValueIterator.next();
        Expression functionValueOfIndicesSubSetsWithSameFunctionValue = makeSymbol(getFirstOrNull(indicesSubSetsWithSameFunctionValue).getFunctionValue());
        Expression conditionForThisFunctionValue = Or.make(mapIntoList(indicesSubSetsWithSameFunctionValue, TranslationOfTableToInequalities::getInequalitiesExpressionForFunctionTableIndicesSubSet));
        currentExpression = IfThenElse.make(conditionForThisFunctionValue, functionValueOfIndicesSubSetsWithSameFunctionValue, currentExpression);
    }
    return currentExpression;
}
Also used : LESS_THAN_OR_EQUAL_TO(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.LESS_THAN_OR_EQUAL_TO) ONE(java.math.BigInteger.ONE) FALSE(com.sri.ai.expresso.helper.Expressions.FALSE) MultiIndexQuantifierEliminator(com.sri.ai.grinder.sgdpllt.api.MultiIndexQuantifierEliminator) Expression(com.sri.ai.expresso.api.Expression) Function(java.util.function.Function) Util.forAll(com.sri.ai.util.Util.forAll) ArrayList(java.util.ArrayList) Util.map(com.sri.ai.util.Util.map) Expressions.apply(com.sri.ai.expresso.helper.Expressions.apply) Map(java.util.Map) And(com.sri.ai.grinder.sgdpllt.library.boole.And) IntegerIterator(com.sri.ai.util.collect.IntegerIterator) BigInteger(java.math.BigInteger) Pair(com.sri.ai.util.base.Pair) CartesianProductEnumeration(com.sri.ai.util.collect.CartesianProductEnumeration) Or(com.sri.ai.grinder.sgdpllt.library.boole.Or) Iterator(java.util.Iterator) MixedRadixNumber(com.sri.ai.util.math.MixedRadixNumber) EQUALITY(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.EQUALITY) Util.mapIntoList(com.sri.ai.util.Util.mapIntoList) GREATER_THAN_OR_EQUAL_TO(com.sri.ai.grinder.sgdpllt.library.FunctorConstants.GREATER_THAN_OR_EQUAL_TO) IfThenElse(com.sri.ai.grinder.sgdpllt.library.controlflow.IfThenElse) Beta(com.google.common.annotations.Beta) Util.getFirstOrNull(com.sri.ai.util.Util.getFirstOrNull) List(java.util.List) Expressions.makeSymbol(com.sri.ai.expresso.helper.Expressions.makeSymbol) UAIUtil(com.sri.ai.praise.model.v1.imports.uai.UAIUtil) Util.arrayListFilledWith(com.sri.ai.util.Util.arrayListFilledWith) FunctionTable(com.sri.ai.praise.lang.grounded.common.FunctionTable) Comparator(java.util.Comparator) Util.putInListValue(com.sri.ai.util.Util.putInListValue) Collections(java.util.Collections) TRUE(com.sri.ai.expresso.helper.Expressions.TRUE) ArrayList(java.util.ArrayList) CartesianProductEnumeration(com.sri.ai.util.collect.CartesianProductEnumeration) BigInteger(java.math.BigInteger) Expression(com.sri.ai.expresso.api.Expression) BigInteger(java.math.BigInteger) ArrayList(java.util.ArrayList) Util.mapIntoList(com.sri.ai.util.Util.mapIntoList) List(java.util.List) Map(java.util.Map) Pair(com.sri.ai.util.base.Pair)

Aggregations

Beta (com.google.common.annotations.Beta)1 Expression (com.sri.ai.expresso.api.Expression)1 FALSE (com.sri.ai.expresso.helper.Expressions.FALSE)1 TRUE (com.sri.ai.expresso.helper.Expressions.TRUE)1 Expressions.apply (com.sri.ai.expresso.helper.Expressions.apply)1 Expressions.makeSymbol (com.sri.ai.expresso.helper.Expressions.makeSymbol)1 MultiIndexQuantifierEliminator (com.sri.ai.grinder.sgdpllt.api.MultiIndexQuantifierEliminator)1 EQUALITY (com.sri.ai.grinder.sgdpllt.library.FunctorConstants.EQUALITY)1 GREATER_THAN_OR_EQUAL_TO (com.sri.ai.grinder.sgdpllt.library.FunctorConstants.GREATER_THAN_OR_EQUAL_TO)1 LESS_THAN_OR_EQUAL_TO (com.sri.ai.grinder.sgdpllt.library.FunctorConstants.LESS_THAN_OR_EQUAL_TO)1 And (com.sri.ai.grinder.sgdpllt.library.boole.And)1 Or (com.sri.ai.grinder.sgdpllt.library.boole.Or)1 IfThenElse (com.sri.ai.grinder.sgdpllt.library.controlflow.IfThenElse)1 FunctionTable (com.sri.ai.praise.lang.grounded.common.FunctionTable)1 UAIUtil (com.sri.ai.praise.model.v1.imports.uai.UAIUtil)1 Util.arrayListFilledWith (com.sri.ai.util.Util.arrayListFilledWith)1 Util.forAll (com.sri.ai.util.Util.forAll)1 Util.getFirstOrNull (com.sri.ai.util.Util.getFirstOrNull)1 Util.map (com.sri.ai.util.Util.map)1 Util.mapIntoList (com.sri.ai.util.Util.mapIntoList)1