in reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalImpl.kt [91:150]
override fun union(other: MutableLogical<T>, reconciler: MutableLogical.ValueReconciler<T>) {
val thisRepr = this.find()
val otherRepr = (other as LogicalImpl<T>).find()
if (thisRepr === otherRepr) {
// nothing to do
return
}
// invariant: thisRepr.rank > otherRepr.rank
if (thisRepr.rank() < otherRepr.rank()) {
otherRepr.union(thisRepr, reconciler)
return
} else if (thisRepr.rank() == otherRepr.rank()) {
if (thisRepr._value == null && otherRepr._value != null) {
otherRepr.union(thisRepr, reconciler)
return
} else {
thisRepr.incRank()
}
}
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
// TODO: no need to copy the value
otherRepr.setValue(thisVal)
}
// reconcile the values/merge value observers
if (thisVal == null && otherVal == null) {
// var var
thisRepr.mergeValueObservers(otherRepr)
} else if (thisVal != null && otherVal != null) {
// ground ground
reconciler.reconcile(thisVal, otherVal)
}
// save other observers
val otherObservers = ArrayList(otherRepr.parentObservers)
mergeParentObservers(thisRepr, otherRepr)
// finally set parent and notify observers
otherRepr._parent = thisRepr
for (p in otherObservers) {
p.second.parentUpdated(p.first)
}
}