Search in sources :

Example 1 with NumberOfDistinctExpressionsIsLessThanStepSolver

use of com.sri.ai.grinder.theory.equality.NumberOfDistinctExpressionsIsLessThanStepSolver in project aic-expresso by aic-sri-international.

the class NumberOfDistinctExpressionsIsLessThanStepSolverTest method test.

@Test
public void test() {
    TheoryTestingSupport theoryTestingSupport = TheoryTestingSupport.make(makeRandom(), new EqualityTheory(true, true));
    Context context = theoryTestingSupport.makeContextWithTestingInformation();
    String contextString = "X != Y and X != a and X != b and Y != b";
    List<String> elementsStrings = list("X", "Y", "a", "b", "c");
    int limit = 5;
    context = context.conjoin(parse(contextString), context);
    ArrayList<Expression> list = mapIntoArrayList(elementsStrings, Expressions::parse);
    NumberOfDistinctExpressionsIsLessThanStepSolver stepSolver = new NumberOfDistinctExpressionsIsLessThanStepSolver(limit, list);
    Step step = stepSolver.step(context);
    assertEquals(true, step.itDepends());
    assertEquals(parse("X = c"), step.getSplitter());
    ExpressionLiteralSplitterStepSolver stepSolverIfXEqualsC = step.getStepSolverForWhenSplitterIs(true);
    ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromC = step.getStepSolverForWhenSplitterIs(false);
    // if X = c, the number of distinct values is at most 4, so it will never reach the limit
    step = stepSolverIfXEqualsC.step(context);
    assertEquals(false, step.itDepends());
    assertEquals(TRUE, step.getValue());
    // using again just to make sure it produces the same result
    step = stepSolverIfXEqualsC.step(context);
    assertEquals(false, step.itDepends());
    assertEquals(TRUE, step.getValue());
    // if X != c, the number of distinct values will now depend on Y = a
    step = stepSolverIfXIsDifferentFromC.step(context);
    assertEquals(true, step.itDepends());
    assertEquals(parse("Y = a"), step.getSplitter());
    // using again just to make sure it produces the same result
    step = stepSolverIfXIsDifferentFromC.step(context);
    assertEquals(true, step.itDepends());
    assertEquals(parse("Y = a"), step.getSplitter());
    ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYEqualsA = step.getStepSolverForWhenSplitterIs(true);
    ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYIsDifferentFromA = step.getStepSolverForWhenSplitterIs(false);
    // ok, moving on, assuming Y = a, limit will not be reached
    step = stepSolverIfXIsDifferentFromCAndYEqualsA.step(context);
    assertEquals(false, step.itDepends());
    assertEquals(TRUE, step.getValue());
    // if however Y != a, limit will depend on Y = c
    step = stepSolverIfXIsDifferentFromCAndYIsDifferentFromA.step(context);
    assertEquals(true, step.itDepends());
    assertEquals(parse("Y = c"), step.getSplitter());
    ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsEqualToC = step.getStepSolverForWhenSplitterIs(true);
    ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsDifferentFromC = step.getStepSolverForWhenSplitterIs(false);
    // if Y = c, then limit is not going to be reached
    step = stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsEqualToC.step(context);
    assertEquals(false, step.itDepends());
    assertEquals(TRUE, step.getValue());
    // if Y != c, then limit is reached
    step = stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsDifferentFromC.step(context);
    assertEquals(false, step.itDepends());
    assertEquals(FALSE, step.getValue());
}
Also used : Context(com.sri.ai.grinder.api.Context) EqualityTheory(com.sri.ai.grinder.theory.equality.EqualityTheory) Expression(com.sri.ai.expresso.api.Expression) TheoryTestingSupport(com.sri.ai.grinder.tester.TheoryTestingSupport) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver) Expressions(com.sri.ai.expresso.helper.Expressions) Step(com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver.Step) NumberOfDistinctExpressionsIsLessThanStepSolver(com.sri.ai.grinder.theory.equality.NumberOfDistinctExpressionsIsLessThanStepSolver) Test(org.junit.Test)

Example 2 with NumberOfDistinctExpressionsIsLessThanStepSolver

use of com.sri.ai.grinder.theory.equality.NumberOfDistinctExpressionsIsLessThanStepSolver in project aic-expresso by aic-sri-international.

the class AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver method getSolutionStepAfterBoundsAreCheckedForFeasibility.

@Override
protected Step getSolutionStepAfterBoundsAreCheckedForFeasibility(Expression maximumLowerBound, Expression minimumUpperBound, AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver sequelBaseAsNumericStepSolver, Context context) {
    AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver sequelBase = (AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver) sequelBaseAsNumericStepSolver;
    StepSolver<List<Expression>> disequalsGreaterThanMaximumLowerBoundStepSolver;
    if (initialDisequalsGreaterThanMaximumLowerBoundStepSolver == null) {
        disequalsGreaterThanMaximumLowerBoundStepSolver = new SelectExpressionsSatisfyingComparisonStepSolver(getDisequals(), GREATER_THAN, // relies on this class's enforcing of all lower bounds being strict
        maximumLowerBound);
    } else {
        disequalsGreaterThanMaximumLowerBoundStepSolver = initialDisequalsGreaterThanMaximumLowerBoundStepSolver;
    }
    StepSolver.Step<List<Expression>> disequalsGreaterThanGreatestStrictLowerBoundStep = disequalsGreaterThanMaximumLowerBoundStepSolver.step(context);
    if (disequalsGreaterThanGreatestStrictLowerBoundStep.itDepends()) {
        AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
        ifTrue.initialDisequalsGreaterThanMaximumLowerBoundStepSolver = disequalsGreaterThanGreatestStrictLowerBoundStep.getStepSolverForWhenSplitterIs(true);
        AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
        ifFalse.initialDisequalsGreaterThanMaximumLowerBoundStepSolver = disequalsGreaterThanGreatestStrictLowerBoundStep.getStepSolverForWhenSplitterIs(false);
        ItDependsOn result = new ItDependsOn(disequalsGreaterThanGreatestStrictLowerBoundStep.getSplitter(), disequalsGreaterThanGreatestStrictLowerBoundStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
        return result;
    }
    List<Expression> disequalsGreaterThanGreatestStrictLowerBound = disequalsGreaterThanGreatestStrictLowerBoundStep.getValue();
    sequelBase.initialDisequalsGreaterThanMaximumLowerBoundStepSolver = new ConstantStepSolver<List<Expression>>(disequalsGreaterThanGreatestStrictLowerBound);
    StepSolver<List<Expression>> disequalsWithinBoundsStepSolver;
    if (initialDisequalsWithinBoundsStepSolver == null) {
        disequalsWithinBoundsStepSolver = new SelectExpressionsSatisfyingComparisonStepSolver(disequalsGreaterThanGreatestStrictLowerBound, LESS_THAN_OR_EQUAL_TO, // relies on this class's enforcing of all upper bounds being non-strict
        minimumUpperBound);
    } else {
        disequalsWithinBoundsStepSolver = initialDisequalsWithinBoundsStepSolver;
    }
    StepSolver.Step<List<Expression>> disequalsWithinBoundsStep = disequalsWithinBoundsStepSolver.step(context);
    if (disequalsWithinBoundsStep.itDepends()) {
        AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
        ifTrue.initialDisequalsWithinBoundsStepSolver = disequalsWithinBoundsStep.getStepSolverForWhenSplitterIs(true);
        AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
        ifFalse.initialDisequalsWithinBoundsStepSolver = disequalsWithinBoundsStep.getStepSolverForWhenSplitterIs(false);
        ItDependsOn result = new ItDependsOn(disequalsWithinBoundsStep.getSplitter(), disequalsWithinBoundsStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
        return result;
    }
    ArrayList<Expression> disequalsWithinBounds = new ArrayList<>(disequalsWithinBoundsStep.getValue());
    sequelBase.initialDisequalsWithinBoundsStepSolver = new ConstantStepSolver<List<Expression>>(disequalsWithinBounds);
    Expression boundsDifference = applyAndSimplify(MINUS, arrayList(minimumUpperBound, maximumLowerBound), context);
    // the goal of the upcoming 'if' is to define the values for these two next declared variables:
    boolean weKnowThatNumberOfDistinctDisequalsExceedsNumberOfValuesWithinBounds;
    // if true, number of distinct disequals exceeds number of values within bounds;
    // if false, that may be true or false, we don't know.
    DistinctExpressionsStepSolver distinctExpressionsStepSolver;
    if (isNumber(boundsDifference)) {
        ExpressionLiteralSplitterStepSolver numberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver;
        if (initialNumberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver == null) {
            numberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver = new NumberOfDistinctExpressionsIsLessThanStepSolver(boundsDifference.intValue(), disequalsWithinBounds);
        } else {
            numberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver = initialNumberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver;
        }
        ExpressionLiteralSplitterStepSolver.Step numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep = numberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver.step(context);
        if (numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.itDepends()) {
            AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
            ifTrue.initialNumberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver = numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.getStepSolverForWhenSplitterIs(true);
            AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
            ifFalse.initialNumberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver = numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.getStepSolverForWhenSplitterIs(false);
            ItDependsOn result = new ItDependsOn(numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.getSplitterLiteral(), numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
            return result;
        }
        Expression numberOfDistinctDisequalsIsLessThanBoundsDifference = numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.getValue();
        sequelBase.initialNumberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver = new ConstantExpressionStepSolver(numberOfDistinctDisequalsIsLessThanBoundsDifference);
        weKnowThatNumberOfDistinctDisequalsExceedsNumberOfValuesWithinBounds = numberOfDistinctDisequalsIsLessThanBoundsDifference.equals(FALSE);
        if (initialDistinctDisequalsStepSolver == null) {
            // if initialDistinctDisequalsStepSolver has not been set yet, it is because the predecessor of this step solver did not get to the point of using distinctExpressionsStepSolver; this means numberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver is not a ConstantExpressionStepSolver (if it were, then the predecessor would have proceeded to use distinctExpressionsStepSolver), so it must be a NumberOfDistinctExpressionsIsLessThanStepSolver.
            distinctExpressionsStepSolver = ((NumberOfDistinctExpressionsIsLessThanStepSolver) numberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver).getDistinctExpressionsStepSolver();
        } else {
            distinctExpressionsStepSolver = initialDistinctDisequalsStepSolver;
        }
    } else {
        weKnowThatNumberOfDistinctDisequalsExceedsNumberOfValuesWithinBounds = false;
        if (initialDistinctDisequalsStepSolver == null) {
            distinctExpressionsStepSolver = new DistinctExpressionsStepSolver(disequalsWithinBounds);
        } else {
            distinctExpressionsStepSolver = initialDistinctDisequalsStepSolver;
        }
    }
    Expression solutionExpression;
    if (weKnowThatNumberOfDistinctDisequalsExceedsNumberOfValuesWithinBounds) {
        // there are no available values left
        solutionExpression = getSolutionExpressionGivenContradiction();
    } else if (!getEquals().isEmpty()) {
        // if bound to a value
        solutionExpression = getSolutionExpressionForBoundVariable();
    } else {
        Step distinctDisequalsStep = distinctExpressionsStepSolver.step(context);
        if (distinctDisequalsStep.itDepends()) {
            AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifTrue = makeSequelStepSolver(sequelBase);
            ifTrue.initialDistinctDisequalsStepSolver = (DistinctExpressionsStepSolver) distinctDisequalsStep.getStepSolverForWhenSplitterIs(true);
            AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
            ifFalse.initialDistinctDisequalsStepSolver = (DistinctExpressionsStepSolver) distinctDisequalsStep.getStepSolverForWhenSplitterIs(false);
            ItDependsOn result = new ItDependsOn(distinctDisequalsStep.getSplitterLiteral(), distinctDisequalsStep.getContextSplittingWhenSplitterIsLiteral(), ifTrue, ifFalse);
            return result;
        }
        Expression distinctDisequalsExtensionalUniSet = distinctDisequalsStep.getValue();
        solutionExpression = getSolutionExpressionGivenBoundsAndDistinctDisequals(maximumLowerBound, minimumUpperBound, boundsDifference, distinctDisequalsExtensionalUniSet, context);
    }
    return new Solution(solutionExpression);
}
Also used : DistinctExpressionsStepSolver(com.sri.ai.grinder.theory.equality.DistinctExpressionsStepSolver) ArrayList(java.util.ArrayList) SelectExpressionsSatisfyingComparisonStepSolver(com.sri.ai.grinder.helper.SelectExpressionsSatisfyingComparisonStepSolver) SelectExpressionsSatisfyingComparisonStepSolver(com.sri.ai.grinder.helper.SelectExpressionsSatisfyingComparisonStepSolver) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver) ConstantExpressionStepSolver(com.sri.ai.grinder.theory.base.ConstantExpressionStepSolver) AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver(com.sri.ai.grinder.theory.numeric.AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver) ConstantStepSolver(com.sri.ai.grinder.theory.base.ConstantStepSolver) NumberOfDistinctExpressionsIsLessThanStepSolver(com.sri.ai.grinder.theory.equality.NumberOfDistinctExpressionsIsLessThanStepSolver) StepSolver(com.sri.ai.grinder.api.StepSolver) DistinctExpressionsStepSolver(com.sri.ai.grinder.theory.equality.DistinctExpressionsStepSolver) NumberOfDistinctExpressionsIsLessThanStepSolver(com.sri.ai.grinder.theory.equality.NumberOfDistinctExpressionsIsLessThanStepSolver) Expression(com.sri.ai.expresso.api.Expression) ExpressionLiteralSplitterStepSolver(com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver) ArrayList(java.util.ArrayList) Util.arrayList(com.sri.ai.util.Util.arrayList) List(java.util.List) ConstantExpressionStepSolver(com.sri.ai.grinder.theory.base.ConstantExpressionStepSolver)

Aggregations

Expression (com.sri.ai.expresso.api.Expression)2 ExpressionLiteralSplitterStepSolver (com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver)2 NumberOfDistinctExpressionsIsLessThanStepSolver (com.sri.ai.grinder.theory.equality.NumberOfDistinctExpressionsIsLessThanStepSolver)2 Expressions (com.sri.ai.expresso.helper.Expressions)1 Context (com.sri.ai.grinder.api.Context)1 Step (com.sri.ai.grinder.api.ExpressionLiteralSplitterStepSolver.Step)1 StepSolver (com.sri.ai.grinder.api.StepSolver)1 SelectExpressionsSatisfyingComparisonStepSolver (com.sri.ai.grinder.helper.SelectExpressionsSatisfyingComparisonStepSolver)1 TheoryTestingSupport (com.sri.ai.grinder.tester.TheoryTestingSupport)1 ConstantExpressionStepSolver (com.sri.ai.grinder.theory.base.ConstantExpressionStepSolver)1 ConstantStepSolver (com.sri.ai.grinder.theory.base.ConstantStepSolver)1 DistinctExpressionsStepSolver (com.sri.ai.grinder.theory.equality.DistinctExpressionsStepSolver)1 EqualityTheory (com.sri.ai.grinder.theory.equality.EqualityTheory)1 AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver (com.sri.ai.grinder.theory.numeric.AbstractSingleVariableNumericConstraintFeasibilityRegionStepSolver)1 Util.arrayList (com.sri.ai.util.Util.arrayList)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Test (org.junit.Test)1