Search in sources :

Example 16 with Pair

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

the class TupleValuedFreeVariablesSimplifier method constructComponentTuple.

private static Expression constructComponentTuple(List<Pair<Expression, Integer>> replacementComponents) {
    List<Expression> elements = replacementComponents.stream().map(pair -> pair.first).collect(Collectors.toList());
    Expression result = Expressions.makeTuple(elements);
    return result;
}
Also used : Type(com.sri.ai.expresso.api.Type) Simplifier(com.sri.ai.grinder.sgdpllt.rewriter.api.Simplifier) Expressions(com.sri.ai.expresso.helper.Expressions) Set(java.util.Set) Expression(com.sri.ai.expresso.api.Expression) Context(com.sri.ai.grinder.sgdpllt.api.Context) 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) LinkedHashSet(java.util.LinkedHashSet) FunctorConstants(com.sri.ai.grinder.sgdpllt.library.FunctorConstants) Pair(com.sri.ai.util.base.Pair) Expression(com.sri.ai.expresso.api.Expression)

Example 17 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) Simplifier(com.sri.ai.grinder.sgdpllt.rewriter.api.Simplifier) Expressions(com.sri.ai.expresso.helper.Expressions) Set(java.util.Set) Expression(com.sri.ai.expresso.api.Expression) Context(com.sri.ai.grinder.sgdpllt.api.Context) 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) LinkedHashSet(java.util.LinkedHashSet) FunctorConstants(com.sri.ai.grinder.sgdpllt.library.FunctorConstants) Pair(com.sri.ai.util.base.Pair) Context(com.sri.ai.grinder.sgdpllt.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 18 with Pair

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

the class SGSolverEvaluator method prCallSGSolverCLI.

//
// PRIVATE
private SGSolverCallResult prCallSGSolverCLI(String model, String evidenceQuery) throws Exception {
    String tempPagedModelContainer = PagedModelContainer.toInternalContainerRepresentation(ModelLanguage.HOGMv1, Arrays.asList(new Pair<String, List<String>>(model, Arrays.asList(evidenceQuery))));
    File tempInput = File.createTempFile("sgsolver", PagedModelContainer.DEFAULT_CONTAINER_FILE_EXTENSION, getConfiguration().getWorkingDirectory());
    Files.write(tempInput.toPath(), tempPagedModelContainer.getBytes());
    //
    File tempSTDERR = File.createTempFile("sgsolver", ".stderr", getConfiguration().getWorkingDirectory());
    File tempSTDOUT = File.createTempFile("sgsolver", ".stdout", getConfiguration().getWorkingDirectory());
    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.directory(getConfiguration().getWorkingDirectory());
    // TODO - add option to PRAiSE to indicate a timeout.
    processBuilder.command("java", "-classpath", System.getProperty("java.class.path"), "-Xms" + getConfiguration().getTotalMemoryLimitInMegabytesPerSolveAttempt() + "M", "-Xmx" + getConfiguration().getTotalMemoryLimitInMegabytesPerSolveAttempt() + "M", PRAiSE.class.getName(), tempInput.getAbsolutePath());
    processBuilder.redirectError(ProcessBuilder.Redirect.to(tempSTDERR));
    processBuilder.redirectOutput(ProcessBuilder.Redirect.to(tempSTDOUT));
    long sgSolverStart = System.currentTimeMillis();
    Process sgSolverProcess = processBuilder.start();
    if (!sgSolverProcess.waitFor(getConfiguration().getTotalCPURuntimeLimitSecondsPerSolveAttempt() + 5, TimeUnit.SECONDS)) {
        // waiting time elapsed
        sgSolverProcess.destroyForcibly();
    }
    long sgSolverEnd = System.currentTimeMillis();
    List<String> sgsolverOutputs = Files.readAllLines(tempSTDOUT.toPath(), StandardCharsets.UTF_8);
    tempInput.delete();
    //
    tempSTDOUT.delete();
    tempSTDERR.delete();
    SGSolverCallResult result = new SGSolverCallResult();
    result.sgSolverProcessTookMS = sgSolverEnd - sgSolverStart;
    result.resultExpression = sgsolverOutputs.stream().filter(line -> line.startsWith(PRAiSE.RESULT_PREFIX)).findFirst().orElse(null);
    if (result.resultExpression != null) {
        result.resultExpression = result.resultExpression.substring(PRAiSE.RESULT_PREFIX.length());
    } else {
        throw new Error("Error launching java process for SGSolver:\n" + sgsolverOutputs);
    }
    return result;
}
Also used : Arrays(java.util.Arrays) Files(java.nio.file.Files) SolverEvaluatorProbabilityEvidenceResult(com.sri.ai.praise.evaluate.solver.SolverEvaluatorProbabilityEvidenceResult) Expressions(com.sri.ai.expresso.helper.Expressions) Expression(com.sri.ai.expresso.api.Expression) IfThenElse(com.sri.ai.grinder.sgdpllt.library.controlflow.IfThenElse) File(java.io.File) StandardCharsets(java.nio.charset.StandardCharsets) PagedModelContainer(com.sri.ai.praise.model.common.io.PagedModelContainer) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Not(com.sri.ai.grinder.sgdpllt.library.boole.Not) AbstractSolverEvaluator(com.sri.ai.praise.evaluate.solver.impl.AbstractSolverEvaluator) ModelLanguage(com.sri.ai.praise.lang.ModelLanguage) PRAiSE(com.sri.ai.praise.sgsolver.cli.PRAiSE) Pair(com.sri.ai.util.base.Pair) PRAiSE(com.sri.ai.praise.sgsolver.cli.PRAiSE) File(java.io.File) Pair(com.sri.ai.util.base.Pair)

Example 19 with Pair

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

the class InversionSimplifier method getIndexAndFunctionType.

private static Pair<Expression, FunctionType> getIndexAndFunctionType(Expression functionOnIntensionalSet, Context context) {
    IndexExpressionsSet indexExpressionsSet = getIndexExpressions(functionOnIntensionalSet);
    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.getType(index, intensionalSetContext);
    FunctionType functionType = null;
    if (type instanceof FunctionType) {
        functionType = (FunctionType) type;
    }
    Pair<Expression, FunctionType> result = new Pair<>(index, functionType);
    return result;
}
Also used : Context(com.sri.ai.grinder.sgdpllt.api.Context) Type(com.sri.ai.expresso.api.Type) FunctionType(com.sri.ai.expresso.type.FunctionType) Expression(com.sri.ai.expresso.api.Expression) FunctionType(com.sri.ai.expresso.type.FunctionType) ExtensionalIndexExpressionsSet(com.sri.ai.expresso.core.ExtensionalIndexExpressionsSet) IndexExpressionsSet(com.sri.ai.expresso.api.IndexExpressionsSet) Pair(com.sri.ai.util.base.Pair)

Example 20 with Pair

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

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