package org.simantics.scl.runtime.unification; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.tuple.Tuple; import org.simantics.scl.runtime.tuple.Tuple0; public class Unification { public static Object canonical(Object a) { if(a instanceof UVar) { UVar ua = (UVar)a; if(ua.bound) return ua.ref = canonical(ua.ref); else return a; } return a; } @SuppressWarnings("unchecked") public static void unify(Object a, Object b) { a = canonical(a); b = canonical(b); if(a == b) return; if(a instanceof UVar) { ((UVar)a).setRef(b); return; } if(b instanceof UVar) { ((UVar)b).setRef(a); return; } if(a instanceof UPending) { ((UPending)a).checkAgains(b); return; } if(b instanceof UPending) { ((UPending)b).checkAgains(a); return; } if(a instanceof UCons) { UCons ua = (UCons)a; if(b instanceof UCons) { UCons ub = (UCons)b; if(ua.tag.id != ub.tag.id) throw new RuntimeUnificationException(); unifyTuple(ua.components, ub.components); ua.components = ub.components; } else { Object bComponents = ua.tag.destructor.apply(b); unifyTuple(ua.components, bComponents); ua.components = bComponents; } } else { if(b instanceof UCons) { UCons ub = (UCons)b; Object aComponents = ub.tag.destructor.apply(a); unifyTuple(aComponents, ub.components); ub.components = aComponents; } else { if(a == null ? b != null : !a.equals(b)) throw new RuntimeUnificationException(); } } } public static void unifyTuple(Object a, Object b) { if(a instanceof Tuple) { Tuple ta = (Tuple)a; Tuple tb = (Tuple)b; int length = ta.length(); for(int i=0;i