aa
HM4.java
Go to the documentation of this file.
1 package com.cliffc.aa.HM;
2 
3 import com.cliffc.aa.type.*;
4 import com.cliffc.aa.util.*;
5 import org.jetbrains.annotations.NotNull;
6 
7 import java.util.HashMap;
8 
9 // Hindley-Milner typing. Complete stand-alone, for research. MEETs base
10 // types, instead of declaring type error. Requires SSA renumbering; looks
11 // 'up' the Syntax tree for variables instead of building a 'nongen' set.
12 //
13 // T2 types form a Lattice, with 'unify' same as 'meet'. T2's form a DAG
14 // (cycles if i allow recursive unification) with sharing. Each Syntax has a
15 // T2, and the forest of T2s can share. Leaves of a T2 can be either a simple
16 // concrete base type, or a sharable leaf. Unify is structural, and where not
17 // unifyable the union is replaced with an Error.
18 
19 public class HM4 {
20  static final HashMap<String,T2> PRIMS = new HashMap<>();
21 
22  public static T2 hm( Syntax prog) {
23  Ary<Syntax> work = new Ary<>(Syntax.class);
24 
25  // Simple types
26  T2 bool = T2.base(TypeInt.BOOL);
27  T2 int64 = T2.base(TypeInt.INT64);
28  T2 flt64 = T2.base(TypeFlt.FLT64);
29  T2 strp = T2.base(TypeMemPtr.STRPTR);
30 
31  // Primitives
32  T2 var1 = T2.tnew();
33  T2 var2 = T2.tnew();
34 
35  PRIMS.put("pair" ,T2.fresh("TOP",T2.fun(var1, T2.fun(var2, T2.prim("pair" ,var1,var2)))));
36  PRIMS.put("pair2",T2.fresh("TOP",T2.fun(var1, var2, T2.prim("pair2",var1,var2) )));
37 
38  //PRIMS.put("if/else" ,new HMT(T2.fun(bool,T2.fun(var1,T2.fun(var1,var1)))));
39  PRIMS.put("if/else3",T2.fresh("TOP",T2.fun(bool,var1,var1,var1)));
40 
41  PRIMS.put("dec",T2.fresh("TOP",T2.fun(int64,int64)));
42  PRIMS.put("*" ,T2.fresh("TOP",T2.fun(int64,T2.fun(int64,int64))));
43  PRIMS.put("*2" ,T2.fresh("TOP",T2.fun(int64,int64,int64)));
44  PRIMS.put("==0",T2.fresh("TOP",T2.fun(int64,bool)));
45  PRIMS.put("isempty",T2.fresh("TOP",T2.fun(strp,bool)));
46 
47  // Print a string; int->str
48  PRIMS.put("str",T2.fresh("TOP",T2.fun(int64,strp)));
49  // Factor; FP div/mod-like operation
50  PRIMS.put("factor",T2.fresh("TOP",T2.fun(flt64,T2.prim("divmod",flt64,flt64))));
51 
52  // Prep for SSA: pre-gather all the (unique) ids
53  prog.prep_tree(null,work);
54 
55  int cnt=0;
56  while( !work.isEmpty() ) { // While work
57  Syntax syn = work.del(cnt%work._len); // Get work
58  T2 t = syn.hm(work); // Get work results
59  T2 tsyn = syn.find();
60  if( t!=tsyn ) { // Progress?
61  assert !t.progress(tsyn); // monotonic: unifying with the result is no-progress
62  syn._t=t; // Progress!
63  if( syn._par !=null ) work.push(syn._par); // Parent updates
64  }
65  // VERY EXPENSIVE ASSERT: O(n^2). Every Syntax that makes progress is on the worklist
66  //assert prog.more_work(work);
67  cnt++;
68  }
69  assert prog.more_work(work);
70  return prog._t;
71  }
72  static void reset() { PRIMS.clear(); T2.reset(); }
73 
74  public static abstract class Syntax {
76  T2 _t; // Current HM type
77  T2 find() { // U-F find
78  T2 t = _t.find();
79  return t==_t ? t : (_t=t);
80  }
81 
82  // Compute a new HM type, without modification of any existing T2 in any Syntax
83  abstract T2 hm(Ary<Syntax> work);
84 
85  abstract void prep_tree(Syntax par,Ary<Syntax> work);
86  void prep_tree_impl( Syntax par, T2 t, Ary<Syntax> work ) { _par=par; _t=t; work.push(this); }
87  T2 prep_tree_lookup(String name, Syntax prior) { return null; }
88 
89  // Giant Assert: True if OK; all Syntaxs off worklist do not make progress
90  abstract boolean more_work(Ary<Syntax> work);
91  final boolean more_work_impl(Ary<Syntax> work) {
92  if( work.find(this)!=-1 ) return true; // On worklist, so ok
93  // Check does not make progress
94  int old = T2.CNT; int olen = work._len;
95  boolean more_work;
96  try {
97  T2 t = find();
98  Type con = t._con;
99  T2 hm = hm(null); // Run H-M, with null work, looking for progress
100  T2 un = find().unify(hm,null);
101  more_work = t!=un || con!=un._con || work._len!=olen; // Something happened?
102  assert !more_work;
103  } catch( RuntimeException no_unify ) { more_work=true; } // Fail to unify assert is progress
104  if( !more_work ) T2.CNT=old; // Reset if no error; prevents assert from endlessly raising CNT
105  return !more_work;
106  }
107  // Print for debugger
108  @Override final public String toString() { return str(new SB()).toString(); }
109  abstract SB str(SB sb);
110  // Line-by-line print with more detail
111  public String p() { return p0(new SB(), new VBitSet()).toString(); }
112  final SB p0(SB sb, VBitSet dups) {
113  _t.get_dups(dups);
114  _t.str(p1(sb.i()).p(" "), new VBitSet(),dups).nl();
115  return p2(sb.ii(1),dups).di(1);
116  }
117  abstract SB p1(SB sb); // Self short print
118  abstract SB p2(SB sb, VBitSet dups); // Recursion print
119  abstract void live(IBitSet visit);
120  }
121 
122  public static class Con extends Syntax {
123  final Type _con;
124  Con(Type con) { super(); _con=con; }
125  @Override SB str(SB sb) { return p1(sb); }
126  @Override SB p1(SB sb) { return sb.p(_con instanceof TypeMemPtr ? "str" : _con.toString()); }
127  @Override SB p2(SB sb, VBitSet dups) { return sb; }
128  @Override T2 hm(Ary<Syntax> work) { return find(); }
129  @Override void prep_tree( Syntax par, Ary<Syntax> work ) { prep_tree_impl(par, T2.base(_con), work); }
130  @Override boolean more_work(Ary<Syntax> work) { return more_work_impl(work); }
131  @Override void live(IBitSet visit) {if( _t!=null ) _t.live(visit);}
132  }
133 
134  public static class Ident extends Syntax {
135  final String _name;
136  Ident(String name) { _name=name; }
137  @Override SB str(SB sb) { return p1(sb); }
138  @Override SB p1(SB sb) { return sb.p(_name); }
139  @Override SB p2(SB sb, VBitSet dups) { return sb; }
140  @Override T2 hm(Ary<Syntax> work) { return find(); }
141  @Override void prep_tree( Syntax par, Ary<Syntax> work ) {
142  // Find Ident in some lexical scope. Get a T2 for it.
143  T2 t=null;
144  for( Syntax syn = par, prior=this; syn!=null; prior=syn, syn=syn._par )
145  if( (t = syn.prep_tree_lookup(_name,prior)) !=null )
146  break;
147  if( t==null ) t = PRIMS.get(_name); // Check prims; always FRESH
148  if( t==null ) throw new RuntimeException("Parse error, "+_name+" is undefined");
149  prep_tree_impl(par,t,work);
150  }
151  @Override boolean more_work(Ary<Syntax> work) { return more_work_impl(work); }
152  @Override void live(IBitSet visit) {if( _t!=null ) _t.live(visit);}
153  }
154 
155  public static class Lambda extends Syntax {
156  final String _arg0;
157  final Syntax _body;
159  Lambda(String arg0, Syntax body) { _arg0=arg0; _body=body; _targ = T2.tnew(); }
160  @Override SB str(SB sb) { return _body.str(sb.p("{ ").p(_arg0).p(" -> ")).p(" }"); }
161  @Override SB p1(SB sb) { return sb.p("{ ").p(_arg0).p(" -> ... } "); }
162  @Override SB p2(SB sb, VBitSet dups) { return _body.p0(sb,dups); }
163  T2 targ() { T2 targ = _targ.find(); return targ==_targ ? targ : (_targ=targ); }
164  @Override T2 hm(Ary<Syntax> work) {
165  assert !targ().is_fresh();
166  // The normal lambda work
167  T2 fun = T2.fun(targ(),_body.find());
168  // Force forwards progress; an Apply may already have lifted _t to
169  // something better than just a plain fun wrapper.
170  return find().unify(fun,work);
171  }
172  @Override void prep_tree( Syntax par, Ary<Syntax> work ) {
173  prep_tree_impl(par,T2.tnew(),work);
174  _body.prep_tree(this,work);
175  }
176  // If found name, inside a Lambda so NOT fresh
177  @Override T2 prep_tree_lookup(String name, Syntax prior) { return Util.eq(_arg0,name) ? _targ : null; }
178  @Override boolean more_work(Ary<Syntax> work) {
179  if( !more_work_impl(work) ) return false;
180  return _body.more_work(work);
181  }
182  @Override void live(IBitSet visit) {
183  if( _t!=null ) _t.live(visit);
184  _targ.live(visit);
185  _body.live(visit);
186  }
187  }
188 
189  public static class Lambda2 extends Syntax {
190  final String _arg0, _arg1;
191  final Syntax _body;
194  Lambda2(String arg0, String arg1, Syntax body) { _arg0=arg0; _arg1 = arg1; _body=body; _targ0 = T2.tnew(); _targ1 = T2.tnew(); }
195  @Override SB str(SB sb) { return _body.str(sb.p("{ ").p(_arg0).p(" ").p(_arg1).p(" -> ")).p(" }"); }
196  @Override SB p1(SB sb) { return sb.p("{ ").p(_arg0).p(" ").p(_arg1).p(" -> ... } "); }
197  @Override SB p2(SB sb, VBitSet dups) { return _body.p0(sb,dups); }
198  T2 targ0() { T2 targ = _targ0.find(); return targ==_targ0 ? targ : (_targ0=targ); }
199  T2 targ1() { T2 targ = _targ1.find(); return targ==_targ1 ? targ : (_targ1=targ); }
200  @Override T2 hm(Ary<Syntax> work) {
201  // The normal lambda work
202  T2 fun = T2.fun(targ0(),targ1(),_body.find());
203  // Force forwards progress; an Apply may already have lifted _t to
204  // something better than just a plain fun wrapper.
205  return find().unify(fun,work);
206  }
207  @Override void prep_tree( Syntax par, Ary<Syntax> work ) {
208  prep_tree_impl(par,T2.tnew(),work);
209  _body.prep_tree(this,work);
210  }
211  // If found name, inside a Lambda so NOT fresh
212  @Override T2 prep_tree_lookup(String name, Syntax prior) {
213  if( Util.eq(_arg0,name) ) return _targ0;
214  if( Util.eq(_arg1,name) ) return _targ1;
215  return null;
216  }
217  @Override boolean more_work(Ary<Syntax> work) {
218  if( !more_work_impl(work) ) return false;
219  return _body.more_work(work);
220  }
221  @Override void live(IBitSet visit) {
222  if( _t!=null ) _t.live(visit);
223  _targ0.live(visit);
224  _targ1.live(visit);
225  _body .live(visit);
226  }
227  }
228 
229  public static class Let extends Syntax {
230  final String _arg0;
231  final Syntax _body, _use;
233  Let(String arg0, Syntax body, Syntax use) { _arg0=arg0; _body=body; _use=use; _targ=T2.tnew(); }
234  @Override SB str(SB sb) { return _use.str(_body.str(sb.p("let ").p(_arg0).p(" = ")).p(" in ")); }
235  @Override SB p1(SB sb) { return sb.p("let ").p(_arg0).p(" = ... in ..."); }
236  @Override SB p2(SB sb, VBitSet dups) { _body.p0(sb,dups); return _use.p0(sb,dups); }
237  T2 targ() { T2 targ = _targ.find(); return targ==_targ ? targ : (_targ=targ); }
238  @Override T2 hm(Ary<Syntax> work) {
239  _use.find().push_update(this);
240  targ().unify(_body.find(),work);
241  return _use.find();
242  }
243  @Override void prep_tree( Syntax par, Ary<Syntax> work ) {
244  prep_tree_impl(par,T2.tnew(),work);
245  _body.prep_tree(this,work);
246  _use .prep_tree(this,work);
247  }
248  @Override T2 prep_tree_lookup(String name, Syntax prior) {
249  return Util.eq(_arg0,name)
250  // Let _body, NOT fresh; Let _use, YES fresh
251  ? (prior==_use ? T2.fresh(name,_targ) : _targ)
252  : null; // Missed on name
253  }
254 
255  @Override boolean more_work(Ary<Syntax> work) {
256  if( !more_work_impl(work) ) return false;
257  return _body.more_work(work) && _use.more_work(work);
258  }
259  @Override void live(IBitSet visit) {
260  if( _t!=null ) _t.live(visit);
261  _targ.live(visit);
262  _body.live(visit);
263  _use .live(visit);
264  }
265  }
266 
267  public static class Apply extends Syntax {
268  final Syntax _fun;
269  final Syntax[] _args;
270  Apply(Syntax fun, Syntax... args) { _fun = fun; _args = args; }
271  @Override SB str(SB sb) {
272  _fun.str(sb.p("(")).p(" ");
273  for( Syntax arg : _args )
274  arg.str(sb).p(" ");
275  return sb.unchar().p(")");
276  }
277  @Override SB p1(SB sb) { return sb.p("(...)"); }
278  @Override SB p2(SB sb, VBitSet dups) {
279  _fun.p0(sb,dups);
280  for( Syntax arg : _args ) arg.p0(sb,dups);
281  return sb;
282  }
283 
284  @Override T2 hm(Ary<Syntax> work) {
285  T2 tfun = _fun.find();
286  if( tfun.is_fresh() )
287  tfun.get_fresh().push_update(this);
288  T2[] targs = new T2[_args.length+1];
289  for( int i=0; i<_args.length; i++ )
290  targs[i] = _args[i].find();
291  // if testing, allow progress on the last new result tvar....
292  targs[_args.length] = Util.eq(tfun._name,"->") && work==null ? tfun.find(tfun._args.length-1) : T2.tnew(); // Return is new unconstrained T2
293  T2 nfun = T2.fun(targs);
294  T2 ufun = tfun.unify(nfun,work);
295  if( _fun.find()!=tfun && work!=null ) work.push(_fun);
296  // Return last element
297  T2 trez = ufun.find(_args.length);
298  // Force forward progress
299  return trez.unify(find(),work);
300  }
301  @Override void prep_tree(Syntax par,Ary<Syntax> work) {
302  prep_tree_impl(par,T2.tnew(),work);
303  _fun.prep_tree(this,work);
304  for( Syntax arg : _args ) arg.prep_tree(this,work);
305  }
306  @Override boolean more_work(Ary<Syntax> work) {
307  if( !more_work_impl(work) ) return false;
308  if( !_fun.more_work(work) ) return false;
309  for( Syntax arg : _args ) if( !arg.more_work(work) ) return false;
310  return true;
311  }
312  @Override void live(IBitSet visit) {
313  if( _t!=null ) _t.live(visit);
314  for( Syntax arg : _args ) arg.live(visit);
315  }
316  }
317 
318  // ---------------------------------------------------------------------
319  // T2 types form a Lattice, with 'unify' same as 'meet'. T2's form a DAG
320  // (cycles if i allow recursive unification) with sharing. Each Syntax has a
321  // T2, and the forest of T2s can share. Leaves of a T2 can be either a
322  // simple concrete base type, or a sharable leaf. Unify is structural, and
323  // where not unifyable the union is replaced with an Error.
324  public static class T2 {
325  static void reset() { CNT=0; }
326  private static int CNT=0;
327 
328  // Base constants are same as structural but using BASE.
329  // Other names are structural, eg "->" or "pair".
330  @NotNull final String _name; // name, eq "->" or "pair", or unique string for TVar leaves
331  T2 @NotNull [] _args;
332  final int _uid;
333  // If set, this is a 'fresh' T2, which means it lazily clones during
334  // unification such that it imparts its structure on the RHS but does not
335  // itself change. The args are length 1 with the U-F in slot0.
336  String _fresh;
337  // Base types carry a concrete Type
339  // Part of the incrementalization: if a fresh fcn type changes, any Applys
340  // using it might update.
342 
343  static T2 fun(T2... args) { return new T2("->",args); }
344  static T2 tnew() { return new T2("V"+CNT,new T2[1]); }
345  static T2 base(Type con) { T2 t = tnew(); t._con=con; return t; }
346  static T2 prim(String name, T2... args) { return new T2(name,args); }
347  static T2 fresh(String name, T2 t) {
348  assert !t.is_fresh();
349  T2 t2 = new T2(name,t); // Points to non-fresh
350  t2._fresh=name;
351  assert t2.is_fresh();
352  return t2;
353  }
354 
355  private T2(@NotNull String name, T2 @NotNull ... args) { _name = name; _args= args; _uid=CNT++; }
356 
357  // A fresh-able type var; a simple wrapper over another type var.
358  boolean is_fresh() { assert _fresh==null || (_args.length==1 && _args[0]!=null); return _fresh!=null; }
359  // A type var, not a concrete leaf. Might be U-Fd or not.
360  boolean is_leaf () { return _name.charAt(0)=='V' && !is_base(); }
361  // Concrete primitive base
362  boolean is_base () { return _con!=null; }
363  // Is a structural type variable, neither is_leaf nor is_base
364  boolean is_tvar() { return _name.charAt(0)!='V' && _con==null; }
366  assert is_fresh();
367  T2 fun = find(0);
368  assert Util.eq(fun._name,"->");
369  return fun;
370  }
371 
372  void live(IBitSet visit) {
373  if( visit.set(_uid) ) return;
374  for( T2 t : _args ) if( t!=null ) t.live(visit);
375  }
376 
377  // U-F find
378  T2 find() {
379  if( is_tvar() ) return this; // Shortcut
380  T2 u = _args[0];
381  if( u==null ) return this; // Shortcut
382  if( u.no_uf() ) return u; // Shortcut
383  // U-F fixup
384  while( !u.is_tvar() && u._args[0]!=null ) u = u._args[0];
385  T2 v = this, v2;
386  while( !v.is_tvar() && (v2=v._args[0])!=u ) { v._args[0]=u; v = v2; }
387  return u;
388  }
389  // U-F find on the args array
390  T2 find(int i) {
391  T2 u = _args[i];
392  T2 uu = u.find();
393  return u==uu ? uu : (_args[i]=uu);
394  }
395  boolean no_uf() { return is_tvar() || _args[0]==null; }
396 
397  // U-F union; this becomes that. If 'this' was used in an Apply, re-check
398  // the Apply.
399  T2 union(T2 that, Ary<Syntax> work) {
400  assert _args[0]==null; // Cannot union twice
401  if( this==that ) return this;
402  // Worklist: put updates on the worklist for revisiting
403  if( work!=null ) work.addAll(_updates); // Re-Apply
404  // Merge update lists, for future unions
405  if( _updates != null ) {
406  if( that._updates==null ) that._updates = _updates;
407  else throw com.cliffc.aa.AA.unimpl();
408  }
409  return (_args[0] = that);
410  }
411 
412  // Structural unification. Both 'this' and t' are the same afterwards and
413  // returns the unified bit. If 'this' is 'fresh', it is cloned during
414  // unification and unchanged, only imparting its sharing structure on 't'.
415  T2 unify( T2 t, Ary<Syntax> work ) {
416  if( this==t ) return this;
417  assert no_uf() && t.no_uf();
418  assert !t.is_fresh(); // Only can lazy-clone LHS
419  if( is_fresh() ) // Peel off fresh lazy & do a fresh-unify
420  return get_fresh()._fresh_unify(new HashMap<>(),t,work);
421  // Normal unification, with side-effects
422  assert DUPS.isEmpty();
423  T2 rez = _unify(t,work);
424  DUPS.clear();
425  return rez;
426  }
427 
428  // Structural unification. Both 'this' and t' are the same afterwards and
429  // returns the unified bit.
430  static private final HashMap<Long,T2> DUPS = new HashMap<>();
431  private T2 _unify(T2 t, Ary<Syntax> work) {
432  assert no_uf() && t.no_uf();
433  if( this==t ) return this;
434  if( is_fresh() ) throw com.cliffc.aa.AA.unimpl(); // recursive fresh?
435  if( t.is_fresh() ) throw com.cliffc.aa.AA.unimpl(); // RHS is fresh?
436 
437  if( is_base() && t.is_base() ) return unify_base(t,work);
438  // two leafs union in either order, so keep lower uid
439  if( is_leaf() && t.is_leaf() && _uid<t._uid ) return t.union(this,work);
440  if( is_leaf() ) return union(t ,work);
441  if( t.is_leaf() ) return t.union(this,work);
442 
443  if( !Util.eq(_name,t._name) )
444  throw new RuntimeException("Cannot unify "+this+" and "+t);
445  if( _args==t._args ) return this; // Names are equal, args are equal
446  if( _args.length != t._args.length )
447  throw new RuntimeException("Cannot unify "+this+" and "+t);
448 
449  // Cycle check.
450  long luid = ((long)_uid<<32)|t._uid;
451  T2 rez = DUPS.get(luid), rez2;
452  if( rez!=null ) return rez; // Been there, done that
453  T2[] args = new T2[_args.length];
454  rez = rez2 = new T2(_name,args);
455  DUPS.put(luid,rez); // Close cycles
456 
457  // Structural recursion unification.
458  for( int i=0; i<_args.length; i++ )
459  args[i] = find(i)._unify(t.find(i),work);
460 
461  // Check for being equal, cyclic-ly, and return a prior if possible.
462  boolean eq0 = rez.cycle_equals(this);
463  boolean eq1 = rez.cycle_equals(t );
464  if( eq0 ) rez2 = this;
465  if( eq1 ) rez2 = t ;
466  if( eq0 && eq1 ) rez2 = _uid < t._uid ? this : t;
467  if( rez!=rez2 ) DUPS.put(luid,rez2);
468  // Return new unified T2
469  return rez2;
470  }
471 
472  private T2 fresh_base(T2 t) { t._con = _con.meet(t._con); return t; }
473  private T2 unify_base(T2 t, Ary<Syntax> work) { return union(fresh_base(t),work); }
474 
475  // Apply 'this' structure on 't'; no modifications to 'this'.
476  // 'vars' maps from the cloned LHS to the RHS replacement.
477  private T2 _fresh_unify( HashMap<T2, T2> vars, T2 t, Ary<Syntax> work ) {
478  assert no_uf() && t.no_uf();
479  assert this!=t || is_base(); // No overlap between LHS and RHS.
480  T2 prior = vars.get(this);
481  if( prior!=null ) // Been there, done that? Return prior mapping
482  return prior.find().unify(t,work);
483  assert !is_fresh(); // recursive fresh?
484  T2 rez = _fresh_unify_impl( vars, t, work );
485  vars.put(this,rez);
486  return rez;
487  }
488 
489  private T2 _fresh_unify_impl( HashMap<T2, T2> vars, T2 t, Ary<Syntax> work ) {
490  // RHS is also a lazy clone, which if cloned, will not be part of any
491  // other structure. When unioned with the clone of the LHS, the result
492  // is not part of anything direct... but the structures still have to
493  // align for the returned T2. Make a replica & unify (e.g. stop being lazy).
494  if( t.is_fresh() ) t = t.get_fresh().repl(vars, new HashMap<>());
495 
496  if( is_base() && t.is_base() ) return fresh_base(t);
497  if( is_leaf() ) return t; // Lazy map LHS tvar to RHS
498  if( t.is_leaf() ) return t.union(repl(vars, new HashMap<>()),work); // RHS is a tvar; union with a copy of LHS
499 
500  if( !Util.eq(_name,t._name) )
501  throw com.cliffc.aa.AA.unimpl(); // unification error
502  if( _args.length != t._args.length )
503  throw new RuntimeException("Cannot unify "+this+" and "+t);
504  // Structural recursion unification, lazy on LHS
505  T2[] args = new T2[_args.length];
506  for( int i=0; i<_args.length; i++ )
507  args[i] = find(i)._fresh_unify(vars,t.find(i),work);
508 
509  return new T2(_name,args);
510  }
511 
512  // Replicate LHS, replacing vars as they appear
513  T2 repl(HashMap<T2,T2> vars, HashMap<T2,T2> dups) {
514  assert no_uf() && !is_fresh();
515  T2 t = vars.get(this);
516  if( t!=null ) return t; // Been there, done that, return prior answer
517  T2 rez = _repl(vars,dups);
518  vars.put(this,rez);
519  return rez;
520  }
521  T2 _repl(HashMap<T2,T2> vars, HashMap<T2,T2> dups) {
522  if( is_leaf() ) return tnew(); // LHS is a leaf, make a new one for RHS
523 
524  // Must replicate base's, because they are not really immutable:
525  // mismatched Types meet instead of error.
526  if( is_base() ) return base(_con);
527  T2[] args = new T2[_args.length];
528  T2 rez = new T2(_name,args);
529  vars.put(this,rez); // Insert in dups BEFORE structural recursion, to stop cycles
530  // Structural recursion replicate
531  for( int i=0; i<_args.length; i++ )
532  args[i] = find(i).repl(vars,dups);
533  return rez;
534  }
535 
536  // Structural unification, except return true if ever LHS progress
537  boolean progress(T2 t) {
538  assert no_uf() && t.no_uf();
539  if( this==t ) return false;
540  if( t.is_leaf() ) return false; // will be equal after unify
541  if( is_base() && t.is_base() && _con==t._con ) return false;
542  if( is_fresh() ) return get_fresh().progress(t);
543  if( !Util.eq(_name,t._name) || _args.length!=t._args.length )
544  return true; // Blatantly not-equal
545  for( int i=0; i<_args.length; i++ )
546  if( find(i).progress(t.find(i)) )
547  return true; // Recursive progress
548  return false;
549  }
550 
551  static private final HashMap<T2,T2> CDUPS = new HashMap<>();
552  boolean cycle_equals(T2 t) {
553  assert CDUPS.isEmpty();
554  boolean rez = _cycle_equals(t);
555  CDUPS.clear();
556  return rez;
557  }
558  boolean _cycle_equals(T2 t) {
559  assert no_uf() && t.no_uf();
560  if( this==t ) return true;
561  if( !is_tvar() || !t.is_tvar() || // Base-cases have to be completely identical
562  !Util.eq(_name,t._name) || // Wrong type-var names
563  _args.length != t._args.length ) // Mismatched sizes
564  return false;
565  if( _args==t._args ) return true;
566  // Cycles stall the equal/unequal decision until we see a difference.
567  T2 tc = CDUPS.get(this);
568  if( tc!=null )
569  return tc==t; // Cycle check; true if both cycling the same
570  CDUPS.put(this,t);
571  for( int i=0; i<_args.length; i++ )
572  if( !find(i)._cycle_equals(t.find(i)) )
573  return false;
574  return true;
575  }
576 
577  // This is a T2 function that is the target of 'fresh', i.e., this function
578  // might be fresh-unified with some other function. Push the application
579  // down the function parts; if any changes the fresh-application may make
580  // progress.
581  static final VBitSet UPDATE_VISIT = new VBitSet();
583  private void push_update_impl(Syntax a) {
584  assert no_uf();
585  if( is_leaf() ) {
586  if( _updates==null ) _updates = new Ary<>(Syntax.class);
587  if( _updates.find(a)==-1 ) _updates.push(a);
588  } else if( is_tvar() ) {
589  if( UPDATE_VISIT.tset(_uid) ) return;
590  for( int i=0; i<_args.length; i++ )
591  find(i).push_update_impl(a);
592  } else assert is_base();
593  }
594 
595  // -----------------
596  // Glorious Printing
597 
598  // Look for dups, in a tree or even a forest (which Syntax.p() does)
599  VBitSet get_dups(VBitSet dups) { return _get_dups(new VBitSet(),dups); }
601  if( visit.tset(_uid) && no_uf() ) dups.set(_uid);
602  else
603  for( T2 t : _args )
604  if( t!=null )
605  t._get_dups(visit,dups);
606  return dups;
607  }
608 
609  // Fancy print for Debuggers - includes explicit U-F re-direction.
610  // Does NOT roll-up U-F, has no side-effects.
611  @Override public String toString() { return str(new SB(), new VBitSet(), get_dups(new VBitSet()) ).toString(); }
612  SB str(SB sb, VBitSet visit, VBitSet dups) {
613  if( is_fresh() ) return _args[0].str(sb.p('#'),visit,dups);
614  if( is_leaf() || is_base() ) {
615  if( is_base() ) sb.p(_con instanceof TypeMemPtr ? "str" : _con.toString()); else sb.p(_name);
616  return _args[0]==null ? sb : _args[0].str(sb.p(">>"), visit, dups);
617  }
618  boolean dup = dups.get(_uid);
619  if( dup ) sb.p('$').p(_uid);
620  if( visit.tset(_uid) && dup ) return sb;
621  if( dup ) sb.p(':');
622 
623  if( _name.equals("->") ) {
624  sb.p("{ ");
625  for( int i=0; i<_args.length-1; i++ )
626  str(sb,visit,_args[i],dups).p(" ");
627  return str(sb.p("-> "),visit,_args[_args.length-1],dups).p(" }");
628  }
629  // Generic structural T2
630  sb.p("(").p(_name).p(" ");
631  for( T2 t : _args ) str(sb,visit,t,dups).p(" ");
632  return sb.unchar().p(")");
633  }
634  static private SB str(SB sb, VBitSet visit, T2 t, VBitSet dups) { return t==null ? sb.p("_") : t.str(sb,visit,dups); }
635 
636  // Same as toString but calls find(). Can thus side-effect & roll-up U-Fs, so not a toString
637  public String p() { return p(get_dups(new VBitSet())); }
638  String p(VBitSet dups) { return find()._p(new SB(), new VBitSet(), dups).toString(); }
639  private SB _p(SB sb, VBitSet visit, VBitSet dups) {
640  assert no_uf();
641  if( is_fresh() ) return get_fresh()._p(sb.p('#'),visit,dups);
642  if( is_base() ) return sb.p(_con instanceof TypeMemPtr ? "str" : _con.toString() );
643  if( is_leaf() ) return sb.p(_name);
644  boolean dup = dups.get(_uid);
645  if( dup ) sb.p('$').p(_uid);
646  if( visit.tset(_uid) && dup ) return sb;
647  if( dup ) sb.p(':');
648  if( _name.equals("->") ) {
649  sb.p("{ ");
650  for( int i=0; i<_args.length-1; i++ )
651  find(i)._p(sb,visit,dups).p(" ");
652  return find(_args.length-1)._p(sb.p("-> "),visit,dups).p(" }");
653  }
654  // Generic structural T2
655  sb.p("(").p(_name).p(" ");
656  for( int i=0; i<_args.length; i++ ) find(i)._p(sb,visit,dups).p(" ");
657  return sb.unchar().p(")");
658  }
659  }
660 
661 }
com.cliffc.aa.HM.HM4.T2.base
static T2 base(Type con)
Definition: HM4.java:345
com.cliffc.aa.HM.HM4.Lambda2.p2
SB p2(SB sb, VBitSet dups)
Definition: HM4.java:197
com.cliffc.aa.HM.HM4.Lambda2._body
final Syntax _body
Definition: HM4.java:191
com.cliffc.aa.HM.HM4.Lambda2.prep_tree
void prep_tree(Syntax par, Ary< Syntax > work)
Definition: HM4.java:207
com.cliffc.aa.HM.HM4.T2.str
SB str(SB sb, VBitSet visit, VBitSet dups)
Definition: HM4.java:612
com.cliffc.aa.HM.HM4.T2.p
String p()
Definition: HM4.java:637
com.cliffc.aa.HM.HM4.Syntax
Definition: HM4.java:74
com.cliffc.aa.HM.HM4.Apply.p1
SB p1(SB sb)
Definition: HM4.java:277
com.cliffc.aa.HM.HM4.T2.p
String p(VBitSet dups)
Definition: HM4.java:638
com.cliffc.aa.HM.HM4.T2
Definition: HM4.java:324
com.cliffc.aa.HM.HM4.Lambda2.targ0
T2 targ0()
Definition: HM4.java:198
com.cliffc.aa.util.Ary.push
E push(E e)
Add element in amortized constant time.
Definition: Ary.java:58
com.cliffc.aa.HM.HM4.Lambda2
Definition: HM4.java:189
com.cliffc.aa.util.Ary.isEmpty
boolean isEmpty()
Definition: Ary.java:20
com.cliffc.aa.HM.HM4.T2._p
SB _p(SB sb, VBitSet visit, VBitSet dups)
Definition: HM4.java:639
com.cliffc.aa.HM.HM4.reset
static void reset()
Definition: HM4.java:72
com.cliffc.aa.HM.HM4.Ident._name
final String _name
Definition: HM4.java:135
com.cliffc.aa.HM.HM4.T2.push_update
void push_update(Syntax a)
Definition: HM4.java:582
com.cliffc.aa.util.Util.eq
static boolean eq(String s0, String s1)
Definition: Util.java:16
com.cliffc.aa.HM.HM4.T2.union
T2 union(T2 that, Ary< Syntax > work)
Definition: HM4.java:399
com.cliffc.aa.util.SB.ii
SB ii(int i)
Definition: SB.java:44
com.cliffc.aa.HM.HM4.T2.progress
boolean progress(T2 t)
Definition: HM4.java:537
com.cliffc.aa.HM.HM4.T2.reset
static void reset()
Definition: HM4.java:325
com.cliffc
com.cliffc.aa.type.Type.toString
final String toString()
Definition: Type.java:127
com.cliffc.aa.util.SB.di
SB di(int i)
Definition: SB.java:46
com.cliffc.aa.HM.HM4.Syntax.prep_tree_impl
void prep_tree_impl(Syntax par, T2 t, Ary< Syntax > work)
Definition: HM4.java:86
com.cliffc.aa.HM.HM4.Ident
Definition: HM4.java:134
com.cliffc.aa.HM.HM4.Con.live
void live(IBitSet visit)
Definition: HM4.java:131
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.HM.HM4.Apply.hm
T2 hm(Ary< Syntax > work)
Definition: HM4.java:284
com.cliffc.aa.HM.HM4.Syntax.toString
final String toString()
Definition: HM4.java:108
com.cliffc.aa.HM.HM4.Syntax.hm
abstract T2 hm(Ary< Syntax > work)
com.cliffc.aa.HM.HM4
Definition: HM4.java:19
com.cliffc.aa.type.TypeInt
Definition: TypeInt.java:9
com.cliffc.aa.HM.HM4.Con.more_work
boolean more_work(Ary< Syntax > work)
Definition: HM4.java:130
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.type.TypeFlt
Definition: TypeFlt.java:9
com.cliffc.aa.util.Ary
Definition: Ary.java:11
com.cliffc.aa.HM.HM4.T2.prim
static T2 prim(String name, T2... args)
Definition: HM4.java:346
com.cliffc.aa.HM.HM4.Ident.prep_tree
void prep_tree(Syntax par, Ary< Syntax > work)
Definition: HM4.java:141
com.cliffc.aa.HM.HM4.Let.more_work
boolean more_work(Ary< Syntax > work)
Definition: HM4.java:255
com.cliffc.aa.util.Ary._len
int _len
Definition: Ary.java:13
com.cliffc.aa.HM.HM4.Lambda2._arg1
final String _arg1
Definition: HM4.java:190
com.cliffc.aa.HM.HM4.Apply.str
SB str(SB sb)
Definition: HM4.java:271
com.cliffc.aa.HM.HM4.Let._arg0
final String _arg0
Definition: HM4.java:230
com.cliffc.aa.HM.HM4.Con.str
SB str(SB sb)
Definition: HM4.java:125
com.cliffc.aa.HM.HM4.Apply.Apply
Apply(Syntax fun, Syntax... args)
Definition: HM4.java:270
com.cliffc.aa.HM.HM4.T2.is_leaf
boolean is_leaf()
Definition: HM4.java:360
com.cliffc.aa.util.IBitSet
Definition: IBitSet.java:10
com.cliffc.aa.type.Type.meet
final Type meet(Type t)
Definition: Type.java:412
com.cliffc.aa.HM.HM4.T2.T2
T2(@NotNull String name, T2 @NotNull ... args)
Definition: HM4.java:355
com.cliffc.aa.AA.unimpl
static RuntimeException unimpl()
Definition: AA.java:10
com.cliffc.aa.HM.HM4.Lambda.str
SB str(SB sb)
Definition: HM4.java:160
com.cliffc.aa.HM.HM4.T2._unify
T2 _unify(T2 t, Ary< Syntax > work)
Definition: HM4.java:431
com.cliffc.aa.HM.HM4.T2.get_dups
VBitSet get_dups(VBitSet dups)
Definition: HM4.java:599
com.cliffc.aa.HM.HM4.Con.prep_tree
void prep_tree(Syntax par, Ary< Syntax > work)
Definition: HM4.java:129
com.cliffc.aa.HM.HM4.Con.Con
Con(Type con)
Definition: HM4.java:124
com.cliffc.aa.HM.HM4.Lambda2.targ1
T2 targ1()
Definition: HM4.java:199
com.cliffc.aa.HM.HM4.Lambda2.more_work
boolean more_work(Ary< Syntax > work)
Definition: HM4.java:217
com.cliffc.aa.util.SB.unchar
SB unchar()
Definition: SB.java:58
com.cliffc.aa.HM.HM4.Apply._fun
final Syntax _fun
Definition: HM4.java:268
com.cliffc.aa.util.VBitSet.tset
boolean tset(int idx)
Definition: VBitSet.java:7
com.cliffc.aa.HM.HM4.Con.p2
SB p2(SB sb, VBitSet dups)
Definition: HM4.java:127
com.cliffc.aa.HM.HM4.Syntax.more_work
abstract boolean more_work(Ary< Syntax > work)
com.cliffc.aa.type.TypeInt.INT64
static final TypeInt INT64
Definition: TypeInt.java:39
com.cliffc.aa.HM.HM4.Lambda2.live
void live(IBitSet visit)
Definition: HM4.java:221
com.cliffc.aa.HM.HM4.T2.get_fresh
T2 get_fresh()
Definition: HM4.java:365
com.cliffc.aa.HM.HM4.Let._use
final Syntax _use
Definition: HM4.java:231
com.cliffc.aa.HM.HM4.Let.p1
SB p1(SB sb)
Definition: HM4.java:235
com.cliffc.aa.HM.HM4.Lambda.hm
T2 hm(Ary< Syntax > work)
Definition: HM4.java:164
com.cliffc.aa.HM.HM4.T2.toString
String toString()
Definition: HM4.java:611
com.cliffc.aa.HM.HM4.Ident.hm
T2 hm(Ary< Syntax > work)
Definition: HM4.java:140
com.cliffc.aa.HM.HM4.Lambda.more_work
boolean more_work(Ary< Syntax > work)
Definition: HM4.java:178
com.cliffc.aa.HM.HM4.Ident.Ident
Ident(String name)
Definition: HM4.java:136
com.cliffc.aa.HM.HM4.T2.fresh_base
T2 fresh_base(T2 t)
Definition: HM4.java:472
com.cliffc.aa.HM.HM4.T2.tnew
static T2 tnew()
Definition: HM4.java:344
com.cliffc.aa.HM.HM4.Apply.p2
SB p2(SB sb, VBitSet dups)
Definition: HM4.java:278
com.cliffc.aa.HM.HM4.Syntax.prep_tree_lookup
T2 prep_tree_lookup(String name, Syntax prior)
Definition: HM4.java:87
com.cliffc.aa.HM.HM4.Syntax.p2
abstract SB p2(SB sb, VBitSet dups)
com.cliffc.aa.HM.HM4.Ident.p2
SB p2(SB sb, VBitSet dups)
Definition: HM4.java:139
com.cliffc.aa.HM.HM4.Lambda2._targ1
T2 _targ1
Definition: HM4.java:193
com.cliffc.aa.HM.HM4.Let.str
SB str(SB sb)
Definition: HM4.java:234
com.cliffc.aa.HM.HM4.Lambda._targ
T2 _targ
Definition: HM4.java:158
com.cliffc.aa.HM.HM4.Syntax.p
String p()
Definition: HM4.java:111
com.cliffc.aa.util.Util
Definition: Util.java:5
com.cliffc.aa.HM.HM4.Lambda2.str
SB str(SB sb)
Definition: HM4.java:195
com.cliffc.aa.HM.HM4.Let.targ
T2 targ()
Definition: HM4.java:237
com.cliffc.aa.HM.HM4.T2.CDUPS
static final HashMap< T2, T2 > CDUPS
Definition: HM4.java:551
com.cliffc.aa.HM.HM4.T2.fun
static T2 fun(T2... args)
Definition: HM4.java:343
com.cliffc.aa.HM.HM4.Lambda2.p1
SB p1(SB sb)
Definition: HM4.java:196
com.cliffc.aa.HM.HM4.T2._get_dups
VBitSet _get_dups(VBitSet visit, VBitSet dups)
Definition: HM4.java:600
com.cliffc.aa.HM.HM4.Lambda._arg0
final String _arg0
Definition: HM4.java:156
com.cliffc.aa.HM.HM4.Lambda.p1
SB p1(SB sb)
Definition: HM4.java:161
com.cliffc.aa.HM.HM4.hm
static T2 hm(Syntax prog)
Definition: HM4.java:22
com.cliffc.aa.HM.HM4.Lambda2.Lambda2
Lambda2(String arg0, String arg1, Syntax body)
Definition: HM4.java:194
com.cliffc.aa.HM.HM4.Let.p2
SB p2(SB sb, VBitSet dups)
Definition: HM4.java:236
com.cliffc.aa.HM.HM4.Lambda2._arg0
final String _arg0
Definition: HM4.java:190
com.cliffc.aa.HM.HM4.T2.unify_base
T2 unify_base(T2 t, Ary< Syntax > work)
Definition: HM4.java:473
com.cliffc.aa.HM.HM4.Con._con
final Type _con
Definition: HM4.java:123
com.cliffc.aa.HM.HM4.Apply._args
final Syntax[] _args
Definition: HM4.java:269
com.cliffc.aa.HM.HM4.Apply.more_work
boolean more_work(Ary< Syntax > work)
Definition: HM4.java:306
com.cliffc.aa.HM.HM4.Let.Let
Let(String arg0, Syntax body, Syntax use)
Definition: HM4.java:233
com.cliffc.aa.HM.HM4.Syntax.find
T2 find()
Definition: HM4.java:77
com.cliffc.aa.HM.HM4.Let.prep_tree_lookup
T2 prep_tree_lookup(String name, Syntax prior)
Definition: HM4.java:248
com.cliffc.aa.HM.HM4.T2.find
T2 find(int i)
Definition: HM4.java:390
com.cliffc.aa.HM.HM4.T2.is_fresh
boolean is_fresh()
Definition: HM4.java:358
com.cliffc.aa.util.VBitSet
Definition: VBitSet.java:5
NotNull
com.cliffc.aa.util.SB
Tight/tiny StringBuilder wrapper.
Definition: SB.java:8
com.cliffc.aa.HM.HM4.T2.UPDATE_VISIT
static final VBitSet UPDATE_VISIT
Definition: HM4.java:581
com.cliffc.aa.HM.HM4.T2._cycle_equals
boolean _cycle_equals(T2 t)
Definition: HM4.java:558
com.cliffc.aa.HM.HM4.Apply
Definition: HM4.java:267
com.cliffc.aa.HM.HM4.T2.push_update_impl
void push_update_impl(Syntax a)
Definition: HM4.java:583
com.cliffc.aa.HM.HM4.T2._fresh
String _fresh
Definition: HM4.java:336
com.cliffc.aa.HM.HM4.T2._repl
T2 _repl(HashMap< T2, T2 > vars, HashMap< T2, T2 > dups)
Definition: HM4.java:521
com.cliffc.aa.AA
an implementation of language AA
Definition: AA.java:9
com.cliffc.aa.HM.HM4.Lambda.live
void live(IBitSet visit)
Definition: HM4.java:182
com.cliffc.aa.HM.HM4.Lambda
Definition: HM4.java:155
com.cliffc.aa.HM.HM4.T2.fresh
static T2 fresh(String name, T2 t)
Definition: HM4.java:347
com.cliffc.aa.HM.HM4.Lambda.Lambda
Lambda(String arg0, Syntax body)
Definition: HM4.java:159
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.HM.HM4.Lambda.prep_tree_lookup
T2 prep_tree_lookup(String name, Syntax prior)
Definition: HM4.java:177
com.cliffc.aa.util.SB.nl
SB nl()
Definition: SB.java:48
com.cliffc.aa.HM.HM4.Lambda.p2
SB p2(SB sb, VBitSet dups)
Definition: HM4.java:162
com.cliffc.aa.HM.HM4.Let.prep_tree
void prep_tree(Syntax par, Ary< Syntax > work)
Definition: HM4.java:243
com.cliffc.aa.HM.HM4.T2.find
T2 find()
Definition: HM4.java:378
com.cliffc.aa.HM.HM4.Apply.live
void live(IBitSet visit)
Definition: HM4.java:312
com.cliffc.aa.HM.HM4.Ident.str
SB str(SB sb)
Definition: HM4.java:137
com.cliffc.aa.HM.HM4.Lambda._body
final Syntax _body
Definition: HM4.java:157
com.cliffc.aa.HM.HM4.Con
Definition: HM4.java:122
com.cliffc.aa.util.SB.p
SB p(String s)
Definition: SB.java:13
com.cliffc.aa.HM.HM4.T2._name
final String _name
Definition: HM4.java:330
com.cliffc.aa.HM.HM4.T2.is_base
boolean is_base()
Definition: HM4.java:362
com.cliffc.aa.HM.HM4.T2.cycle_equals
boolean cycle_equals(T2 t)
Definition: HM4.java:552
com.cliffc.aa.HM.HM4.T2._args
T2[] _args
Definition: HM4.java:331
com.cliffc.aa.HM.HM4.T2.live
void live(IBitSet visit)
Definition: HM4.java:372
com.cliffc.aa.HM.HM4.Syntax.more_work_impl
final boolean more_work_impl(Ary< Syntax > work)
Definition: HM4.java:91
com.cliffc.aa.HM.HM4.Syntax.live
abstract void live(IBitSet visit)
com.cliffc.aa.HM.HM4.Con.hm
T2 hm(Ary< Syntax > work)
Definition: HM4.java:128
com.cliffc.aa.HM.HM4.Let._targ
T2 _targ
Definition: HM4.java:232
com.cliffc.aa.HM.HM4.T2._updates
Ary< Syntax > _updates
Definition: HM4.java:341
com.cliffc.aa.HM.HM4.Lambda2.hm
T2 hm(Ary< Syntax > work)
Definition: HM4.java:200
com.cliffc.aa.HM.HM4.Lambda2.prep_tree_lookup
T2 prep_tree_lookup(String name, Syntax prior)
Definition: HM4.java:212
com.cliffc.aa.HM.HM4.T2.no_uf
boolean no_uf()
Definition: HM4.java:395
com.cliffc.aa.HM.HM4.Let._body
final Syntax _body
Definition: HM4.java:231
com.cliffc.aa.HM.HM4.Syntax.prep_tree
abstract void prep_tree(Syntax par, Ary< Syntax > work)
com.cliffc.aa.HM.HM4.Ident.live
void live(IBitSet visit)
Definition: HM4.java:152
com.cliffc.aa.HM.HM4.T2._fresh_unify_impl
T2 _fresh_unify_impl(HashMap< T2, T2 > vars, T2 t, Ary< Syntax > work)
Definition: HM4.java:489
com.cliffc.aa.HM.HM4.T2._uid
final int _uid
Definition: HM4.java:332
com.cliffc.aa.HM.HM4.Syntax._par
Syntax _par
Definition: HM4.java:75
com.cliffc.aa.util.Ary.del
E del(int i)
Fast, constant-time, element removal.
Definition: Ary.java:78
com.cliffc.aa.util.SB.i
SB i(int d)
Definition: SB.java:38
com.cliffc.aa.HM.HM4.Apply.prep_tree
void prep_tree(Syntax par, Ary< Syntax > work)
Definition: HM4.java:301
com.cliffc.aa.util.Ary.find
int find(E e)
Find the first matching element using ==, or -1 if none.
Definition: Ary.java:192
com.cliffc.aa.type.TypeMemPtr.STRPTR
static final TypeMemPtr STRPTR
Definition: TypeMemPtr.java:97
com.cliffc.aa.HM.HM4.T2.unify
T2 unify(T2 t, Ary< Syntax > work)
Definition: HM4.java:415
com.cliffc.aa.util.IBitSet.set
boolean set(int idx)
Definition: IBitSet.java:26
com.cliffc.aa.HM.HM4.Lambda.prep_tree
void prep_tree(Syntax par, Ary< Syntax > work)
Definition: HM4.java:172
com.cliffc.aa.HM.HM4.Let.hm
T2 hm(Ary< Syntax > work)
Definition: HM4.java:238
com
com.cliffc.aa.HM.HM4.T2._fresh_unify
T2 _fresh_unify(HashMap< T2, T2 > vars, T2 t, Ary< Syntax > work)
Definition: HM4.java:477
com.cliffc.aa.HM.HM4.Syntax.str
abstract SB str(SB sb)
com.cliffc.aa.HM.HM4.Syntax._t
T2 _t
Definition: HM4.java:76
com.cliffc.aa.HM.HM4.T2.DUPS
static final HashMap< Long, T2 > DUPS
Definition: HM4.java:430
com.cliffc.aa.type.TypeInt.BOOL
static final TypeInt BOOL
Definition: TypeInt.java:43
com.cliffc.aa.HM.HM4.Let
Definition: HM4.java:229
com.cliffc.aa.util.SB.toString
String toString()
Definition: SB.java:62
com.cliffc.aa.HM.HM4.T2.CNT
static int CNT
Definition: HM4.java:326
com.cliffc.aa.HM.HM4.T2._con
Type _con
Definition: HM4.java:338
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.HM.HM4.Syntax.p0
final SB p0(SB sb, VBitSet dups)
Definition: HM4.java:112
com.cliffc.aa.HM.HM4.Let.live
void live(IBitSet visit)
Definition: HM4.java:259
com.cliffc.aa.HM.HM4.T2.str
static SB str(SB sb, VBitSet visit, T2 t, VBitSet dups)
Definition: HM4.java:634
com.cliffc.aa.HM.HM4.Con.p1
SB p1(SB sb)
Definition: HM4.java:126
com.cliffc.aa.type.TypeMemPtr
Definition: TypeMemPtr.java:14
com.cliffc.aa.HM.HM4.T2.repl
T2 repl(HashMap< T2, T2 > vars, HashMap< T2, T2 > dups)
Definition: HM4.java:513
com.cliffc.aa.HM.HM4.Syntax.p1
abstract SB p1(SB sb)
com.cliffc.aa.HM.HM4.Lambda.targ
T2 targ()
Definition: HM4.java:163
com.cliffc.aa.HM.HM4.T2.is_tvar
boolean is_tvar()
Definition: HM4.java:364
com.cliffc.aa.type.TypeFlt.FLT64
static final TypeFlt FLT64
Definition: TypeFlt.java:38
com.cliffc.aa.HM.HM4.Lambda2._targ0
T2 _targ0
Definition: HM4.java:192
com.cliffc.aa.HM.HM4.Ident.p1
SB p1(SB sb)
Definition: HM4.java:138
com.cliffc.aa.HM.HM4.PRIMS
static final HashMap< String, T2 > PRIMS
Definition: HM4.java:20
com.cliffc.aa.HM.HM4.Ident.more_work
boolean more_work(Ary< Syntax > work)
Definition: HM4.java:151