Ensure the null value is never exposed when merging variable (ground-free)

This commit is contained in:
Fedor Isakov 2016-03-03 16:42:09 +01:00
parent 701a434d69
commit 63bb7f578d
2 changed files with 42 additions and 8 deletions

View File

@ -104,27 +104,31 @@ class MemLogical<T> : SolverLogical<T> {
thisRepr.incRank();
}
otherRepr.setParent(thisRepr)
thisRepr.mergeParentObservers(otherRepr)
val thisVal = thisRepr.value();
val otherVal = otherRepr.value();
// first copy the value
if (thisVal == null && otherVal != null) {
// var ground
thisRepr.setValue(otherVal);
// TODO: clear the value in the "other" logical after union
} else if (thisVal != null && otherVal == null) {
// ground var
// otherRepr.setValue(thisRepr.value());
// TODO: no need to copy the value
otherRepr.notifyValueUpdated();
otherRepr.setValue(thisVal);
}
} else if (thisVal == null && otherVal == null) {
// then set parent
otherRepr.setParent(thisRepr)
thisRepr.mergeParentObservers(otherRepr)
// last, reconcile the values/merge observers
if (thisVal == null && otherVal == null) {
// var var
thisRepr.mergeValueObservers(otherRepr);
} else {
} else if (thisVal != null && otherVal != null) {
// ground ground
reconciler.reconcile(thisVal, otherVal);
}

View File

@ -166,7 +166,8 @@ class TestProgram {
).session("reactivateOnUnion").run {
assertEquals(setOf( ConstraintSymbol("foo", 2),
ConstraintSymbol("capture", 1),
ConstraintSymbol("replaced", 0)), constraintSymbols())
ConstraintSymbol("replaced", 0)),
constraintSymbols())
assertEquals(1, constraintOccurrences(ConstraintSymbol("foo", 2)).count())
// FIXME: this count should be 2 instead as per the "activation history" feature
assertEquals(3, constraintOccurrences(ConstraintSymbol("capture", 1)).count())
@ -174,6 +175,35 @@ class TestProgram {
}
}
@Test
fun reactivateOnUnionKeepValue() {
val (X,Y,Z) = metaLogical<Int>("X", "Y", "Z")
program(
rule("main",
headReplaced( constraint("main") ), body( statement({ x, y -> x eq y }, X, Y), // rank(X) = 1
statement({ z -> z.set(42) }, Z),
constraint("foo", Z),
statement({ x, z -> x eq z }, X, Z) )
),
rule("capture_foo_free",
headKept( constraint("foo", X) ), guard( expression({x -> x.getNullable() == null }, X) ),
body( constraint("free") )
),
rule("capture_foo_assigned",
headKept( constraint("foo", X) ), guard( expression({x -> x.getNullable() != null }, X) ),
body( constraint("assigned") )
)
).session("reactivateOnUnionKeepValue").run {
assertEquals(setOf( ConstraintSymbol("foo", 1),
ConstraintSymbol("assigned", 0)),
constraintSymbols())
assertEquals(1, constraintOccurrences(ConstraintSymbol("foo", 1)).count())
// FIXME: this count should be 1 instead as per the "activation history" feature (??? not sure)
assertEquals(2, constraintOccurrences(ConstraintSymbol("assigned", 0)).count())
}
}
@Test
fun gcd() {
val (M, N, TMP) = metaLogical<Int>("M", "N", "TMP")