override fun union()

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)
        }
    }