use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.
the class TupleTheory method getSingleVariableConstraintQuantifierEliminatorStepSolver.
@Override
public ExpressionLiteralSplitterStepSolver getSingleVariableConstraintQuantifierEliminatorStepSolver(AssociativeCommutativeGroup group, SingleVariableConstraint constraint, Expression body, Context context) {
// The tuple-specific version will do the following:
// - create a E expression equivalent to the quantifier elimination of the constraint given here.
// - you can use AssociativeCommutativeGroup.makeProblemExpression(Expression index, Expression indexType, Expression constraint, Expression body)
// to create E
Expression variable = constraint.getVariable();
Expression typeExpression = GrinderUtil.getTypeExpression(variable, context);
Type type = context.getType(typeExpression);
if (!isSuitableFor(variable, type)) {
throw new Error("Theory " + this + " asked to eliminate quantifier indexed by " + variable + " in " + typeExpression + ", but this theory is not suitable for this type.");
}
Expression exprE = group.makeProblemExpression(variable, typeExpression, constraint, body);
// - use TupleQuantifierSimplifier to transform it to another expression E' without quantification on tuples
Expression exprEPrime = tupleQuantifierSimplifier.apply(exprE, context);
// - return context.getTheory().getRewriter().makeStepSolver(E')
ExpressionLiteralSplitterStepSolver result = context.getTheory().getRewriter().makeStepSolver(exprEPrime);
return result;
}
use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.
the class EqualityTheory method getSingleVariableConstraintQuantifierEliminatorStepSolver.
@Override
public ExpressionLiteralSplitterStepSolver getSingleVariableConstraintQuantifierEliminatorStepSolver(AssociativeCommutativeGroup group, SingleVariableConstraint constraint, Expression body, Context context) {
ExpressionStepSolver formulaSplitterStepSolver = new QuantifierEliminationOnBodyInWhichIndexOnlyOccursInsideLiteralsStepSolver(group, constraint, body);
ExpressionLiteralSplitterStepSolver result = new ExpressionStepSolverToLiteralSplitterStepSolverAdapter(formulaSplitterStepSolver);
return result;
}
use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.
the class DifferenceArithmeticTheory method makeEvaluatorStepSolver.
@Override
public ExpressionLiteralSplitterStepSolver makeEvaluatorStepSolver(Expression expression) {
Rewriter literalExternalizer = new LiteralRewriter(new Recursive(new Exhaustive(getTopRewriter())));
ExpressionLiteralSplitterStepSolver result = new Recursive(new Exhaustive(new FirstOf(getTopRewriter(), literalExternalizer))).makeStepSolver(expression);
return result;
}
use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver 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.getStepSolverForWhenSplitterIsTrue();
AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
ifFalse.initialDisequalsGreaterThanMaximumLowerBoundStepSolver = disequalsGreaterThanGreatestStrictLowerBoundStep.getStepSolverForWhenSplitterIsFalse();
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.getStepSolverForWhenSplitterIsTrue();
AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
ifFalse.initialDisequalsWithinBoundsStepSolver = disequalsWithinBoundsStep.getStepSolverForWhenSplitterIsFalse();
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.getStepSolverForWhenSplitterIsTrue();
AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
ifFalse.initialNumberOfDistinctDisequalsIsLessThanBoundsDifferenceStepSolver = numberOfDistinctDisequalsIsLessThanBoundsDifferenceStep.getStepSolverForWhenSplitterIsFalse();
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.getStepSolverForWhenSplitterIsTrue();
AbstractSingleVariableDifferenceArithmeticConstraintFeasibilityRegionStepSolver ifFalse = makeSequelStepSolver(sequelBase);
ifFalse.initialDistinctDisequalsStepSolver = (DistinctExpressionsStepSolver) distinctDisequalsStep.getStepSolverForWhenSplitterIsFalse();
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);
}
use of com.sri.ai.grinder.sgdpllt.api.ExpressionLiteralSplitterStepSolver in project aic-expresso by aic-sri-international.
the class UnificationStepSolver method step.
@Override
public StepSolver.Step<Boolean> step(Context context) {
StepSolver.Step<Boolean> result = null;
if (precomputedResult != null) {
result = precomputedResult;
} else {
List<Integer> stepUnknownSolutionIndexesForUnificationEqualities = new ArrayList<>(unknownSolutionIndexesForUnificationEqualities);
List<Integer> stepFoundSolutions = new ArrayList<>();
for (Integer unknownSolutionIndex : stepUnknownSolutionIndexesForUnificationEqualities) {
Expression equality = unificationEqualitiesToTest.get(unknownSolutionIndex);
ExpressionLiteralSplitterStepSolver evaluatorStepSolver = context.getTheory().makeEvaluatorStepSolver(equality);
Expression equalityResult = evaluatorStepSolver.solve(context);
if (equalityResult.equals(TRUE)) {
stepFoundSolutions.add(unknownSolutionIndex);
} else if (equalityResult.equals(FALSE)) {
// Can't unify
result = new StepSolver.Solution<>(Boolean.FALSE);
break;
} else {
// Solution to unification equality still unknown
}
}
if (result == null) {
stepUnknownSolutionIndexesForUnificationEqualities.removeAll(stepFoundSolutions);
if (stepUnknownSolutionIndexesForUnificationEqualities.size() == 0) {
// No more unknown solutions and this means all of them were true if we got to here
result = new StepSolver.Solution<>(Boolean.TRUE);
} else {
// We still have unknown equality unifications, so will split on the first unknown
// of these equalities
Integer firstUnknownUnificationEqualityIndex = stepUnknownSolutionIndexesForUnificationEqualities.get(0);
Expression unknownUnificationEqualityToSplitOn = unificationEqualitiesToTest.get(firstUnknownUnificationEqualityIndex);
StepSolver<Boolean> ifTrue;
if (stepUnknownSolutionIndexesForUnificationEqualities.size() == 1) {
// If there is only 1 unknown unification equality remaining, then on the true branch
// we know the unification will result in true, so just return that known up front.
ifTrue = new ConstantStepSolver<>(Boolean.TRUE);
} else {
ifTrue = this.clone();
((UnificationStepSolver) ifTrue).unknownSolutionIndexesForUnificationEqualities = new ArrayList<>(stepUnknownSolutionIndexesForUnificationEqualities);
}
StepSolver<Boolean> ifFalse = new ConstantStepSolver<>(Boolean.FALSE);
ContextSplitting contextSplitting = null;
// information for the literal.
if (context.getTheory().isLiteralOrBooleanConstant(unknownUnificationEqualityToSplitOn, context)) {
contextSplitting = new ContextSplitting(unknownUnificationEqualityToSplitOn, context);
}
result = new StepSolver.ItDependsOn<>(unknownUnificationEqualityToSplitOn, contextSplitting, ifTrue, ifFalse);
}
}
}
return result;
}
Aggregations