use of com.sri.ai.grinder.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.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.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class ExhaustiveTest method testSimpleExhaustiveConditionalRewriter.
@Test
public void testSimpleExhaustiveConditionalRewriter() {
class FunkyStepSolver implements ExpressionLiteralSplitterStepSolver {
private Expression expression;
public FunkyStepSolver(Expression expression) {
this.expression = expression;
}
@Override
public FunkyStepSolver clone() {
FunkyStepSolver result = null;
try {
result = (FunkyStepSolver) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return result;
}
@Override
public Step step(Context context) {
if (Expressions.isNumber(expression) && expression.intValue() % 10 != 0) {
if (expression.intValue() == 5) {
Expression literal = parse("JumpAt5");
ContextSplitting splitting = new ContextSplitting(literal, context);
switch(splitting.getResult()) {
case LITERAL_IS_TRUE:
return new Solution(parse("11"));
case LITERAL_IS_FALSE:
return new Solution(parse("6"));
case LITERAL_IS_UNDEFINED:
return new ItDependsOn(literal, splitting, this, this);
default:
throw new Error("Unpredicted case");
}
} else {
return new Solution(DefaultSymbol.createSymbol(expression.intValue() + 1));
}
} else
return new Solution(expression);
}
}
;
Rewriter rewriter = (Expression e) -> new FunkyStepSolver(e);
Expression initial = parse("1");
Expression expected = parse("if JumpAt5 then 20 else 10");
runTest(rewriter, initial, expected, map(parse("JumpAt5"), parse("Boolean")));
}
use of com.sri.ai.grinder.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class INCOMPLETE_BooleanFormulaExpressionStepSolver method step.
@Override
public Step step(Context context) {
Step result;
Expression splitter;
Expression problemIfSplitterIsTrue;
Expression problemIfSplitterIsFalse;
Expression functor = booleanFormula.getFunctor();
String functorString = functor == null ? "" : functor.toString();
switch(functorString) {
case FunctorConstants.AND:
List<Expression> arguments = booleanFormula.getArguments();
int numberOfArguments = booleanFormula.numberOfArguments();
splitter = arguments.get(0);
List<Expression> rest = arguments.subList(1, numberOfArguments);
problemIfSplitterIsTrue = And.make(rest);
problemIfSplitterIsFalse = Expressions.FALSE;
break;
default:
splitter = booleanFormula;
problemIfSplitterIsTrue = Expressions.TRUE;
problemIfSplitterIsFalse = Expressions.FALSE;
}
// IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
// Need to extend context to non-conjunctive formulas so I can split on formulas below
ContextSplitting contextSplitting = new ContextSplitting(null, context);
ExpressionStepSolver ifFirstConjunctIsTrue;
ExpressionStepSolver ifFirstConjunctIsFalse;
switch(contextSplitting.getResult()) {
case LITERAL_IS_TRUE:
ifFirstConjunctIsTrue = new INCOMPLETE_BooleanFormulaExpressionStepSolver(problemIfSplitterIsTrue);
result = ifFirstConjunctIsTrue.step(contextSplitting.getContextAndLiteral());
break;
case LITERAL_IS_FALSE:
ifFirstConjunctIsFalse = new INCOMPLETE_BooleanFormulaExpressionStepSolver(problemIfSplitterIsFalse);
result = ifFirstConjunctIsFalse.step(contextSplitting.getContextAndLiteralNegation());
break;
case LITERAL_IS_UNDEFINED:
ifFirstConjunctIsTrue = new INCOMPLETE_BooleanFormulaExpressionStepSolver(problemIfSplitterIsTrue);
ifFirstConjunctIsFalse = new INCOMPLETE_BooleanFormulaExpressionStepSolver(problemIfSplitterIsFalse);
result = new ItDependsOn(splitter, contextSplitting, ifFirstConjunctIsTrue, ifFirstConjunctIsFalse);
break;
case CONSTRAINT_IS_CONTRADICTORY:
throw new Error("Should not be operating under contradictory context, but got " + context);
default:
throw new Error("Unexpected context splitting result: " + contextSplitting.getResult());
}
return result;
}
use of com.sri.ai.grinder.core.constraint.ContextSplitting in project aic-expresso by aic-sri-international.
the class FirstOfTest method testSimpleFirstOfConditionalRewriter.
@Test
public void testSimpleFirstOfConditionalRewriter() {
class JumperAtStepSolver implements ExpressionLiteralSplitterStepSolver {
private Expression expression;
private int jumpPoint;
public JumperAtStepSolver(Expression expression, int jumpPoint) {
this.expression = expression;
this.jumpPoint = jumpPoint;
}
@Override
public JumperAtStepSolver clone() {
JumperAtStepSolver result = null;
try {
result = (JumperAtStepSolver) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return result;
}
@Override
public Step step(Context context) {
if (Expressions.isNumber(expression) && expression.intValue() % 10 != 0) {
if (expression.intValue() == jumpPoint) {
Expression literal = parse("Jump5");
ContextSplitting splitting = new ContextSplitting(literal, context);
switch(splitting.getResult()) {
case LITERAL_IS_TRUE:
return new Solution(DefaultSymbol.createSymbol(jumpPoint + 5));
case LITERAL_IS_FALSE:
return new Solution(DefaultSymbol.createSymbol(jumpPoint + 1));
case LITERAL_IS_UNDEFINED:
return new ItDependsOn(literal, splitting, this, this);
default:
throw new Error("Unpredicted case");
}
} else {
return new Solution(expression);
}
} else
return new Solution(expression);
}
}
;
List<Rewriter> rewriters = Util.<Rewriter>list((Expression e) -> new JumperAtStepSolver(e, 5), (Expression e) -> new JumperAtStepSolver(e, 8));
Expression initial;
Expression expected;
initial = parse("1");
// no jumps at 1
expected = parse("1");
runTest(rewriters, initial, expected, map(parse("Jump5"), parse("Boolean")));
initial = parse("5");
expected = parse("if Jump5 then 10 else 6");
runTest(rewriters, initial, expected, map(parse("Jump5"), parse("Boolean")));
initial = parse("8");
expected = parse("if Jump5 then 13 else 9");
runTest(rewriters, initial, expected, map(parse("Jump5"), parse("Boolean")));
}
Aggregations