use of com.sri.ai.grinder.sgdpllt.theory.equality.EqualityTheory in project aic-praise by aic-sri-international.
the class UAIUtil method constructGenericTableExpressionUsingEqualities.
/**
* Returns an {@link Expression} equivalent to a given {@link FunctionTable} but in the form of a decision tree
* (so hopefully more compact) using equalities.
* @param functionTable
* @param solverListener if not null, invoked on solver used for compilation, before and after compilation is performed; returned solver from "before" invocation is used (it may be the same one used as argument, of course).
* @return
*/
public static Expression constructGenericTableExpressionUsingEqualities(FunctionTable functionTable, Function<MultiIndexQuantifierEliminator, MultiIndexQuantifierEliminator> solverListener) {
StringBuilder table = new StringBuilder();
CartesianProductEnumeration<Integer> cartesianProduct = new CartesianProductEnumeration<>(cardinalityValues(functionTable));
int counter = 0;
while (cartesianProduct.hasMoreElements()) {
counter++;
List<Integer> values = cartesianProduct.nextElement();
Double entryValue = functionTable.entryFor(values);
if (counter == cartesianProduct.size().intValue()) {
// i.e. final value
table.append(entryValue);
} else {
table.append("if ");
for (int i = 0; i < values.size(); i++) {
if (i > 0) {
table.append(" and ");
}
String value = genericConstantValueForVariable(values.get(i), i, functionTable.cardinality(i));
if (value.equals("true")) {
table.append(genericVariableName(i));
} else if (value.equals("false")) {
table.append("not " + genericVariableName(i));
} else {
table.append(genericVariableName(i));
table.append(" = ");
table.append(value);
}
}
table.append(" then ");
table.append(entryValue);
table.append(" else ");
}
}
Expression inputExpression = Expressions.parse(table.toString());
Function<Integer, Integer> cardinalityOfIthVariable = i -> functionTable.cardinality(i);
Map<String, String> mapFromCategoricalTypeNameToSizeString = new LinkedHashMap<>();
Map<String, String> mapFromVariableNameToTypeName = new LinkedHashMap<>();
Map<String, String> mapFromUniquelyNamedConstantToTypeName = new LinkedHashMap<>();
for (int i = 0; i < functionTable.numberVariables(); i++) {
String typeName = genericTypeNameForVariable(i, cardinalityOfIthVariable.apply(i));
mapFromCategoricalTypeNameToSizeString.put(typeName, "" + cardinalityOfIthVariable.apply(i));
mapFromVariableNameToTypeName.put(genericVariableName(i), typeName);
for (int j = 0; j != functionTable.cardinality(i); j++) {
String jThConstant = genericConstantValueForVariable(j, i, functionTable.cardinality(i));
mapFromUniquelyNamedConstantToTypeName.put(jThConstant, typeName);
}
}
com.sri.ai.grinder.sgdpllt.api.Theory theory = new EqualityTheory(true, true);
Expression result = Compilation.compile(inputExpression, theory, mapFromVariableNameToTypeName, mapFromUniquelyNamedConstantToTypeName, mapFromCategoricalTypeNameToSizeString, list(), solverListener);
return result;
}
use of com.sri.ai.grinder.sgdpllt.theory.equality.EqualityTheory in project aic-expresso by aic-sri-international.
the class UnificationStepSolverTest method advancedCompositeTest.
@Ignore("TODO - context implementation currently does not support these more advanced/indirect comparisons")
@Test
public void advancedCompositeTest() {
TheoryTestingSupport theoryTestingSupport = TheoryTestingSupport.make(seededRandom, new CompoundTheory(new EqualityTheory(false, true), new DifferenceArithmeticTheory(false, true), new LinearRealArithmeticTheory(false, true), new PropositionalTheory()));
// NOTE: passing explicit FunctionTypes will prevent the general variables' argument types being randomly changed.
theoryTestingSupport.setVariableNamesAndTypesForTesting(map("P", BOOLEAN_TYPE, "Q", BOOLEAN_TYPE, "R", BOOLEAN_TYPE, "unary_prop/1", new FunctionType(BOOLEAN_TYPE, BOOLEAN_TYPE), "binary_prop/2", new FunctionType(BOOLEAN_TYPE, BOOLEAN_TYPE, BOOLEAN_TYPE), "S", TESTING_CATEGORICAL_TYPE, "T", TESTING_CATEGORICAL_TYPE, "U", TESTING_CATEGORICAL_TYPE, "unary_eq/1", new FunctionType(TESTING_CATEGORICAL_TYPE, TESTING_CATEGORICAL_TYPE), "binary_eq/2", new FunctionType(TESTING_CATEGORICAL_TYPE, TESTING_CATEGORICAL_TYPE, TESTING_CATEGORICAL_TYPE), "I", TESTING_INTEGER_INTERVAL_TYPE, "J", TESTING_INTEGER_INTERVAL_TYPE, "K", TESTING_INTEGER_INTERVAL_TYPE, "unary_dar/1", new FunctionType(TESTING_INTEGER_INTERVAL_TYPE, TESTING_INTEGER_INTERVAL_TYPE), "binary_dar/2", new FunctionType(TESTING_INTEGER_INTERVAL_TYPE, TESTING_INTEGER_INTERVAL_TYPE, TESTING_INTEGER_INTERVAL_TYPE), "X", TESTING_REAL_INTERVAL_TYPE, "Y", TESTING_REAL_INTERVAL_TYPE, "Z", TESTING_REAL_INTERVAL_TYPE, "unary_lra/1", new FunctionType(TESTING_REAL_INTERVAL_TYPE, TESTING_REAL_INTERVAL_TYPE), "binary_lra/2", new FunctionType(TESTING_REAL_INTERVAL_TYPE, TESTING_REAL_INTERVAL_TYPE, TESTING_REAL_INTERVAL_TYPE)));
Context rootContext = theoryTestingSupport.makeContextWithTestingInformation();
UnificationStepSolver unificationStepSolver = new UnificationStepSolver(parse("binary_prop(P, unary_prop(P))"), parse("binary_prop(unary_prop(Q), Q)"));
Context localTestContext = rootContext.conjoinWithConjunctiveClause(parse("not P and Q and not unary_prop(Q) and unary_prop(P)"), rootContext);
StepSolver.Step<Boolean> step = unificationStepSolver.step(localTestContext);
Assert.assertEquals(false, step.itDepends());
Assert.assertEquals(true, step.getValue());
localTestContext = rootContext.conjoinWithConjunctiveClause(parse("P and Q and not unary_prop(Q) and unary_prop(P)"), rootContext);
step = unificationStepSolver.step(localTestContext);
Assert.assertEquals(false, step.itDepends());
Assert.assertEquals(false, step.getValue());
}
use of com.sri.ai.grinder.sgdpllt.theory.equality.EqualityTheory in project aic-expresso by aic-sri-international.
the class CompoundTheoryWithDifferenceArithmeticTest method runCompleteSatisfiabilityTest.
/**
* @param conjunction
* @param expected
*/
private void runCompleteSatisfiabilityTest(String conjunction, Expression expected, Map<String, Type> variableNamesAndTypesForTesting) {
TheoryTestingSupport equalityTheoryTestingSupport = TheoryTestingSupport.make(makeRandom(), new EqualityTheory(true, true));
equalityTheoryTestingSupport.setVariableNamesAndTypesForTesting(variableNamesAndTypesForTesting);
TheoryTestingSupport theoryTestingSupport = TheoryTestingSupport.make(makeRandom(), equalityTheoryTestingSupport, TheoryTestingSupport.make(makeRandom(), new PropositionalTheory()));
Context context = theoryTestingSupport.makeContextWithTestingInformation();
Constraint constraint = new CompleteMultiVariableContext(theoryTestingSupport.getTheory(), context);
for (Expression literal : And.getConjuncts(parse(conjunction))) {
constraint = constraint.conjoin(literal, context);
}
assertEquals(expected, constraint);
}
use of com.sri.ai.grinder.sgdpllt.theory.equality.EqualityTheory in project aic-expresso by aic-sri-international.
the class CompoundTheoryWithDifferenceArithmeticTest method makeTheoryTestingSupport.
@Override
protected TheoryTestingSupport makeTheoryTestingSupport() {
TheoryTestingSupport result = TheoryTestingSupport.make(makeRandom(), new CompoundTheory(new EqualityTheory(false, true), new DifferenceArithmeticTheory(false, true), new PropositionalTheory()));
// using different testing variables and types to test distribution of testing information
// to sub constraint theories.
Categorical booleanType = BOOLEAN_TYPE;
Categorical dogsType = new Categorical("Dogs", 4, arrayList(parse("fido"), parse("rex")));
IntegerInterval oneTwoThree = new IntegerInterval(1, 3);
Map<String, Type> variablesAndTypes = map("F", booleanType, "G", booleanType, "R", dogsType, "S", dogsType, "T", oneTwoThree, "U", oneTwoThree);
result.setVariableNamesAndTypesForTesting(variablesAndTypes);
return result;
}
use of com.sri.ai.grinder.sgdpllt.theory.equality.EqualityTheory in project aic-expresso by aic-sri-international.
the class NumberOfDistinctExpressionsStepSolverTest 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");
context = context.conjoin(parse(contextString), context);
ArrayList<Expression> list = mapIntoArrayList(elementsStrings, Expressions::parse);
NumberOfDistinctExpressionsStepSolver stepSolver = new NumberOfDistinctExpressionsStepSolver(list);
Step step = stepSolver.step(context);
assertEquals(true, step.itDepends());
assertEquals(parse("X = c"), step.getSplitter());
ExpressionLiteralSplitterStepSolver stepSolverIfXEqualsC = step.getStepSolverForWhenSplitterIsTrue();
ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromC = step.getStepSolverForWhenSplitterIsFalse();
// if X = c, the number of distinct values can be 3 or 4, depending on whether Y = a, or Y = b
step = stepSolverIfXEqualsC.step(context);
assertEquals(true, step.itDepends());
assertEquals(parse("Y = a"), step.getSplitter());
ExpressionLiteralSplitterStepSolver stepSolverIfXEqualsCAndYEqualsA = step.getStepSolverForWhenSplitterIsTrue();
ExpressionLiteralSplitterStepSolver stepSolverIfXEqualsCAndYIsDifferentFromA = step.getStepSolverForWhenSplitterIsFalse();
// if X = c and Y = a, the number of distinct values is 3 (a, b, c)
step = stepSolverIfXEqualsCAndYEqualsA.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("3"), step.getValue());
// if X = c and Y != a, the number of distinct values is 3 or 4, depending on Y = c
step = stepSolverIfXEqualsCAndYIsDifferentFromA.step(context);
assertEquals(true, step.itDepends());
assertEquals(parse("Y = c"), step.getSplitter());
ExpressionLiteralSplitterStepSolver stepSolverIfXEqualsCAndYIsDifferentFromAAndYEqualsC = step.getStepSolverForWhenSplitterIsTrue();
ExpressionLiteralSplitterStepSolver stepSolverIfXEqualsCAndYIsDifferentFromAAndYIsDifferentFromC = step.getStepSolverForWhenSplitterIsFalse();
// if X = c and Y != a and Y = c, the number of distinct values is 3
step = stepSolverIfXEqualsCAndYIsDifferentFromAAndYEqualsC.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("3"), step.getValue());
// if X = c and Y != a and Y != c, the number of distinct values is 4
step = stepSolverIfXEqualsCAndYIsDifferentFromAAndYIsDifferentFromC.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("4"), step.getValue());
// if X = c and Y = a, the number of distinct values is 3 (a, b, c)
step = stepSolverIfXEqualsCAndYEqualsA.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("3"), step.getValue());
// using again just to make sure it produces the same result
step = stepSolverIfXEqualsCAndYEqualsA.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("3"), step.getValue());
// if X != c, the number of distinct value 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());
// if X != c, the number of distinct values can be 4 or 5, depending on whether Y = a, or Y = b
step = stepSolverIfXIsDifferentFromC.step(context);
assertEquals(true, step.itDepends());
assertEquals(parse("Y = a"), step.getSplitter());
ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYEqualsA = step.getStepSolverForWhenSplitterIsTrue();
ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYIsDifferentFromA = step.getStepSolverForWhenSplitterIsFalse();
step = stepSolverIfXIsDifferentFromCAndYEqualsA.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("4"), 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.getStepSolverForWhenSplitterIsTrue();
ExpressionLiteralSplitterStepSolver stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsDifferentFromC = step.getStepSolverForWhenSplitterIsFalse();
// if Y = c, then there are 4 distinct values
step = stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsEqualToC.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("4"), step.getValue());
// if Y != c, then Y is also unique and the number of distinct values is 5
step = stepSolverIfXIsDifferentFromCAndYIsDifferentFromAAndYIsDifferentFromC.step(context);
assertEquals(false, step.itDepends());
assertEquals(parse("5"), step.getValue());
}
Aggregations