use of com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class LiteralStepSolver method step.
@Override
public StepSolver.Step<Boolean> step(Context context) {
ContextSplitting split = new ContextSplitting(literal, context);
switch(split.getResult()) {
case CONSTRAINT_IS_CONTRADICTORY:
return null;
case LITERAL_IS_TRUE:
return new Solution<Boolean>(true);
case LITERAL_IS_FALSE:
return new Solution<Boolean>(false);
case LITERAL_IS_UNDEFINED:
StepSolver<Boolean> ifTrue = constantStepSolver(true);
StepSolver<Boolean> ifFalse = constantStepSolver(false);
return new ItDependsOn<Boolean>(literal, split, ifTrue, ifFalse);
default:
throw new Error("Unrecognized splitting result.");
}
}
use of com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting 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;
}
use of com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class AbstractQuantifierEliminationStepSolver method combine.
protected Expression combine(Expression solution1, Expression solution2, Context context) {
Expression result;
if (isIfThenElse(solution1)) {
// (if C1 then A1 else A2) op solution2 ---> if C1 then (A1 op solution2) else (A2 op solution2)
ContextSplitting split = new ContextSplitting(condition(solution1), context);
switch(split.getResult()) {
case CONSTRAINT_IS_CONTRADICTORY:
result = null;
break;
case LITERAL_IS_UNDEFINED:
Expression subSolution1 = combine(thenBranch(solution1), solution2, split.getContextAndLiteral());
Expression subSolution2 = combine(elseBranch(solution1), solution2, split.getContextAndLiteralNegation());
result = IfThenElse.make(condition(solution1), subSolution1, subSolution2, true);
break;
case LITERAL_IS_TRUE:
result = combine(thenBranch(solution1), solution2, split.getContextAndLiteral());
break;
case LITERAL_IS_FALSE:
result = combine(elseBranch(solution1), solution2, split.getContextAndLiteralNegation());
break;
default:
throw new Error("Unrecognized result for " + ContextSplitting.class + ": " + split.getResult());
}
} else if (isIfThenElse(solution2)) {
// solution1 op (if C2 then B1 else B2) ---> if C2 then (solution1 op B2) else (solution1 op B2)
ContextSplitting split = new ContextSplitting(condition(solution2), context);
switch(split.getResult()) {
case CONSTRAINT_IS_CONTRADICTORY:
result = null;
break;
case LITERAL_IS_UNDEFINED:
Expression subSolution1 = combine(solution1, thenBranch(solution2), split.getContextAndLiteral());
Expression subSolution2 = combine(solution1, elseBranch(solution2), split.getContextAndLiteralNegation());
result = IfThenElse.make(condition(solution2), subSolution1, subSolution2, true);
break;
case LITERAL_IS_TRUE:
result = combine(solution1, thenBranch(solution2), split.getContextAndLiteral());
break;
case LITERAL_IS_FALSE:
result = combine(solution1, elseBranch(solution2), split.getContextAndLiteralNegation());
break;
default:
throw new Error("Unrecognized result for " + ContextSplitting.class + ": " + split.getResult());
}
} else {
result = group.add(solution1, solution2, context);
}
return result;
}
use of com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class AbstractExpressionWithPropagatedLiteralsStepSolver method cnfIsSatisfied.
/**
* A convenience method for testing whether a CNF, represented as an iterable of iterables of Expressions,
* is satisfied by a context.
* @param cnf
* @param context
* @return <code>null</code> if the context is found to be self-contradictory,
* an instance of {@link ItDependsOn} with a literal, if whether the CNF is satisfied or not depends on that literal,
* or an instance of {@link Solution} with expression {@link Expressions#TRUE} or {@link Expressions#FALSE}
* if whether the CNF is satisfied is already determined positively or negatively, respectively.
*/
protected Step cnfIsSatisfied(ArrayList<ArrayList<Expression>> cnf, Context context) {
// note the very unusual initialization of literalIndex
// this is due to our wanting to be initialized to initialLiteralToConsiderInInitialClauseToConsiderInPropagatedCNF,
// but only the first time the loop is executed (that is, inside the first clause loop)
// We therefore start the method by initializing it to initialLiteralToConsiderInInitialClauseToConsiderInPropagatedCNF,
// and then initialize it to 0 when clauseIndex is iterated.
int literalIndex = initialLiteralToConsiderInInitialClauseToConsiderInPropagatedCNF;
for (int clauseIndex = initialClauseToConsiderInPropagatedCNF; clauseIndex != cnf.size(); clauseIndex++, literalIndex = 0) {
// unusual! See above
ArrayList<Expression> clause = cnf.get(clauseIndex);
boolean clauseIsSatisfied = false;
for (; /* literalIndex already initialized at this point */
literalIndex != clause.size(); literalIndex++) {
Expression literal = clause.get(literalIndex);
ContextSplitting split = new ContextSplitting(literal, context);
switch(split.getResult()) {
case LITERAL_IS_UNDEFINED:
AbstractExpressionWithPropagatedLiteralsStepSolver subStepSolver = MAKE_SUB_STEP_SOLVERS_THAT_START_TO_CHECK_PROPAGATED_CNF_FROM_WHERE_THIS_ONE_LEFT_OFF ? makeCopyConsideringPropagatedCNFFromNowOn(clauseIndex, literalIndex) : this;
// literal is necessary, but undefined
return new ItDependsOn(literal, split, subStepSolver, subStepSolver);
// OPTIMIZATION: instead of returning the first undefined literal, we could look whether some clause is already unsatisfied
case LITERAL_IS_TRUE:
clauseIsSatisfied = true;
context = split.getContextAndLiteral();
break;
case LITERAL_IS_FALSE:
context = split.getContextAndLiteralNegation();
break;
case CONSTRAINT_IS_CONTRADICTORY:
return null;
}
if (clauseIsSatisfied) {
// no need to examine remaining literals in clause
break;
}
}
if (!clauseIsSatisfied) {
// clause is false, so the whole CNF is false
return new Solution(FALSE);
}
// else move on to next clause
}
return new Solution(TRUE);
}
use of com.sri.ai.grinder.sgdpllt.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class AbstractDecisionOnAllOrderedPairsOfExpressionsStepSolver method step.
@Override
public Step step(Context context) {
if (expressions.size() < 2) {
return makeSolutionStepWhenThereAreNoPairs();
}
if (hasPair()) {
Expression unsimplifiedLiteral = makeLiteral();
Expression literal = context.getTheory().simplify(unsimplifiedLiteral, context);
// this null is never used, just making compiler happy
AbstractDecisionOnAllOrderedPairsOfExpressionsStepSolver stepSolverForWhenLiteralIsTrue = null;
// this null is never used, just making compiler happy
AbstractDecisionOnAllOrderedPairsOfExpressionsStepSolver stepSolverForWhenLiteralIsFalse = null;
ContextSplitting split = new ContextSplitting(literal, context);
if (split.getResult().equals(ContextSplitting.Result.CONSTRAINT_IS_CONTRADICTORY)) {
return null;
}
boolean literalIsTrue = split.getResult() == ContextSplitting.Result.LITERAL_IS_TRUE;
boolean literalIsFalse = !literalIsTrue && split.getResult() == ContextSplitting.Result.LITERAL_IS_FALSE;
boolean undefined = !literalIsTrue && !literalIsFalse;
boolean needSubStepSolverForWhenLiteralIsTrue = literalIsTrue || undefined;
boolean needSubStepSolverForWhenLiteralIsFalse = literalIsFalse || undefined;
if (needSubStepSolverForWhenLiteralIsTrue) {
stepSolverForWhenLiteralIsTrue = makeSubStepSolverForWhenLiteralIsTrue();
}
if (needSubStepSolverForWhenLiteralIsFalse) {
stepSolverForWhenLiteralIsFalse = makeSubStepSolverForWhenLiteralIsFalse();
}
if (literalIsTrue) {
return stepSolverForWhenLiteralIsTrue.step(split.getConstraintAndLiteral());
} else if (literalIsFalse) {
return stepSolverForWhenLiteralIsFalse.step(split.getConstraintAndLiteralNegation());
} else {
return new ItDependsOn(literal, split, stepSolverForWhenLiteralIsTrue, stepSolverForWhenLiteralIsFalse);
}
}
// went over all pairs
Solution result = makeSolutionStepAfterGoingOverAllPairs();
return result;
}
Aggregations