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());
}
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);
}
Aggregations