use of com.sri.ai.grinder.sgdpllt.api.SingleVariableConstraint in project aic-expresso by aic-sri-international.
the class SGDPLLT method encodeConditionAsLastIndexConstraintIfPossibleOrInBodyOtherwise.
/**
* If condition is an instance of {@link SingleVariableConstraint} or is representable as one
* (that is, it is a conjunctive clause),
* then make it the constraint to be used for last index, and use original given body.
* Otherwise, encode the condition as part of the body,
* in the form <code>if condition then body else identityElement</code>.
* This is particularly useful when the condition is already a constraint of {@link SingleVariableConstraint},
* since it re-used to work put on building it in the first place.
* @param group
* @param indexExpressions
* @param quantifierFreeIndicesCondition
* @param quantifierFreeBody
* @param context
* @return
*/
private static Pair<Expression, SingleVariableConstraint> encodeConditionAsLastIndexConstraintIfPossibleOrInBodyOtherwise(AssociativeCommutativeGroup group, List<Expression> indices, Expression quantifierFreeIndicesCondition, Expression quantifierFreeBody, Theory theory, Context context) {
Expression body;
SingleVariableConstraint lastIndexConstraint = null;
Expression lastIndex = getLast(indices);
try {
body = quantifierFreeBody;
lastIndexConstraint = SingleVariableConstraint.make(theory, lastIndex, quantifierFreeIndicesCondition, context);
return Pair.make(body, lastIndexConstraint);
} catch (Error e) {
/* proceed to default case below */
}
// did not work out because condition is not SingleVariableConstraint on last index
body = IfThenElse.make(quantifierFreeIndicesCondition, quantifierFreeBody, group.additiveIdentityElement());
lastIndexConstraint = theory.makeSingleVariableConstraint(lastIndex, theory, context);
Pair<Expression, SingleVariableConstraint> bodyAndLastIndexConstraint = Pair.make(body, lastIndexConstraint);
return bodyAndLastIndexConstraint;
}
use of com.sri.ai.grinder.sgdpllt.api.SingleVariableConstraint in project aic-expresso by aic-sri-international.
the class SGDPLLT method solve.
/**
* @param group
* @param indices
* @param indicesCondition
* @param body
* @param context
* @return
*/
@Override
public Expression solve(AssociativeCommutativeGroup group, List<Expression> indices, Expression indicesCondition, Expression body, Context context) {
Theory theory = context.getTheory();
Expression currentBody = body;
int numberOfIndices = indices.size();
if (numberOfIndices != 0) {
// Re-use {@link SingleVariableConstraint} if condition is one.
// TODO: eventually we want the algorithm to work so that it splitters may be entire constraints,
// if they are found. Then this encoding would become superfluous,
// and the condition could always be safely encoded in the body, since it would then be picked and re-used.
// This would also re-use body if it happens to be a constraint.
Pair<Expression, SingleVariableConstraint> bodyAndLastIndexConstraint = SGDPLLT.encodeConditionAsLastIndexConstraintIfPossibleOrInBodyOtherwise(group, indices, indicesCondition, body, theory, context);
currentBody = bodyAndLastIndexConstraint.first;
SingleVariableConstraint lastIndexConstraint = bodyAndLastIndexConstraint.second;
if (lastIndexConstraint.isContradiction()) {
return group.additiveIdentityElement();
}
for (int i = numberOfIndices - 1; i >= 0; i--) {
// evaluate from inside out; this may change in the future
Expression index = indices.get(i);
SingleVariableConstraint constraintForThisIndex = i == numberOfIndices - 1 ? lastIndexConstraint : theory.makeSingleVariableConstraint(index, theory, context);
ExpressionLiteralSplitterStepSolver quantifierEliminatorStepSolver = theory.getSingleVariableConstraintQuantifierEliminatorStepSolver(group, constraintForThisIndex, currentBody, context);
if (quantifierEliminatorStepSolver != null) {
currentBody = quantifierEliminatorStepSolver.solve(context);
} else {
// cannot eliminate this level, so reconstruct original expression up to this index
throw new Error("Reconstruction of quantifier not yet eliminable not yet implemented.");
// once implemented, must return
}
}
} else {
currentBody = IfThenElse.make(indicesCondition, currentBody, group.additiveIdentityElement());
}
// Normalize final result.
ExpressionLiteralSplitterStepSolver evaluator = theory.makeEvaluatorStepSolver(currentBody);
currentBody = evaluator.solve(context);
return currentBody;
}
use of com.sri.ai.grinder.sgdpllt.api.SingleVariableConstraint in project aic-expresso by aic-sri-international.
the class DefaultMultiVariableConstraint method conjoinWithLiteral.
@Override
public DefaultMultiVariableConstraint conjoinWithLiteral(Expression literal, Context context) {
DefaultMultiVariableConstraint result;
Expression variable = getSomeVariableFor(literal, context);
if (variable == null) {
// the literal has no variables.
Expression literalEvaluation = getTheory().simplify(literal, context);
if (literalEvaluation.equals(TRUE)) {
result = this;
} else {
result = makeContradiction();
}
} else {
SingleVariableConstraint singleVariableConstraint = getConstraintFor(variable, context);
SingleVariableConstraint newSingleVariableConstraint = singleVariableConstraint.conjoin(literal, context);
if (newSingleVariableConstraint.isContradiction()) {
result = makeContradiction();
} else if (newSingleVariableConstraint == singleVariableConstraint) {
result = this;
} else {
Map<Expression, SingleVariableConstraint> newFromVariableToItsConstraint = new LinkedHashMap<>(fromVariableToItsConstraint);
newFromVariableToItsConstraint.put(variable, newSingleVariableConstraint);
result = makeWithNewFromVariableToItsConstraint(newFromVariableToItsConstraint);
}
}
return result;
}
use of com.sri.ai.grinder.sgdpllt.api.SingleVariableConstraint in project aic-expresso by aic-sri-international.
the class MultiVariableContextWithCheckedProperty method conjoinWithLiteral.
@Override
public Context conjoinWithLiteral(Expression literal, Context context) {
Context result;
if (literal.equals(TRUE)) {
result = this;
} else if (literal.equals(FALSE)) {
result = makeContradiction();
} else {
Collection<Expression> variablesInLiteral = getTheory().getVariablesIn(literal, context);
if (variablesInLiteral.isEmpty()) {
Expression literalSimplifiedToConstant = getTheory().simplify(literal, context);
if (literalSimplifiedToConstant == literal) {
throw new Error("Literal " + literal + " should have been simplified to a boolean constant, but was not. Sometimes this is caused by using a symbol as a variable, but which has not been declared as a variable in the context, or has been declared as a uniquely named constant in the Context (for example by constructing the Context with the default PrologConstantPredicate as a default predicate for recognizing constants, which recognizes all non-capitalized identifiers as such)");
}
result = conjoinWithLiteral(literalSimplifiedToConstant, context);
} else if (head != null) {
SingleVariableConstraint newHead;
Context newTail;
if (variablesInLiteral.contains(head.getVariable())) {
newHead = head.conjoin(literal, context);
newTail = tail;
} else {
newHead = head;
newTail = tail.conjoin(literal, context);
}
// up the chain so they are integrated and simplified in the corresponding single-variable constraints
if (!newHead.isContradiction()) {
for (Expression externalLiteral : newHead.getExternalLiterals()) {
if (!newTail.isContradiction()) {
newTail = newTail.conjoin(externalLiteral, context);
}
}
newHead = newHead.makeSimplificationWithoutExternalLiterals();
}
if (newHead == head && newTail == tail) {
// in case nothing changed
result = this;
} else {
result = makeAndCheck(getTheory(), newHead, newTail, contextDependentProblemStepSolverMaker, context);
}
} else {
Expression firstVariable = getFirstOrNull(variablesInLiteral);
SingleVariableConstraint newSingleVariableConstraint = getTheory().makeSingleVariableConstraint(firstVariable, getTheory(), context);
newSingleVariableConstraint = newSingleVariableConstraint.conjoin(literal, context);
result = makeAndCheck(getTheory(), newSingleVariableConstraint, this, contextDependentProblemStepSolverMaker, context);
}
}
return result;
}
use of com.sri.ai.grinder.sgdpllt.api.SingleVariableConstraint in project aic-expresso by aic-sri-international.
the class SGDPLLTTester method runGroupProblemSolvingTesterForSuccessiveConstraints.
private static void runGroupProblemSolvingTesterForSuccessiveConstraints(String problemName, TestRunner tester, boolean testAgainstBruteForce, AssociativeCommutativeGroup group, TheoryTestingSupport theoryTestingSupport, long numberOfTests, int maxNumberOfLiterals, boolean outputCount) throws Error {
Context context = theoryTestingSupport.makeContextWithTestingInformation();
NullaryFunction<Constraint> makeInitialConstraint = () -> theoryTestingSupport.getTheory().makeSingleVariableConstraint(parse(theoryTestingSupport.pickTestingVariableAtRandom()), theoryTestingSupport.getTheory(), context);
Function<Constraint, Expression> makeRandomLiteral = c -> theoryTestingSupport.makeRandomLiteralOn(((SingleVariableConstraint) c).getVariable().toString(), context);
runTesterGivenOnSuccessiveConjunctionsOfLiterals(problemName, tester, numberOfTests, maxNumberOfLiterals, testAgainstBruteForce, theoryTestingSupport, makeInitialConstraint, makeRandomLiteral, outputCount, context);
}
Aggregations