Search in sources :

Example 6 with ExpressionLiteralSplitterStepSolver

use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.

the class AbstractTheory method makeEvaluatorStepSolver.

@Override
public ExpressionLiteralSplitterStepSolver makeEvaluatorStepSolver(Expression expression) {
    Rewriter literalExternalizer = new LiteralRewriter(new Recursive(new Exhaustive(getTopRewriter())));
    Recursive completeEvaluator = new Recursive(new Exhaustive(new FirstOf(getTopRewriter(), literalExternalizer)));
    // it is a good idea to leave the literal externalizer at the end,
    // since it is expensive due to duplicating the entire problem at every split
    ExpressionLiteralSplitterStepSolver result = completeEvaluator.makeStepSolver(expression);
    return result;
}
Also used : Exhaustive(com.sri.ai.grinder.sgdpllt.rewriter.core.Exhaustive) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver) MaxRewriter(com.sri.ai.grinder.sgdpllt.library.number.MaxRewriter) Rewriter(com.sri.ai.grinder.sgdpllt.rewriter.api.Rewriter) ThereExistsRewriter(com.sri.ai.grinder.sgdpllt.library.boole.ThereExistsRewriter) ForAllRewriter(com.sri.ai.grinder.sgdpllt.library.boole.ForAllRewriter) LiteralRewriter(com.sri.ai.grinder.sgdpllt.library.boole.LiteralRewriter) TopRewriter(com.sri.ai.grinder.sgdpllt.rewriter.api.TopRewriter) SummationRewriter(com.sri.ai.grinder.sgdpllt.library.number.SummationRewriter) CardinalityTopRewriter(com.sri.ai.grinder.sgdpllt.library.set.CardinalityTopRewriter) ProductRewriter(com.sri.ai.grinder.sgdpllt.library.number.ProductRewriter) FirstOf(com.sri.ai.grinder.sgdpllt.rewriter.core.FirstOf) LiteralRewriter(com.sri.ai.grinder.sgdpllt.library.boole.LiteralRewriter) Recursive(com.sri.ai.grinder.sgdpllt.rewriter.core.Recursive)

Example 7 with ExpressionLiteralSplitterStepSolver

use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.

the class AbstractQuantifierEliminationStepSolver method step.

@Override
public Step step(Context context) {
    Step result;
    Context contextForBody = getContextForBody(context);
    if (contextForBody.isContradiction()) {
        result = new Solution(group.additiveIdentityElement());
    } else {
        ExpressionLiteralSplitterStepSolver bodyStepSolver = getInitialBodyStepSolver(context.getTheory());
        ExpressionLiteralSplitterStepSolver.Step bodyStep = bodyStepSolver.step(contextForBody);
        // Check (**) in this file to see where this happens
        if (!bodyStep.itDepends()) {
            ExpressionLiteralSplitterStepSolver evaluatorStepSolver = getTheory().makeEvaluatorStepSolver(bodyStep.getValue());
            bodyStep = evaluatorStepSolver.step(context);
        }
        if (bodyStep.itDepends()) {
            // "intercept" literals containing the index and split the quantifier based on it
            if (isSubExpressionOf(getIndex(), bodyStep.getSplitterLiteral())) {
                Expression literalOnIndex = bodyStep.getSplitterLiteral();
                result = resultIfLiteralContainsIndex(literalOnIndex, bodyStep, contextForBody, context);
            } else {
                // not on index, just pass the expression on which we depend on, but with appropriate sub-step solvers (this, for now)
                AbstractQuantifierEliminationStepSolver ifTrue = clone();
                AbstractQuantifierEliminationStepSolver ifFalse = clone();
                ifTrue.initialBodyEvaluationStepSolver = bodyStep.getStepSolverForWhenSplitterIsTrue();
                ifFalse.initialBodyEvaluationStepSolver = bodyStep.getStepSolverForWhenSplitterIsFalse();
                ifTrue.initialContextForBody = bodyStep.getContextSplittingWhenSplitterIsLiteral().getContextAndLiteral();
                ifFalse.initialContextForBody = bodyStep.getContextSplittingWhenSplitterIsLiteral().getContextAndLiteralNegation();
                // to compute the result's constraint splitting,
                // we cannot directly re-use bodyStep.getConstraintSplitting() because it was not obtained from
                // the context it is returning to,
                // but from the context conjoined with the index constraint.
                // In order to provide two contexts to work with the sequel step solvers,
                // we calculate the splittings here.
                // TODO: In the future, we expect it possible to efficiently extract the contextForBody component relative
                // to the original context only, excluding the index.
                ContextSplitting split = new ContextSplitting(bodyStep.getSplitterLiteral(), context);
                result = new ItDependsOn(bodyStep.getSplitterLiteral(), split, ifTrue, ifFalse);
            }
        } else {
            // body is already literal free
            result = eliminateQuantifierForLiteralFreeBodyAndSingleVariableConstraint(indexConstraint, bodyStep.getValue(), context);
        }
    }
    return result;
}
Also used : Context(com.sri.ai.grinder.sgdpllt.api.Context) Expression(com.sri.ai.expresso.api.Expression) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver) ContextSplitting(com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting)

Example 8 with ExpressionLiteralSplitterStepSolver

use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.

the class ContextDependentExpressionProblemSolver method solve.

/**
	 * Returns the solution for a problem using a step solver.
	 * @param stepSolver
	 * @param context
	 * @return
	 */
public Expression solve(ExpressionLiteralSplitterStepSolver stepSolver, Context context) {
    if (interrupted) {
        throw new Error("Solver interrupted.");
    }
    Expression result;
    ExpressionLiteralSplitterStepSolver.Step step = stepSolver.step(context);
    if (step.itDepends()) {
        Expression splitter = step.getSplitter();
        ContextSplitting split = (ContextSplitting) step.getContextSplittingWhenSplitterIsLiteral();
        myAssert(() -> split.isUndefined(), () -> "Undefined " + ContextSplitting.class + " result value: " + split.getResult());
        Expression subSolution1 = solve(step.getStepSolverForWhenSplitterIsTrue(), split.getConstraintAndLiteral());
        Expression subSolution2 = solve(step.getStepSolverForWhenSplitterIsFalse(), split.getConstraintAndLiteralNegation());
        result = IfThenElse.make(splitter, subSolution1, subSolution2, true);
    } else {
        result = step.getValue();
    }
    return result;
}
Also used : Expression(com.sri.ai.expresso.api.Expression) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver) ContextSplitting(com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting)

Example 9 with ExpressionLiteralSplitterStepSolver

use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.

the class AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver method solutionIfPropagatedLiteralsAndSplittersCNFAreSatisfied.

@Override
protected Step solutionIfPropagatedLiteralsAndSplittersCNFAreSatisfied(Context context) {
    Expression solutionExpression;
    // sequelBase keeps track of updates to non-splitting sub-step solvers so far.
    // When a splitting sub-step solver is found, it is used as a basis
    // for the sequel step solvers.
    // The reason we keep this clone, that is itself cloned later,
    // as opposed to updating and cloning "this" every time,
    // is that step solvers must not be modified by their method "step",
    // unless they are caching context-independent information.
    // sequelBase serves as a blackboard for all the updates learned while executing this method,
    // which then don't need to be kept by "this".
    // These updates are then cloned into the sequel step solvers.
    AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver sequelBase = clone();
    if (getConstraint().getPropagateAllLiteralsWhenVariableIsBound() && !getEquals().isEmpty()) {
        solutionExpression = getSolutionExpressionForBoundVariable();
    } else {
        ExpressionLiteralSplitterStepSolver maximumLowerBoundStepSolver;
        if (initialMaximumLowerBoundStepSolver == null) {
            maximumLowerBoundStepSolver = new MaximumExpressionStepSolver(getLowerBoundsIncludingImplicitOnes(context), // use total order <
            LESS_THAN_SYMBOL, MINUS_INFINITY, // at first, I placed the type minimum and maximum strict lower bounds here. This is incorrect because if the type maximum is, say, 4, and I have "X > 3 and X > I" (3 is the maximum strict lower bounds for values in the type), the step solver short-circuits and returns 3, without ever even looking at I. Looking at I is needed because if I is greater than 3 than this constraint is unsatisfiable.
            INFINITY);
        } else {
            maximumLowerBoundStepSolver = initialMaximumLowerBoundStepSolver;
        }
        ExpressionLiteralSplitterStepSolver.Step maximumLowerBoundStep = maximumLowerBoundStepSolver.step(context);
        if (maximumLowerBoundStep.itDepends()) {
            AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
            ifTrue.initialMaximumLowerBoundStepSolver = maximumLowerBoundStep.getStepSolverForWhenSplitterIsTrue();
            AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
            ifFalse.initialMaximumLowerBoundStepSolver = maximumLowerBoundStep.getStepSolverForWhenSplitterIsFalse();
            ItDependsOn result = new ItDependsOn(maximumLowerBoundStep.getSplitterLiteral(), maximumLowerBoundStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
            return result;
        }
        Expression maximumLowerBound = maximumLowerBoundStep.getValue();
        sequelBase.initialMaximumLowerBoundStepSolver = new ConstantExpressionStepSolver(maximumLowerBound);
        ExpressionLiteralSplitterStepSolver minimumUpperBoundStepSolver;
        if (initialMinimumUpperBoundStepSolver == null) {
            minimumUpperBoundStepSolver = new MaximumExpressionStepSolver(getUpperBoundsIncludingImplicitOnes(context), // use total order > since "minimum" is maximum under it
            GREATER_THAN_SYMBOL, // "minimum" is maximum value because we are operating on the inverse order
            INFINITY, // "maximum" is minimum value because we are operating on the inverse order
            MINUS_INFINITY);
        } else {
            minimumUpperBoundStepSolver = initialMinimumUpperBoundStepSolver;
        }
        ExpressionLiteralSplitterStepSolver.Step minimumUpperBoundStep = minimumUpperBoundStepSolver.step(context);
        if (minimumUpperBoundStep.itDepends()) {
            AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
            ifTrue.initialMinimumUpperBoundStepSolver = minimumUpperBoundStep.getStepSolverForWhenSplitterIsTrue();
            AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
            ifFalse.initialMinimumUpperBoundStepSolver = minimumUpperBoundStep.getStepSolverForWhenSplitterIsFalse();
            ItDependsOn result = new ItDependsOn(minimumUpperBoundStep.getSplitterLiteral(), minimumUpperBoundStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
            return result;
        }
        Expression minimumUpperBound = minimumUpperBoundStep.getValue();
        sequelBase.initialMinimumUpperBoundStepSolver = new ConstantExpressionStepSolver(minimumUpperBound);
        if (unboundedVariableProducesShortCircuitSolution() && (maximumLowerBound.equals(MINUS_INFINITY) || minimumUpperBound.equals(INFINITY))) {
            solutionExpression = getSolutionExpressionForUnboundedVariables();
        } else {
            StepSolver<Boolean> boundedSpaceIsNotEmptyStepSolver;
            if (initialBoundedSpaceIsNotEmptyStepSolver == null) {
                Expression boundedSpaceIsNotEmpty = makeLiteralCheckingWhetherThereAreAnyValuesWithinBounds(maximumLowerBound, minimumUpperBound, context);
                boundedSpaceIsNotEmptyStepSolver = new LiteralStepSolver(boundedSpaceIsNotEmpty);
            } else {
                boundedSpaceIsNotEmptyStepSolver = initialBoundedSpaceIsNotEmptyStepSolver;
            }
            StepSolver.Step<Boolean> lowerBoundIsLessThanUpperBoundStep = boundedSpaceIsNotEmptyStepSolver.step(context);
            if (lowerBoundIsLessThanUpperBoundStep.itDepends()) {
                AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
                ifTrue.initialBoundedSpaceIsNotEmptyStepSolver = lowerBoundIsLessThanUpperBoundStep.getStepSolverForWhenSplitterIsTrue();
                AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
                ifFalse.initialBoundedSpaceIsNotEmptyStepSolver = lowerBoundIsLessThanUpperBoundStep.getStepSolverForWhenSplitterIsFalse();
                ItDependsOn result = new ItDependsOn(lowerBoundIsLessThanUpperBoundStep.getSplitter(), lowerBoundIsLessThanUpperBoundStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
                return result;
            }
            if (!lowerBoundIsLessThanUpperBoundStep.getValue()) {
                return new Solution(getSolutionExpressionGivenContradiction());
            }
            // else, bounds difference is positive and we can move on
            sequelBase.initialBoundedSpaceIsNotEmptyStepSolver = new ConstantStepSolver<Boolean>(true);
            Step result = getSolutionStepAfterBoundsAreCheckedForFeasibility(maximumLowerBound, minimumUpperBound, sequelBase, context);
            return result;
        }
    }
    return new Solution(solutionExpression);
}
Also used : LiteralStepSolver(com.sri.ai.grinder.sgdpllt.theory.base.LiteralStepSolver) ConstantStepSolver(com.sri.ai.grinder.sgdpllt.theory.base.ConstantStepSolver) AbstractExpressionWithPropagatedLiteralsStepSolver(com.sri.ai.grinder.sgdpllt.core.solver.AbstractExpressionWithPropagatedLiteralsStepSolver) LiteralStepSolver(com.sri.ai.grinder.sgdpllt.theory.base.LiteralStepSolver) StepSolver(com.sri.ai.grinder.sgdpllt.api.StepSolver) ConstantExpressionStepSolver(com.sri.ai.grinder.sgdpllt.theory.base.ConstantExpressionStepSolver) AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver(com.sri.ai.grinder.sgdpllt.theory.differencearithmetic.AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver) MaximumExpressionStepSolver(com.sri.ai.grinder.sgdpllt.helper.MaximumExpressionStepSolver) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver) Expression(com.sri.ai.expresso.api.Expression) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver) MaximumExpressionStepSolver(com.sri.ai.grinder.sgdpllt.helper.MaximumExpressionStepSolver) ConstantExpressionStepSolver(com.sri.ai.grinder.sgdpllt.theory.base.ConstantExpressionStepSolver)

Example 10 with ExpressionLiteralSplitterStepSolver

use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.

the class PropositionalTheory method getSingleVariableConstraintQuantifierEliminatorStepSolver.

@Override
public ExpressionLiteralSplitterStepSolver getSingleVariableConstraintQuantifierEliminatorStepSolver(AssociativeCommutativeGroup group, SingleVariableConstraint constraintForThisIndex, Expression body, Context context) {
    ExpressionStepSolver formulaSplitterStepSolver = new QuantifierEliminationOnBodyInWhichIndexOnlyOccursInsideLiteralsStepSolver(group, constraintForThisIndex, body);
    ExpressionLiteralSplitterStepSolver result = new ExpressionStepSolverToLiteralSplitterStepSolverAdapter(formulaSplitterStepSolver);
    return result;
}
Also used : ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver) ExpressionStepSolver(com.sri.ai.grinder.sgdpllt.api.ExpressionStepSolver) QuantifierEliminationOnBodyInWhichIndexOnlyOccursInsideLiteralsStepSolver(com.sri.ai.grinder.sgdpllt.core.solver.QuantifierEliminationOnBodyInWhichIndexOnlyOccursInsideLiteralsStepSolver) ExpressionStepSolverToLiteralSplitterStepSolverAdapter(com.sri.ai.grinder.sgdpllt.core.solver.ExpressionStepSolverToLiteralSplitterStepSolverAdapter)

Aggregations

ExpressionLiteralSplitterStepSolver (com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver)26 Expression (com.sri.ai.expresso.api.Expression)14 Context (com.sri.ai.grinder.sgdpllt.api.Context)5 ContextSplitting (com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting)5 Rewriter (com.sri.ai.grinder.sgdpllt.rewriter.api.Rewriter)5 ExpressionStepSolver (com.sri.ai.grinder.sgdpllt.api.ExpressionStepSolver)4 Theory (com.sri.ai.grinder.sgdpllt.api.Theory)4 ExpressionStepSolverToLiteralSplitterStepSolverAdapter (com.sri.ai.grinder.sgdpllt.core.solver.ExpressionStepSolverToLiteralSplitterStepSolverAdapter)4 QuantifierEliminationOnBodyInWhichIndexOnlyOccursInsideLiteralsStepSolver (com.sri.ai.grinder.sgdpllt.core.solver.QuantifierEliminationOnBodyInWhichIndexOnlyOccursInsideLiteralsStepSolver)4 Test (org.junit.Test)4 Step (com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver.Step)3 StepSolver (com.sri.ai.grinder.sgdpllt.api.StepSolver)3 AbstractTheory (com.sri.ai.grinder.sgdpllt.core.constraint.AbstractTheory)3 TopRewriter (com.sri.ai.grinder.sgdpllt.rewriter.api.TopRewriter)3 ConstantExpressionStepSolver (com.sri.ai.grinder.sgdpllt.theory.base.ConstantExpressionStepSolver)3 Expressions (com.sri.ai.expresso.helper.Expressions)2 Solution (com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver.Solution)2 TrueContext (com.sri.ai.grinder.sgdpllt.core.TrueContext)2 Sum (com.sri.ai.grinder.sgdpllt.group.Sum)2 LiteralRewriter (com.sri.ai.grinder.sgdpllt.library.boole.LiteralRewriter)2