1 package org.simantics.scl.runtime.unification;
3 import org.simantics.scl.runtime.function.Function;
4 import org.simantics.scl.runtime.tuple.Tuple;
5 import org.simantics.scl.runtime.tuple.Tuple0;
8 public class Unification {
9 public static Object canonical(Object a) {
10 if(a instanceof UVar) {
13 return ua.ref = canonical(ua.ref);
20 @SuppressWarnings("unchecked")
21 public static void unify(Object a, Object b) {
26 if(a instanceof UVar) {
30 if(b instanceof UVar) {
34 if(a instanceof UPending) {
35 ((UPending)a).checkAgains(b);
38 if(b instanceof UPending) {
39 ((UPending)b).checkAgains(a);
42 if(a instanceof UCons) {
44 if(b instanceof UCons) {
46 if(ua.tag.id != ub.tag.id)
47 throw new RuntimeUnificationException();
48 unifyTuple(ua.components, ub.components);
49 ua.components = ub.components;
52 Object bComponents = ua.tag.destructor.apply(b);
53 unifyTuple(ua.components, bComponents);
54 ua.components = bComponents;
58 if(b instanceof UCons) {
60 Object aComponents = ub.tag.destructor.apply(a);
61 unifyTuple(aComponents, ub.components);
62 ub.components = aComponents;
65 if(a == null ? b != null : !a.equals(b))
66 throw new RuntimeUnificationException();
71 public static void unifyTuple(Object a, Object b) {
72 if(a instanceof Tuple) {
75 int length = ta.length();
76 for(int i=0;i<length;++i)
77 unify(ta.get(i), tb.get(i));
84 @SuppressWarnings({ "rawtypes", "unchecked" })
85 public static Object extractWithDefault(Function def, Object uni) {
86 if(uni instanceof UVar) {
89 return var.ref = extractWithDefault(def, var.ref);
92 return var.ref = def.apply(Tuple0.INSTANCE);
95 else if(uni instanceof UCons) {
96 UCons cons = (UCons)uni;
97 return cons.tag.constructor.apply(cons.components);
99 else if(uni instanceof UPending) {
100 UPending pending = (UPending)uni;
101 return pending.force();