Ensure the null value is never exposed when merging variable (ground-free)
This commit is contained in:
parent
701a434d69
commit
63bb7f578d
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Reference in New Issue