aa
TestLattice.java
Go to the documentation of this file.
1 package com.cliffc.aa;
2 
3 import com.cliffc.aa.util.Ary;
4 import com.cliffc.aa.util.SB;
5 import org.junit.Test;
6 import org.junit.Ignore;
7 
8 import java.util.BitSet;
9 
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 
13 // The core Type system is a distributive complete bounded lattice.
14 // See: https://en.wikipedia.org/wiki/Lattice_(order)
15 
16 // This is a series of tests to validate various structures as lattices with
17 // the right properties, or not. A lot of "obvious" structures fail to be
18 // lattices, and that has led to a lot of failed attempts at type-inference via
19 // finding the stable meet over a "Sea of Nodes" graph.
20 
21 // While some structures are lattices and some are not, we can envision graph
22 // combinators that preserve the right properties when mixing two lattices.
23 // Mixing a non-lattice & a lattice with a combinator generally keeps the
24 // non-lattice property.
25 
26 // An example combinator is multiplying two lattices; if {A} and {B} are
27 // lattices then we can make a lattice by simple pairs of A & B elements:
28 // {(A,B)}. This happens in lots of places, e.g. structure fields or mixing
29 // fidxs (code constants) and arguments to function pointers.
30 //
31 // If {A} is a lattice, and we clone A and rename all the elements as AA, then
32 // {AA} is a lattice (simple rename). If we add edges from all the high
33 // elements of {A} to the high elements of {AA}, and low-{AA} to low-{A}, then
34 // again we have a lattice. Notice the inside-out-edge ordering. We can
35 // repeat this process to get a "chain" of lattices going however deep down the
36 // "AAAA...." rabbit-hole we like. The integers use this process for types
37 // int64,int32,int16,int8,int1.
38 //
39 // However! If we clone lattice {A} into two lattices {A0} and {A1}, each being
40 // a simple rename, and we add all the inside-out edges from {A} elements to
41 // the corresponding {A0} and seperately to {A1} - the combination is NOT a
42 // lattice. This implies, e.g. we cannot simply add "names" to a lattice and
43 // have the result be a lattice.
44 //
45 // Two make the simple-renamed-clones work, we can use a simple nested
46 // combinator: A_top >> AA_top >> AAA_top... and A_bot << AA_bot << AAA_bot but
47 // NO interior edges. Basically we can "insert" a lattice "inside" another one
48 // via taking any two symmetric elements from the "outer" lattice as having
49 // edges to the top/bot of the inner lattice. This implies that mixing
50 // elements from 2 different "inserted" lattices - even if they have a common
51 // parent insertion point - always must fall to the "bot" parent point. There
52 // cannot be any interior crossing edges! This is too weak for "names".
53 //
54 // NIL: Generally speaking we cannot have a common center constant suggestively
55 // called "nil" that is in the center of two multiplied lattices - this leads
56 // to the "crossing nil" bug referred to in the code. We CAN inject the NIL in
57 // a few places - but using it typically requires losing all the structure of
58 // one of the two multiplied lattices. We can "sign" a NIL and do a little
59 // better; the "~NIL" variant can keep structure in the "off-side" lattice.
60 // (and obviously for symmetry on "NIL" going "up" the lattice).
61 
62 // ------------
63 // So here's a thought about "names": use the pair-wise (multiplicative)
64 // combinator, and a "name" is associated with a set of fields. There is no
65 // "real" subtyping, but instead multiplicative addition of more named types
66 // and their matching fields - more like mixins than subtyping.
67 //
68 // Means there's names for ints & flts, like now. And names for "chunks" of a
69 // struct, which could be flattened - rolling the "name" into the fields.
70 // E.g. java
71 // class Point2D { int x,y; }; class Point3D extends Point 2D { int z; }
72 //
73 // Short hand Point2D:@{x;y} is syntatic sugar for: @{ Point2D:x; Point2D:y }
74 // Short hand Point3D:Point2D:@{z} is syntatic sugar for:
75 // @{ Point2D:x; Point2D:y; Point3D:z; }
76 
77 
78 
79 public class TestLattice {
80  private static class N {
81  private static int ID=0;
82  static Ary<N> NS=new Ary<>(new N[1],0);
83  static void reset() { NS.clear(); ID=0; }
84  final int _id;
85  final String _t;
86  final Ary<N> _subs;
87  final Ary<N> _sups;
88  final BitSet _reaches; // Who reaches this node, including self
89  int _cnt; // Reaches count
91  N(String t, N... subs) {
92  _id = ID++;
93  _t=t;
94  _subs = new Ary<>(subs);
95  _sups = new Ary<>(new N[1],0); // Fill in later
96  _reaches = new BitSet();
97  _dual = this;
98  NS.add(this);
99  }
100  void set_dual( N d ) {
101  assert _dual==this && d._dual==d;
102  _dual=d; d._dual=this;
103  }
104  // Setup reverse edges for later walks
105  void walk_set_sup( BitSet bs ) {
106  if( bs.get(_id) ) return;
107  bs.set(_id);
108  for( N sub : _subs ) sub._sups.add(this);
109  for( N sub : _subs ) sub.walk_set_sup(bs);
110  }
111  // top-down recursive print
112  void walk_print( BitSet bs, int indent ) {
113  if( bs.get(_id) ) return;
114  bs.set(_id);
115  System.out.println(new SB().i(indent).toString()+toString());
116  for( N sub : _subs ) sub.walk_print(bs,indent+1);
117  }
118  @Override public String toString() {
119  SB sb = new SB().p(_t).p(" -> ");
120  for( N sub : _subs ) sb.p(sub._t).p(" ");
121  return sb.toString();
122  }
123  // top-down find extra edges
124  boolean walk_min_edge( int[] vs, N sup ) {
125  vs[_id]++;
126  if( sup != null ) {
127  for( N sup0 : _sups )
128  if( sup._reaches.get(sup0._id) ) {
129  System.out.println("Edge "+sup0._t+" -> "+_t+" and also path "+sup0._t+" ... -> "+sup._t+" -> "+_t);
130  return false;
131  }
132  _reaches.or(sup._reaches);
133  }
134  if( vs[_id]<_sups._len ) return true; // Pre-order still; return
135  for( N sup0 : _sups ) _reaches.set(sup0._id); // Post-order: add all supers in
136  for( N sub : _subs ) if( !sub.walk_min_edge(vs,this) ) return false;
137  return true;
138  }
139  // Demand dual symmetry: A->B === ~B->~A
140  boolean walk_dual(BitSet bs) {
141  if( bs.get(_id) ) return true;
142  bs.set(_id);
143  boolean x=true;
144  for( N sub : _subs ) {
145  if( sub._dual._subs.find(_dual) == -1 ) {
146  System.out.println(""+_t+" -> "+sub._t+"; expect "+sub._dual._t+" -> "+_dual._t);
147  x = false;
148  }
149  }
150  for( N sub : _subs ) if( !sub.walk_dual(bs) ) x=false;
151  return x;
152  }
153  }
154 
155  // Complete the lattice and test it
156  private static void test(N top) {
157  // Fill in the reverse edges
158  top.walk_set_sup(new BitSet());
159  // Pretty print
160  top.walk_print(new BitSet(),0);
161 
162  // Find and barf redundant edges. Computes reachable.
163  assertTrue(top.walk_min_edge(new int[N.ID],null));
164  for( int i=0; i<N.ID; i++ ) {
165  N n = N.NS.at(i);
166  n._reaches.set(i); // Add self to reaches
167  n._cnt = n._reaches.cardinality();
168  }
169 
170  // Demand dual symmetry: A->B === ~B->~A
171  assertTrue(top.walk_dual(new BitSet()));
172 
173  // Check for single lowest unique meet. BAD: For all nodes, compute Reach
174  // (to Bot, and already done). For each pair of nodes compute the
175  // intersection of their reach sets; this is their common reachable set
176  // just following graph edges. The LCA will be a node with a Reach set
177  // equal to the intersection; it may not exist. If it does not, the set of
178  // nodes with the largest Reach sets make a good error message.
179  int errs=0;
180  for( N a : N.NS )
181  for( N b : N.NS ) if( a._id < b._id ) { // triangle efficiency
182  BitSet as = a._reaches;
183  BitSet bs = b._reaches;
184  N meet = null;
185  forall_reaches:
186  for( int x=as.nextSetBit(0); x>=0; x=as.nextSetBit(x+1) ) {
187  if( bs.get(x) ) {
188  N c = N.NS.at(x); // Common in both reaches sets
189  for( N sub : c._subs )
190  if( as.get(sub._id) && bs.get(sub._id) )
191  continue forall_reaches; // node is inside both a & b reaches sets, so is not unique meet
192  if( meet == null ) meet = c; // Found a unique meet point
193  else { // Found a 2nd meet point... so not unique
194  errs++;
195  System.out.println("No meet found for "+a._t+" and "+b._t+", tied candidates are: "+meet._t+" and "+c._t);
196  break;
197  }
198  }
199  }
200  }
201  assertEquals("Found errors", 0, errs);
202  }
203 
204  // Lattice!
205  // This structure is tested to be a lattice:
206 
207  // ~scalar
208  // ~num ~oop+?
209  // ~int { ~str+?, ~tup+? } -X-~oop-X-
210  // { ~str, ~tup }
211  // 42 0 { "abc", "def", @{x}, @{x,y} }
212  // { str, tup }
213  // int { str?, tup? } -X-oop-X-
214  // num oop?
215  // scalar
216 
217  // Notice NO {oop,~oop} as this makes the non-lattice issue; join of
218  // {oop,null} is not well-defined, as it tops out as either ~str+? OR ~tup+?
219  // instead of being unique. Similarly meet of {~oop,null} is not well
220  // defined, and bottoms out as either {str?} OR {tup?}.
221  @Test public void testLattice0() {
222  N.reset();
223  N scal= new N( "scalar");
224  N num = new N("num" ,scal);
225  N int8= new N("int8",num );
226 
227  N oop0= new N( "oop?",scal);
228  N str0= new N( "str?",oop0);
229  N tup0= new N( "tup?",oop0);
230  N str = new N( "str" ,str0);
231  N tup = new N( "tup" ,tup0);
232 
233  N nil = new N( "0",str0,tup0,int8);
234 
235  N abc = new N( "\"abc\"",str);
236  N def = new N( "\"def\"",str);
237  N flx = new N( "@{x}" ,tup);
238  N fly = new N( "@{y}" ,tup);
239  N strx= new N("~str" ,abc,def);
240  N tupx= new N("~tup" ,flx,fly);
241  N str_= new N("~str+0",strx,nil);
242  N tup_= new N("~tup+0",tupx,nil);
243  N oop_= new N("~oop+0",str_,tup_);
244 
245  N i3 = new N("42",int8 );
246  N xint= new N("~int8",i3,nil );
247  N xnum= new N("~num",xint);
248 
249  N xscl= new N( "~scalar",oop_,xnum);
250  // Mark the non-centerline duals
251  scal.set_dual(xscl);
252  num .set_dual(xnum);
253  int8.set_dual(xint);
254  oop0.set_dual(oop_);
255  str0.set_dual(str_);
256  tup0.set_dual(tup_);
257  str .set_dual(strx);
258  tup .set_dual(tupx);
259 
260  test(xscl);
261  }
262  // intuition: top-tuple allows all field names; prefix field names on
263  // top-struct allows more post-fix names. After falling across center,
264  // reverse: extra fields are dropped & shortened until no-names - which is a
265  // tuple. Same field names are sorted by field contents. Field contents
266  // fall independently. No center-line notion (either have a field or not)
267  // but may still be constant if the tuple is a constant.
268  // /----> ~[b]+? -\ /-> [b]? -------\ []?
269  // ~[]+? -----> ~[x]+? -> 0 -> [x]? --------> []?
270  // \-> ~[] -> ~[x] --------> [x] -> [] -/
271 
272  // Fails to be a valid lattice; same fail: MEET of 0 and ~[]+? falls to
273  // either [x]? or [b]? and "invents" fields as it falls.
274  @Ignore @Test public void testLattice1() {
275  N.reset();
276  N ta0 = new N("[]?" );
277  N tx0 = new N("[x]?" ,ta0);
278  N tb0 = new N("[b]?" ,ta0);
279  N ty0 = new N("[x,y]?",tx0);
280  N ta = new N("[]" ,ta0);
281  N tx = new N("[x]" ,ta,tx0);
282  N tb = new N("[b]" ,ta,tb0);
283  N ty = new N("[x,y]" ,tx,ty0);
284 
285  N nil = new N("0", ty0,tb0 );
286 
287  N xty = new N("~[x,y]",ty);
288  N xtx = new N("~[x]",xty);
289  N xtb = new N("~[b]",tb);
290  N xta = new N("~[]",xtx,xtb);
291 
292  N xty0= new N("~[x,y]+?",xty,nil);
293  N xtx0= new N("~[x]+?",xtx,xty0);
294  N xtb0= new N("~[b]+?",xtb,nil);
295  N xta0= new N("~[]+?",xta,xtx0,xtb0);
296 
297  // Mark the non-centerline duals
298  xta0.set_dual(ta0);
299  xtx0.set_dual(tx0);
300  xtb0.set_dual(tb0);
301  xty0.set_dual(ty0);
302  xta .set_dual(ta );
303  xtx .set_dual(tx );
304  xtb .set_dual(tb );
305  xty .set_dual(ty );
306 
307  test(xta0);
308  }
309 
310  // Lattice!
311  // This structure is tested to be a lattice:
312 
313  // back to field-by-field for structs; each tuple/struct has a {choice-null,
314  // not-null, support-null, is-null}. Each field is Top, field, Bot,
315  // replicated for all fields separately. Also, the nil choice is available
316  // for all combos; so there are lots of variations of nil. There is a lowest
317  // nil and a highest nil. Struct nil is different from int 0, and seeing a 0
318  // probably means producing a union{0[_,_]0,0:int}
319  @Test public void testLattice2() {
320  N.reset();
321  N tb0 = new N("[_,_]0" );
322  N tx0 = new N("[x,_]0" ,tb0);
323  N ty0 = new N("[y,_]0" ,tb0);
324  N tt0 = new N("[^,_]0" ,tx0,ty0);
325 
326  N tb = new N("[_,_]" ,tb0 );
327  N tx = new N("[x,_]" ,tb,tx0);
328  N ty = new N("[y,_]" ,tb,ty0);
329  N tt = new N("[^,_]" ,tx,ty,tt0);
330 
331  N bb0 = new N("[_,^]0" ,tb0);
332  N bx0 = new N("[x,^]0" ,bb0,tx0);
333  N by0 = new N("[y,^]0" ,bb0,ty0);
334  N bt0 = new N("[^,^]0" ,bx0,by0,tt0);
335 
336  // The 8 different flavors of nil...
337  N nilbb = new N("0[_,_]0",tb0);
338  N nilxb = new N("0[x,_]0",tx0);
339  N nilyb = new N("0[y,_]0",ty0);
340  N niltb = new N("0[^,_]0",tt0);
341  N nilbt = new N("0[_,^]0",bb0);
342  N nilxt = new N("0[x,^]0",bx0);
343  N nilyt = new N("0[y,^]0",by0);
344  N niltt = new N("0[^,^]0",bt0);
345  // Attempt a single nil
346  //N nil = new N("0",tb0,tx0,ty0,tt0,bb0,bx0,by0,bt0);
347  //N nilbb=nil, nilxb=nil, nilyb=nil, niltb=nil, nilbt=nil, nilxt=nil, nilyt=nil, niltt=nil;
348 
349  N tbp = new N("[_,_]+" ,tb,nilbb);
350  N txp = new N("[x,_]+" ,tbp,tx,nilxb);
351  N typ = new N("[y,_]+" ,tbp,ty,nilyb);
352  N ttp = new N("[^,_]+" ,txp,typ,tt,niltb);
353 
354  N bb = new N("[_,^]" ,tb, bb0 );
355  N bx = new N("[x,^]" ,bb,bx0,tx);
356  N by = new N("[y,^]" ,bb,by0,ty);
357  N bt = new N("[^,^]" ,bx,by,bt0,tt);
358 
359  N bbp = new N("[_,^]+" ,bb,tbp,nilbt);
360  N bxp = new N("[x,^]+" ,bbp,bx,txp,nilxt);
361  N byp = new N("[y,^]+" ,bbp,by,typ,nilyt);
362  N btp = new N("[^,^]+" ,bxp,byp,bt,ttp,niltt);
363 
364  // Mark the non-centerline duals
365  btp.set_dual(tb0);
366  byp.set_dual(ty0);
367  bxp.set_dual(tx0);
368  bbp.set_dual(tt0);
369 
370  bt .set_dual(tb );
371  bx .set_dual(tx );
372  by .set_dual(ty );
373  bb .set_dual(tt );
374 
375  nilbb.set_dual(niltt);
376  nilxb.set_dual(nilxt);
377  nilyb.set_dual(nilyt);
378  niltb.set_dual(nilbt);
379 
380  bb0.set_dual(ttp);
381  bx0.set_dual(txp);
382  by0.set_dual(typ);
383  bt0.set_dual(tbp);
384 
385  test(btp);
386  }
387 
388 
389  // Lattice!
390  // This structure is tested to be a lattice:
391 
392  // ~num
393  // M:~num N:~num
394  // ~int
395  // M:~int N:~int
396  //M:0 M:7 0 7 N:0 N:7
397  // M:int N:int
398  // int
399  // M:num N:num
400  // num
401  @Test public void testLattice3() {
402  N.reset();
403  N num = new N( "num" );
404  N nnum= new N("N:num",num);
405  N mnum= new N("M:num",num);
406  N i64= new N( "int",num );
407  N ni64= new N("N:int",i64,nnum );
408  N mi64= new N("M:int",i64,mnum );
409 
410  N i0 = new N( "0", i64);
411  N i7 = new N( "7", i64);
412  N ni0 = new N("N:0", ni64);
413  N ni7 = new N("N:7", ni64);
414  N mi0 = new N("M:0", mi64);
415  N mi7 = new N("M:7", mi64);
416 
417  N nx64= new N("N:~int",ni0,ni7 );
418  N mx64= new N("M:~int",mi0,mi7 );
419  N x64= new N( "~int",nx64,mx64, i0, i7 );
420  N nxum= new N("N:~num",nx64 );
421  N mxum= new N("M:~num",mx64 );
422  N xum= new N( "~num",nxum,mxum,x64 );
423 
424  // Mark the non-centerline duals
425  num.set_dual( xum);
426  nnum.set_dual(nxum);
427  mnum.set_dual(mxum);
428  i64.set_dual( x64);
429  ni64.set_dual(nx64);
430  mi64.set_dual(mx64);
431 
432  test(xum);
433  }
434 
435  // Not a lattice: has str? and "abc"? and "def"?
436  //
437  // ~scalar
438  // ~num ~oop+?
439  // ~str+?
440  // ~str "abc"+? "def"+?
441  // "abc" nil "def"
442  // str "abc"? "def"?
443  // str?
444  // num oop?
445  // scalar
446 
447 
448  // Lattice!
449  // This structure is tested to be a lattice:
450  // BUT: adding "def"? makes it NOT a lattice!
451 
452  // ~scalar
453  // ~num ~oop+?
454  // ~str+? ~{~int64}+?
455  // ~{~int64} ~{~int8}+?
456  // ~{~int8}
457  // ~str "abc"+? {nil}+?
458  // nil "abc" nil {nil} {7} <<-- {nil} is a constant tuple
459  // str "abc"? {nil}? <<-- Least tuple AND nil
460  // { int8}
461  // { int64} { int8}?
462  // str? { int64}?
463  // num oop?
464  // scalar
465  @Test public void testLattice4() {
466  N.reset();
467  N scal= new N("scalar");
468  N num =new N("num" ,scal);
469  N oop0= new N("oop?" ,scal);
470  N str0= new N("str?" ,oop0);
471  N i640= new N("{i64}?" ,oop0);
472  N i64 = new N("{i64}" ,i640);
473  N i80 = new N("{i8}?" ,i640);
474  N i8 = new N("{i8}" ,i80,i64);
475  N str = new N("str" ,str0);
476  N abc0= new N("abc?" ,str0);
477  N t00 = new N("{nil}?" ,i80);
478  N abc = new N("abc" ,abc0,str);
479  N t7 = new N("{7}" ,i8);
480  N t0 = new N("{nil}" ,i8,t00);
481  N nil = new N("nil" ,t00,abc0,num);
482  N abc_= new N("abc+?" ,abc,nil);
483  N t0_ = new N("{nil}+?" ,nil,t0);
484  N xstr= new N("~str" ,abc);
485  N xi8 = new N("~{~i8}" ,t0,t7);
486  N xi8_= new N("~{~i8}+?",xi8,t0_);
487  N xstr_=new N("~str+?" ,xstr,abc_);
488  N xi64= new N("~{~i64}" ,xi8);
489  N xi64_=new N("~{~i64}+?",xi64,xi8_);
490  N oop_ =new N("~oop+?" ,xi64_,xstr_);
491  N xnum =new N("~num" ,nil);
492  N xscal=new N("~scalar" ,oop_,xnum);
493 
494  // Mark the non-centerline duals
495  scal.set_dual(xscal);
496  num .set_dual(xnum );
497  oop0.set_dual( oop_);
498  str0.set_dual(xstr_);
499  i640.set_dual(xi64_);
500  i64 .set_dual(xi64 );
501  str .set_dual(xstr );
502  i80 .set_dual(xi8_ );
503  i8 .set_dual(xi8 );
504  t00 .set_dual(t0_ );
505  abc0.set_dual(abc_ );
506 
507  test(xscal);
508  }
509 
510  // Lattice!
511  // This structure is tested to be a lattice:
512  // BUT does not support "or-null" on complex tuples
513 
514  // ~scalar
515  // ~num ~oop+?
516  // ~str+? ~{~int64}
517  // ~str ~{~int8}
518  // nil "abc" "def" {nil} {7} <<-- {nil} is a constant tuple
519  // str { int8}
520  // str? { int64}
521  // num oop?
522  // scalar
523  @Test public void testLattice5() {
524  N.reset();
525  N scal= new N("scalar");
526  N num =new N("num" ,scal);
527  N oop0= new N("oop?" ,scal);
528  N str0= new N("str?" ,oop0);
529  N i64 = new N("{i64}" ,oop0); // tuple with a single int field
530 
531  N i8 = new N("{i8}" ,i64);
532  N str = new N("str" ,str0);
533  N abc = new N("abc" ,str);
534  N def = new N("def" ,str);
535  N t7 = new N("{7}" ,i8);
536  N t0 = new N("{nil}" ,i8); // two different flavors of nil
537  N nil = new N("nil" ,str0,num); // two different flavors of nil
538  N xstr= new N("~str" ,abc,def);
539  N xi8 = new N("~{~i8}" ,t0,t7);
540 
541  N xstr_=new N("~str+?" ,xstr,nil);
542  N xi64= new N("~{~i64}" ,xi8);
543  N oop_ =new N("~oop+?" ,xi64,xstr_);
544  N xnum =new N("~num" ,nil);
545  N xscal=new N("~scalar" ,oop_,xnum);
546 
547  // Mark the non-centerline duals
548  scal.set_dual(xscal);
549  num .set_dual(xnum );
550  oop0.set_dual( oop_);
551  str0.set_dual(xstr_);
552  i64 .set_dual(xi64 );
553  i8 .set_dual(xi8 );
554  str .set_dual(xstr );
555 
556  test(xscal);
557  }
558 
559  // Lattice!
560  // This structure is tested to be a lattice:
561 
562  // ~scalar
563  // ~i64 ~oop+?
564  // N:~i64 M:~i64
565  // ~i8
566  // N:~i8 M:~i8
567  // N:7 N:0 7 nil M:7 M:0 "abc"
568  // N:i8 M:i8
569  // i8
570  // N:i64 M:i64
571  // i64 oop?
572  // scalar
573  @Test public void testLattice6() {
574  N.reset();
575  N scal= new N("scalar");
576  N oop0= new N("oop?" ,scal);
577  N i64 = new N("i64" ,scal);
578  N n64 = new N("N:i64" ,i64);
579  N m64 = new N("M:i64" ,i64);
580 
581  N i8 = new N("i8" ,i64);
582  N n8 = new N("N:i8" ,n64,i8);
583  N m8 = new N("M:i8" ,m64,i8);
584 
585  N nil = new N("nil" ,i8);
586  N c7 = new N("7" ,i8);
587  N m0 = new N("M:0" ,m8);
588  N m7 = new N("M:7" ,m8);
589  N n0 = new N("N:0" ,n8);
590  N n7 = new N("N:7" ,n8);
591  N abc = new N("abc" ,oop0);
592 
593  N xn8 = new N("N:~i8" ,n0,n7);
594  N xm8 = new N("M:~i8" ,m0,m7);
595  N xi8 = new N("~i8" ,xn8,xm8,c7,nil);
596 
597  N xm64= new N("M:~i64" ,xm8);
598  N xn64= new N("N:~i64" ,xn8);
599  N xi64= new N("~i64" ,xn64,xm64,xi8);
600  N xoop= new N("~oop+?" ,abc);
601 
602  N xscal=new N("~scalar" ,xoop,xi64);
603 
604  // Mark the non-centerline duals
605  scal.set_dual(xscal);
606  oop0.set_dual(xoop );
607  i64 .set_dual(xi64 );
608  n64 .set_dual(xn64 );
609  m64 .set_dual(xm64 );
610  i8 .set_dual(xi8 );
611  n8 .set_dual(xn8 );
612  m8 .set_dual(xm8 );
613 
614  test(xscal);
615  }
616 
617  // Lattice!
618  // This structure is tested to be a lattice:
619 
620  // Same as Lattice6 but includes a not-nil notion, and i8 becomes i1.
621  // not-nil of ~i1 is not-nil-choice{0,1} is just {1}. Notice not allowed to
622  // have edges ~nzi64 -> N:~nzi64 or else we lose the lattice property. This
623  // implies we can only pick up named-numbers once: at the i64 outermost level.
624  //
625  // ~scalar
626  // ~nzscalar
627  // ~i64 ~oop+?
628  // ~nzi64
629  // N:~i64 M:~i64
630  // N:~nzi64 M:~nzi64
631  // ~i1
632  // N:~i1 M:~i1
633  // N:1 N:0 1 nil M:1 M:0 "abc"
634  // N:i1 M:i1
635  // i1
636  // N:nzi64 M:nzi64
637  // N:i64 M:i64
638  // nzi64
639  // i64 oop?
640  // nzscalar
641  // scalar
642  @Test public void testLattice6_1() {
643  N.reset();
644  N scal= new N("scalar");
645  N nzscal= new N("nzscalar",scal);
646  N oop0= new N("oop?" ,scal);
647  N i64 = new N("i64" ,scal);
648  N nzi64 = new N("nzi64" ,i64,nzscal);
649  N n64 = new N("N:i64" ,i64);
650  N m64 = new N("M:i64" ,i64);
651  N nzn64 = new N("N:nzi64" ,n64);
652  N nzm64 = new N("M:nzi64" ,m64);
653 
654  N i1 = new N("i1" ,i64);
655  N n8 = new N("N:i1" ,n64,i1);
656  N m8 = new N("M:i1" ,m64,i1);
657 
658  N nil = new N("nil" ,i1);
659  N c1 = new N("1" ,i1,nzi64);
660  N m0 = new N("M:0" ,m8);
661  N m1 = new N("M:1" ,m8,nzm64);
662  N n0 = new N("N:0" ,n8);
663  N n1 = new N("N:1" ,n8,nzn64);
664  N abc = new N("abc" ,oop0);
665 
666  N xn8 = new N("N:~i1" ,n0,n1);
667  N xm8 = new N("M:~i1" ,m0,m1);
668  N xi1 = new N("~i1" ,xn8,xm8,c1,nil);
669 
670  N xnzm64= new N("M:~nzi64" ,m1);
671  N xnzn64= new N("N:~nzi64" ,n1);
672  N xm64= new N("M:~i64" ,xm8,xnzm64);
673  N xn64= new N("N:~i64" ,xn8,xnzn64);
674  N xnzi64= new N("~nzi64" ,c1);
675  N xi64= new N("~i64" ,xn64,xm64,xi1,xnzi64);
676  N xoop= new N("~oop+?" ,abc);
677 
678  N xnzscal=new N("~nzscalar" ,xnzi64);
679  N xscal=new N("~scalar" ,xoop,xi64,xnzscal);
680 
681  // Mark the non-centerline duals
682  scal.set_dual(xscal);
683  nzscal.set_dual(xnzscal);
684  oop0.set_dual(xoop );
685  i64 .set_dual(xi64 );
686  nzi64 .set_dual(xnzi64 );
687  n64 .set_dual(xn64 );
688  m64 .set_dual(xm64 );
689  nzn64 .set_dual(xnzn64 );
690  nzm64 .set_dual(xnzm64 );
691  i1 .set_dual(xi1 );
692  n8 .set_dual(xn8 );
693  m8 .set_dual(xm8 );
694 
695  test(xscal);
696  }
697 
698  // Not a Lattice: same problem as before: meet of ~oop and nil can turn into
699  // any "struct?", and there's an infinite number of them.
700  //
701 
702  // ~scalar
703  // ~num ~oop+?
704  // ~@{x:~i64}+? ~@{y:~i64}+? ~oop
705  // ~@{x:~i64} ~@{y:~i64}
706  // nil @{x:nil} @{y:nil}
707  // @{x:i64} @{y:i64}
708  // @{x:i64}? @{y:i64}? oop
709  // num oop?
710  // scalar
711  @Ignore @Test public void testLattice7() {
712  N.reset();
713  N scal= new N("scalar");
714  N num = new N("num" ,scal);
715  N oop0= new N("oop?" ,scal);
716  N oop = new N("oop" ,oop0);
717  N xi0 = new N("@{x:i64}?",oop0);
718  N yi0 = new N("@{y:i64}?",oop0);
719  N xi = new N("@{x:i64}" ,xi0,oop );
720  N yi = new N("@{y:i64}" ,yi0,oop );
721  N x0 = new N("@{x:nil}" ,xi );
722  N y0 = new N("@{y:nil}" ,yi );
723  N nil = new N("nil" ,xi0,yi0,num);
724  N xix = new N("~@{x:~i64}",x0 );
725  N yix = new N("~@{y:~i64}",y0 );
726  N xi_ = new N("~@{x:~i64}+0",xix,nil);
727  N yi_ = new N("~@{y:~i64}+0",yix,nil);
728  N oopx= new N("~oop" ,xix,yix);
729  N oop_= new N("~oop+0" ,xi_,yi_,oopx);
730  N numx= new N("~num" ,nil);
731  N xscal=new N("~scalar" ,oop_,numx);
732 
733  // Mark the non-centerline duals
734  scal.set_dual(xscal);
735  num .set_dual(numx );
736  oop0.set_dual(oop_ );
737  oop .set_dual(oopx );
738  xi0 .set_dual(xi_ );
739  yi0 .set_dual(yi_ );
740  xi .set_dual(xix );
741  yi .set_dual(yix );
742 
743  test(xscal);
744  }
745 
746  // Another experiment with nil and lattice. There is a unified central
747  // tuple-nil. Lattice7 fails because no central tuple-nil. There is no
748  // central string-nil.
749 
750  // nil cannot go to either "abc?" nor "def?", as this breaks the lattice,
751  // thus nil falls to "str?". "abc" can fall to "abc?" but not when mixed in
752  // with nil - which makes "abc?" a useless (but correct) entry in the
753  // lattice.
754 
755  // Making a private nil-type per each regular type restores the lattice.
756  // This is the TypeUnion.NIL concept taking to the limit. So: {oop,oop?}
757  // lifts to {str,str?} lifts to e.g. {abc,abc?} and {def,def?}. abc? lifts
758  // to abc:nil; def? lifts to def:nil.
759 
760 
761  // Lattice!
762  // This structure is tested to be a lattice (with and without {abc?,def?,abc+0,def+0}):
763 
764  // ~scalar
765  // ~num ~oop+0
766  // ~oop {~i64}+0 {~f64}+0 ~str+0
767  // {~i64} {~f64} ~str
768  // {7}+0 {nil}+0 {7.}+0 "abc"+0 "def"+0
769  // i64:0 {7} {nil} {7.} abc:0 "abc" "def" def:0
770  // {7}? {nil}? {7.}? "abc"? "def"?
771  // { i64} { f64} str
772  // oop { i64}? { f64}? str?
773  // num oop?
774  // scalar
775  @Test public void testLattice8() {
776  N.reset();
777  N scal= new N("scalar");
778 
779  N num = new N("num" ,scal);
780  N inil= new N("0:int" ,num);
781 
782  N oop0= new N("oop?" ,scal);
783  N oop = new N("oop" ,oop0);
784  N i0 = new N("(i64)?" ,oop0);
785  N f0 = new N("(f64)?" ,oop0);
786  N i70 = new N("(7)?" ,i0);
787  N f70 = new N("(7.)?" ,f0);
788  N i = new N("(i64)" ,oop,i0);
789  N f = new N("(f64)" ,oop,f0);
790  N n0 = new N("(nil)?" ,i70,f70);
791 
792  N n = new N("(nil)" ,n0,i,f);
793  N i7 = new N("(7)" ,i);
794  N f7 = new N("(7.)" ,f);
795  N tnil= new N("0:tup" ,n0);
796 
797  N str0= new N("str?" ,oop0);
798  N str = new N("str" ,str0,oop );
799  N abc0= new N("abc?" ,str0);
800  N def0= new N("def?" ,str0);
801 
802  N abc = new N("abc" ,str,abc0);
803  N def = new N("def" ,str,def0);
804  N abcnil= new N("0:abc",abc0);
805  N defnil= new N("0:def",def0);
806 
807  N abc_= new N("abc+0" ,abc,abcnil);
808  N def_= new N("def+0" ,def,defnil);
809  N strx= new N("~str" ,abc,def);
810  N str_= new N("~str+0" ,strx,abc_,def_);
811 
812  N n_ = new N("(nil)+0" ,tnil,n);
813  N ix = new N("(~i64)" ,n,i7);
814  N fx = new N("(~f64)" ,n,f7);
815  N i7_ = new N("(7)+0" ,n_);
816  N f7_ = new N("(7.)+0" ,n_);
817  N i_ = new N("(~i64)+0",ix,i7_);
818  N f_ = new N("(~f64)+0",fx,f7_);
819  N oopx= new N("~oop" ,ix,fx,strx);
820  N oop_= new N("~oop+0" ,oopx,i_,f_,str_);
821 
822  N numx= new N("~num" ,inil);
823 
824  N xscl= new N("~scalar" ,oop_,numx);
825 
826  // Mark the non-centerline duals
827  scal.set_dual(xscl );
828  num .set_dual(numx );
829  oop0.set_dual(oop_ );
830  oop .set_dual(oopx );
831  i0 .set_dual(i_ );
832  f0 .set_dual(f_ );
833  i70 .set_dual(i7_ );
834  f70 .set_dual(f7_ );
835  i .set_dual(ix );
836  f .set_dual(fx );
837  n0 .set_dual(n_ );
838 
839  str0.set_dual(str_ );
840  str .set_dual(strx );
841  abc0.set_dual(abc_ );
842  def0.set_dual(def_ );
843 
844  test(xscl);
845  }
846 
847 
848  // Lattice!
849  // This structure is tested to be a lattice.
850 
851  // Testing mixed tuple contents:
852  // ( ANY,ANY...)
853  // (ANY,ALL...)
854  // (~i64,ANY...) (~str,ANY...)
855  // (~i64,ALL...) (~str,ALL...)
856  // ( i64,ANY...) ( str,ANY...)
857  // ( i64,ALL...) ( str,ALL...)
858  // (ALL,ANY...)
859  // ( ALL,ALL...)
860  @Test public void testLattice9() {
861  N.reset();
862  N bot = new N("( ALL,ALL)");
863  N i64 = new N("( i64,ALL)",bot);
864  N str = new N("( str,ALL)",bot);
865 
866  N xi64= new N("(~i64,ALL)",i64);
867  N xstr= new N("(~str,ALL)",str);
868 
869  N xbot= new N("( ANY,ALL)",xstr,xi64);
870  N xtop= new N("( ALL,ANY)",bot);
871 
872  N i64x= new N("( i64,ANY)",xtop);
873  N strx= new N("( str,ANY)",xtop);
874 
875  N xi64x=new N("(~i64,ANY)",i64x);
876  N xstrx=new N("(~str,ANY)",strx);
877 
878  N top = new N("( ANY,ANY)" ,xi64x,xstrx,xbot);
879 
880  // Mark the non-centerline duals
881  bot.set_dual(top);
882  xbot.set_dual(xtop);
883 
884  i64.set_dual(xi64x);
885  str.set_dual(xstrx);
886 
887  xi64.set_dual(i64x);
888  xstr.set_dual(strx);
889 
890  test(top);
891  }
892 
893 
894  // Testing for lattices over trees - specifically Bits.java trees. Expanding
895  // all tree parents into their leaves gives us a lattice over sets and
896  // set-inclusions, which typically ARE a lattice
897  // (https://en.wikipedia.org/wiki/Lattice_(order) pic#1).
898 
899  // The following is NOT a lattice (matches pic#7). Set elements are 2,5,6
900  // and are all independent sets (siblings in the tree).
901  //
902  // {+2+5+6}
903  // / | \
904  // {+2+5} {+2+6} {+5+6}
905  // | / \ / \ |
906  // 2 5 6 -- centerline constants
907  // | \ / \ / |
908  // { 2&5} { 2&6} { 5&6}
909  // \ | /
910  // { 2&5&6}
911  @Ignore @Test public void testLattice10() {
912  N.reset();
913  N x256 = new N("{ 2&5&6}");
914 
915  N x25 = new N("{ 2&5}",x256);
916  N x26 = new N("{ 2&6}",x256);
917  N x56 = new N("{ 5&6}",x256);
918 
919  N c2 = new N("2",x25,x26);
920  N c5 = new N("5",x25,x56);
921  N c6 = new N("6",x26,x56);
922 
923  N o25 = new N("{+2+5}",c2,c5);
924  N o26 = new N("{+2+6}",c2,c6);
925  N o56 = new N("{+5+6}",c5,c6);
926 
927  N o256 = new N("{+2+5+6}",o25,o26,o56);
928 
929  // Mark the non-centerline duals
930  x256.set_dual(o256);
931  x25 .set_dual(o25 );
932  x26 .set_dual(o26 );
933  x56 .set_dual(o56 );
934 
935  test(o256);
936  }
937 
938  // Same as Lattice10, except no centerline constants; everything is either up
939  // or down. Still not a Lattice. The MEET of {+2+5} and &6 is either {2&6}
940  // or {5&6}, no GLB.
941  // The following is NOT a lattice (matches pic#7). Set elements are 2,5,6
942  // and are all independent sets (siblings in the tree).
943  //
944  // {+2+5+6}
945  // / | \
946  // {+2+5} {+2+6} {+5+6}
947  // | / \ / \ |
948  // +2 +5 +6
949  // | | |
950  // &2 &5 &6
951  // | \ / \ / |
952  // { 2&5} { 2&6} { 5&6}
953  // \ | /
954  // { 2&5&6}
955  @Ignore @Test public void testLattice11() {
956  N.reset();
957  N x256 = new N("{ 2&5&6}");
958 
959  N x25 = new N("{ 2&5}",x256);
960  N x26 = new N("{ 2&6}",x256);
961  N x56 = new N("{ 5&6}",x256);
962 
963  N x2 = new N("&2",x25,x26);
964  N x5 = new N("&5",x25,x56);
965  N x6 = new N("&6",x26,x56);
966 
967  N o2 = new N("+2",x2);
968  N o5 = new N("+5",x5);
969  N o6 = new N("+6",x6);
970 
971  N o25 = new N("{+2+5}",o2,o5);
972  N o26 = new N("{+2+6}",o2,o6);
973  N o56 = new N("{+5+6}",o5,o6);
974 
975  N o256 = new N("{+2+5+6}",o25,o26,o56);
976 
977  // Mark the non-centerline duals
978  x256.set_dual(o256);
979  x25 .set_dual(o25 );
980  x26 .set_dual(o26 );
981  x56 .set_dual(o56 );
982 
983  x2 .set_dual(o2 );
984  x5 .set_dual(o5 );
985  x6 .set_dual(o6 );
986 
987  test(o256);
988  }
989 
990 
991  // The following IS a lattice (two copies of pic#1 joined by the empty set).
992  // Set elements are 2,5,6 and are all independent sets (siblings in the tree).
993  //
994  // {+2+5+6}
995  // / | \
996  // {+2+5} {+2+6} {+5+6}
997  // | / \ / \ |
998  // +2 +5 +6
999  // \ | /
1000  // [ ]
1001  // / | \
1002  // &2 &5 &6
1003  // | \ / \ / |
1004  // { 2&5} { 2&6} { 5&6}
1005  // \ | /
1006  // { 2&5&6}
1007  @Test public void testLattice12() {
1008  N.reset();
1009  N x256 = new N("{ 2&5&6}");
1010 
1011  N x25 = new N("{ 2&5}",x256);
1012  N x26 = new N("{ 2&6}",x256);
1013  N x56 = new N("{ 5&6}",x256);
1014 
1015  N x2 = new N("&2",x25,x26);
1016  N x5 = new N("&5",x25,x56);
1017  N x6 = new N("&6",x26,x56);
1018 
1019  N mt = new N("[]",x2,x5,x6);
1020 
1021  N o2 = new N("+2",mt);
1022  N o5 = new N("+5",mt);
1023  N o6 = new N("+6",mt);
1024 
1025  N o25 = new N("{+2+5}",o2,o5);
1026  N o26 = new N("{+2+6}",o2,o6);
1027  N o56 = new N("{+5+6}",o5,o6);
1028 
1029  N o256 = new N("{+2+5+6}",o25,o26,o56);
1030 
1031  // Mark the non-centerline duals
1032  x256.set_dual(o256);
1033  x25 .set_dual(o25 );
1034  x26 .set_dual(o26 );
1035  x56 .set_dual(o56 );
1036 
1037  x2 .set_dual(o2 );
1038  x5 .set_dual(o5 );
1039  x6 .set_dual(o6 );
1040 
1041  test(o256);
1042  }
1043 
1044  // Not a lattice; exactly Pic.8 from Lattice_(order) page.
1045  // Set {1} is the parent of {2,3}.
1046  // Using just a {+1} means: pick any of 2 or 3.
1047  // Using {2,3} means: pick any 2 AND pick any 3.
1048 
1049  // Cannot collapse {+1,+2,+3} into {+1}, because this does not return both a
1050  // 2 and a 3. Instead, since {+2,+3} "cover" {+1}, can remove the +1.
1051  // Assume all tree-splits are complete, and only the primitives & Parse have
1052  // more than 2 (otherwise fidx & alias splits are *splits* and make 2 from 1).
1053  //
1054  // {+1}
1055  // {+2+3+4}
1056  // {+2+3} {+2+4} {+3+4} ### &2 meet {+3+4}
1057  // {+2} {+3} {+4} ### &2&3 and &2&4
1058  // {&2} {&3} {&4}
1059  // {&2&3} {&2&4} {&3&4}
1060  // {&2&3&4}
1061  // {&1}
1062  @Ignore
1063  @Test public void testLattice12a() {
1064  N.reset();
1065  N _1 = new N("{&1}");
1066  N _234= new N("{&2&3&4}",_1);
1067 
1068  N _23 = new N("{&2&3}",_234);
1069  N _24 = new N("{&2&4}",_234);
1070  N _34 = new N("{&3&4}",_234);
1071 
1072  N _2 = new N("&2",_23,_24);
1073  N _3 = new N("&3",_23,_34);
1074  N _4 = new N("&4",_24,_34);
1075 
1076  N x2 = new N("+2",_2);
1077  N x3 = new N("+3",_3);
1078  N x4 = new N("+4",_4);
1079 
1080  N x23 = new N("{+2+3}",x2,x3);
1081  N x24 = new N("{+2+4}",x2,x4);
1082  N x34 = new N("{+3+4}",x3,x4);
1083 
1084  N x234= new N("{+2+3+4}",x23,x24,x34);
1085 
1086  N x1 = new N("{+1}",x234);
1087 
1088  // Mark the non-centerline duals
1089  x234.set_dual(_234);
1090  x23 .set_dual(_23 );
1091  x24 .set_dual(_24 );
1092  x34 .set_dual(_34 );
1093 
1094  x2 .set_dual(_2 );
1095  x3 .set_dual(_3 );
1096  x4 .set_dual(_4 );
1097 
1098  x1 .set_dual(_1 );
1099 
1100  test(x1);
1101  }
1102 
1103 
1104  // Bits indicate in/out. Another bit for up/down. Another bit for bulk
1105  // meet/join. In the implementation, if a parent in is IN, then all children
1106  // are IN, and forced zero. Future/unnamed children are IN. If a parent is
1107  // OUT, then each child can be in or out. Future/unnamed children are OUT.
1108  //
1109  // +{~2~3~4}
1110  // +{~2~3} +{~2~4} +{~3~4}
1111  // +{~2} +{~3} +{~4}
1112  // &{~2} &{~3} &{~4}
1113  // &{~2~3} &{~2~4} &{~3~4}
1114  // &{~2~3~4}
1115  //
1116  // +{ 2 3 4}
1117  // +{ 2 3} +{ 2 4} +{ 3 4}
1118  // +{ 2} +{ 3} +{ 4}
1119  // &{ 2} &{ 3} &{ 4}
1120  // &{ 2 3} &{ 2 4} &{ 3 4}
1121  // &{ 2 3 4}
1122  //
1123  @Ignore
1124  @Test public void testLattice12b() {
1125  N.reset();
1126  N and_234= new N("&{ 2 3 4}");
1127 
1128  N and_23 = new N("&{ 2 3}",and_234);
1129  N and_24 = new N("&{ 2 4}",and_234);
1130  N and_34 = new N("&{ 3 4}",and_234);
1131 
1132  N and_2 = new N("&{ 2}",and_23,and_24);
1133  N and_3 = new N("&{ 3}",and_23,and_34);
1134  N and_4 = new N("&{ 4}",and_24,and_34);
1135 
1136  N oor_2 = new N("+{ 2}",and_2);
1137  N oor_3 = new N("+{ 3}",and_3);
1138  N oor_4 = new N("+{ 4}",and_4);
1139 
1140  N oor_23 = new N("+{ 2 3}",oor_2,oor_3);
1141  N oor_24 = new N("+{ 2 4}",oor_2,oor_4);
1142  N oor_34 = new N("+{ 3 4}",oor_3,oor_4);
1143 
1144  N oor_234= new N("+{ 2 3 4}",oor_23,oor_24,oor_34);
1145 
1146  N andx234= new N("&{~2~3~4}",oor_234);
1147 
1148  N andx23 = new N("&{~2~3}",andx234);
1149  N andx24 = new N("&{~2~4}",andx234);
1150  N andx34 = new N("&{~3~4}",andx234);
1151 
1152  N andx2 = new N("&{~2}",andx23,andx24);
1153  N andx3 = new N("&{~3}",andx23,andx34);
1154  N andx4 = new N("&{~4}",andx24,andx34);
1155 
1156  N oorx2 = new N("+{~2}",andx2);
1157  N oorx3 = new N("+{~3}",andx3);
1158  N oorx4 = new N("+{~4}",andx4);
1159 
1160  N oorx23 = new N("+{~2~3}",oorx2,oorx3);
1161  N oorx24 = new N("+{~2~4}",oorx2,oorx4);
1162  N oorx34 = new N("+{~3~4}",oorx3,oorx4);
1163 
1164  N oorx234= new N("+{~2~3~4}",oorx23,oorx24,oorx34);
1165 
1166  // Mark the non-centerline duals
1167  andx234.set_dual(oor_234);
1168 
1169  andx23 .set_dual(oor_23 );
1170  andx24 .set_dual(oor_24 );
1171  andx34 .set_dual(oor_34 );
1172 
1173  andx2 .set_dual(oor_2 );
1174  andx3 .set_dual(oor_3 );
1175  andx4 .set_dual(oor_4 );
1176 
1177  oorx2 .set_dual(and_2 );
1178  oorx3 .set_dual(and_3 );
1179  oorx4 .set_dual(and_4 );
1180 
1181  oorx23 .set_dual(and_23 );
1182  oorx24 .set_dual(and_24 );
1183  oorx34 .set_dual(and_34 );
1184 
1185  oorx234.set_dual(and_234);
1186 
1187  test(oorx234);
1188  }
1189 
1190 
1191  // Same as lattice 12, except using a high & low empty sets.
1192  // Set elements are 2,5,6 and are all independent sets (siblings in the tree).
1193  //
1194  // {+2+5+6}
1195  // / | \
1196  // {+2+5} {+2+6} {+5+6}
1197  // | / \ / \ |
1198  // +2 +5 +6
1199  // \ | /
1200  // [+] -- high empty
1201  // [ ] -- low empty
1202  // / | \
1203  // &2 &5 &6
1204  // | \ / \ / |
1205  // { 2&5} { 2&6} { 5&6}
1206  // \ | /
1207  // { 2&5&6}
1208  @Test public void testLattice12d() {
1209  N.reset();
1210  N x256 = new N("{ 2&5&6}");
1211 
1212  N x25 = new N("{ 2&5}",x256);
1213  N x26 = new N("{ 2&6}",x256);
1214  N x56 = new N("{ 5&6}",x256);
1215 
1216  N x2 = new N("&2",x25,x26);
1217  N x5 = new N("&5",x25,x56);
1218  N x6 = new N("&6",x26,x56);
1219 
1220  N mt = new N("[]",x2,x5,x6);
1221 
1222  N o2 = new N("+2",mt);
1223  N o5 = new N("+5",mt);
1224  N o6 = new N("+6",mt);
1225 
1226  N o25 = new N("{+2+5}",o2,o5);
1227  N o26 = new N("{+2+6}",o2,o6);
1228  N o56 = new N("{+5+6}",o5,o6);
1229 
1230  N o256 = new N("{+2+5+6}",o25,o26,o56);
1231 
1232  // Mark the non-centerline duals
1233  x256.set_dual(o256);
1234  x25 .set_dual(o25 );
1235  x26 .set_dual(o26 );
1236  x56 .set_dual(o56 );
1237 
1238  x2 .set_dual(o2 );
1239  x5 .set_dual(o5 );
1240  x6 .set_dual(o6 );
1241 
1242  test(o256);
1243  }
1244 
1245  // Same as testLattice12, except 6 is now nil... which is on the centerline.
1246  // Not a lattice, although testLattice12 IS.
1247  // This implies I need a sign-nil: unsigned nil sits on the centerline.
1248  // Set elements are 2,5 and are all independent sets (siblings in the tree).
1249  //
1250  // {+2+5+0}
1251  // / | \
1252  // {+2+5} {+2+0} {+5+0}
1253  // | / \ / \ /
1254  // +2 +5 |
1255  // \ | |
1256  // [ ] 0
1257  // / | |
1258  // &2 &5 |
1259  // | \ / \ / \
1260  // { 2&5} { 2&0} { 5&0}
1261  // \ | /
1262  // { 2&5&0}
1263  @Ignore @Test public void testLattice13() {
1264  N.reset();
1265  N x250 = new N("{ 2&5&0}");
1266 
1267  N x25 = new N("{ 2&5}",x250);
1268  N x20 = new N("{ 2&0}",x250);
1269  N x50 = new N("{ 5&0}",x250);
1270 
1271  N x2 = new N("&2",x25,x20);
1272  N x5 = new N("&5",x25,x50);
1273 
1274  N nil = new N("0",x20,x50);
1275  N mt = new N("[]",x2,x5);
1276 
1277  N o2 = new N("+2",mt);
1278  N o5 = new N("+5",mt);
1279 
1280  N o25 = new N("{+2+5}",o2,o5);
1281  N o20 = new N("{+2+0}",o2,nil);
1282  N o50 = new N("{+5+0}",o5,nil);
1283 
1284  N o250 = new N("{+2+5+0}",o25,o20,o50);
1285 
1286  // Mark the non-centerline duals
1287  x250.set_dual(o250);
1288  x25 .set_dual(o25 );
1289  x20 .set_dual(o20 );
1290  x50 .set_dual(o50 );
1291 
1292  x2 .set_dual(o2 );
1293  x5 .set_dual(o5 );
1294 
1295  test(o250);
1296  }
1297 
1298 
1299  // Tests as a lattice. The following is testLattice12, with 0 instead of 6
1300  // AND more structure appended around: {scalar->int->{nint,nil}} and its
1301  // inverse. nil ONLY goes to +/-0. Each bit-set, e.g. {+5+0} or {+0}
1302  // expands to a full pointer-target-type 6-element mini-lattice:
1303  // ~obj
1304  // ~rec ~str
1305  // rec str
1306  // obj
1307  //
1308  // Which means crossing-nil has to choose between pointing at
1309  // {+0->obj} or {+0->~obj} but canNOT point at e.g. {+0->rec}.
1310  //
1311  // /--- ~scalar
1312  // /- \
1313  // {+2+5+0} ~int
1314  // / | \ / \
1315  // {+2+5} {+2+0} {+5+0} | ~nint
1316  // | / \ / \ | | |
1317  // +2 +5 +0 |
1318  // \ | / \ /
1319  // [ ] nil
1320  // / | \ / \
1321  // &2 &5 &0 |
1322  // | \ / \ / | | |
1323  // { 2&5} { 2&0} { 5&0} | nint
1324  // \ | / \ /
1325  // { 2&5&0} int
1326  // \- /
1327  // \--- scalar
1328  //
1329  @Test public void testLattice14() {
1330  N.reset();
1331  N xscl = new N("scalar");
1332  N x250 = new N("{ 2&5&0}",xscl);
1333  N xint = new N("int",xscl);
1334 
1335  N x25 = new N("{ 2&5}",x250);
1336  N x20 = new N("{ 2&0}",x250);
1337  N x50 = new N("{ 5&0}",x250);
1338  N xnint= new N("nint",xint);
1339 
1340  N x2 = new N("&2",x25,x20);
1341  N x5 = new N("&5",x25,x50);
1342  N x0 = new N("&0",x20,x50);
1343 
1344  N mt = new N("[]",x2,x5,x0);
1345  N nil = new N("nil",x0,xint);
1346 
1347  N o2 = new N("+2",mt);
1348  N o5 = new N("+5",mt);
1349  N o0 = new N("+0",mt,nil);
1350 
1351  N onint= new N("~nint",xnint);
1352  N o25 = new N("{+2+5}",o2,o5);
1353  N o20 = new N("{+2+0}",o2,o0);
1354  N o50 = new N("{+5+0}",o5,o0);
1355 
1356  N oint = new N("~int",nil,onint);
1357  N o250 = new N("{+2+5+0}",o25,o20,o50);
1358  N sclr = new N("~scalar",o250,oint);
1359 
1360  // Mark the non-centerline duals
1361  xscl.set_dual(sclr);
1362  x250.set_dual(o250);
1363 
1364  x25 .set_dual(o25 );
1365  x20 .set_dual(o20 );
1366  x50 .set_dual(o50 );
1367  xint.set_dual(oint);
1368  xnint.set_dual(onint);
1369 
1370  x2 .set_dual(o2 );
1371  x5 .set_dual(o5 );
1372  x0 .set_dual(o0 );
1373 
1374  test(sclr);
1375  }
1376 
1377  // Building the simplist possible 2-alias ptr lattice, then adding nil.
1378  // The two aliases are 0 & 4, and the ptr-lattice includes {obj,rec,str}.
1379  // Alias lattice has 7 states: Ptr-lattice has 6:
1380  // ~0~4 ~obj
1381  // ~0 ~4 ~rec ~str
1382  // mt rec str
1383  // 0 4 obj
1384  // 0 4
1385 
1386  // These two lattices are "multiplied" yielding 42 states. Then we inject
1387  // 'nil'. Does 'nil' have edges to "[0]->obj"? "[0]->~obj"? Something else?
1388  // Tested as Lattice: [0]-> obj <== NIL <== [~0]->~obj
1389  // Fails as Lattice: [0]->~obj <== NIL <== [~0]-> obj
1390  @Test public void testLattice15() {
1391  N.reset();
1392 
1393  // Layer [ 0 4] -> {~obj,~rec,~str,str,rec,obj}
1394  N n_04_obj = new N("n_04_obj");
1395  N n_04_rec = new N("n_04_rec",n_04_obj);
1396  N n_04_str = new N("n_04_str",n_04_obj);
1397  N n_04xrec = new N("n_04xrec",n_04_rec);
1398  N n_04xstr = new N("n_04xstr",n_04_str);
1399  N n_04xobj = new N("n_04xobj",n_04xrec,n_04xstr);
1400 
1401  // Layer [ 0 ] -> {~obj,~rec,~str,str,rec,obj}
1402  N n_0__obj = new N("n_0__obj" ,n_04_obj);
1403  N n_0__rec = new N("n_0__rec",n_0__obj ,n_04_rec);
1404  N n_0__str = new N("n_0__str",n_0__obj ,n_04_str);
1405  N n_0_xrec = new N("n_0_xrec",n_0__rec ,n_04xrec);
1406  N n_0_xstr = new N("n_0_xstr",n_0__str ,n_04xstr);
1407  N n_0_xobj = new N("n_0_xobj",n_0_xrec,n_0_xstr,n_04xobj);
1408 
1409  // Layer [ 4] -> {~obj,~rec,~str,str,rec,obj}
1410  N n__4_obj = new N("n__4_obj" ,n_04_obj);
1411  N n__4_rec = new N("n__4_rec",n__4_obj ,n_04_rec);
1412  N n__4_str = new N("n__4_str",n__4_obj ,n_04_str);
1413  N n__4xrec = new N("n__4xrec",n__4_rec ,n_04xrec);
1414  N n__4xstr = new N("n__4xstr",n__4_str ,n_04xstr);
1415  N n__4xobj = new N("n__4xobj",n__4xrec,n__4xstr,n_04xobj);
1416 
1417  // Layer [ ] -> {~obj,~rec,~str,str,rec,obj}
1418  N n_mt_obj = new N("n_mt_obj" ,n_0__obj,n__4_obj);
1419  N n_mt_rec = new N("n_mt_rec",n_mt_obj ,n_0__rec,n__4_rec);
1420  N n_mt_str = new N("n_mt_str",n_mt_obj ,n_0__str,n__4_str);
1421  N n_mtxrec = new N("n_mtxrec",n_mt_rec ,n_0_xrec,n__4xrec);
1422  N n_mtxstr = new N("n_mtxstr",n_mt_str ,n_0_xstr,n__4xstr);
1423  N n_mtxobj = new N("n_mtxobj",n_mtxrec,n_mtxstr,n_0_xobj,n__4xobj);
1424 
1425  // An UNSIGNED NIL works IFF NIL expands as-if "[0]->obj", which means
1426  // meeting with NIL loses the base type of a pointer. But it remains a
1427  // lattice.
1428 
1429  // Signed Nil works, and is a lattice.
1430  N NIL = new N(" NIL",n_0__obj);
1431  N XNIL= new N("XNIL",n_0_xobj);
1432 
1433  // Layer [~0 ] -> {~obj,~rec,~str,str,rec,obj}
1434  N nx0__obj = new N("nx0__obj" ,n_mt_obj, NIL);
1435  N nx0__rec = new N("nx0__rec",nx0__obj ,n_mt_rec);
1436  N nx0__str = new N("nx0__str",nx0__obj ,n_mt_str);
1437  N nx0_xrec = new N("nx0_xrec",nx0__rec ,n_mtxrec);
1438  N nx0_xstr = new N("nx0_xstr",nx0__str ,n_mtxstr);
1439  N nx0_xobj = new N("nx0_xobj",nx0_xrec,nx0_xstr,n_mtxobj, XNIL);
1440 
1441  // Layer [~4 ] -> {~obj,~rec,~str,str,rec,obj}
1442  N nx_4_obj = new N("nx_4_obj" ,n_mt_obj);
1443  N nx_4_rec = new N("nx_4_rec",nx_4_obj ,n_mt_rec);
1444  N nx_4_str = new N("nx_4_str",nx_4_obj ,n_mt_str);
1445  N nx_4xrec = new N("nx_4xrec",nx_4_rec ,n_mtxrec);
1446  N nx_4xstr = new N("nx_4xstr",nx_4_str ,n_mtxstr);
1447  N nx_4xobj = new N("nx_4xobj",nx_4xrec,nx_4xstr,n_mtxobj);
1448 
1449  // Layer [~0~4] -> {~obj,~rec,~str,str,rec,obj}
1450  N nx04_obj = new N("nx04_obj" ,nx0__obj,nx_4_obj);
1451  N nx04_rec = new N("nx04_rec",nx04_obj ,nx0__rec,nx_4_rec);
1452  N nx04_str = new N("nx04_str",nx04_obj ,nx0__str,nx_4_str);
1453  N nx04xrec = new N("nx04xrec",nx04_rec ,nx0_xrec,nx_4xrec);
1454  N nx04xstr = new N("nx04xstr",nx04_str ,nx0_xstr,nx_4xstr);
1455  N nx04xobj = new N("nx04xobj",nx04xrec,nx04xstr,nx0_xobj,nx_4xobj);
1456 
1457 
1458  // Mark the non-centerline duals
1459  n_04_obj.set_dual(nx04xobj);
1460  n_04_rec.set_dual(nx04xrec);
1461  n_04_str.set_dual(nx04xstr);
1462  n_04xrec.set_dual(nx04_rec);
1463  n_04xstr.set_dual(nx04_str);
1464  n_04xobj.set_dual(nx04_obj);
1465 
1466  n_0__obj.set_dual(nx0_xobj);
1467  n_0__rec.set_dual(nx0_xrec);
1468  n_0__str.set_dual(nx0_xstr);
1469  n_0_xrec.set_dual(nx0__rec);
1470  n_0_xstr.set_dual(nx0__str);
1471  n_0_xobj.set_dual(nx0__obj);
1472 
1473  n__4_obj.set_dual(nx_4xobj);
1474  n__4_rec.set_dual(nx_4xrec);
1475  n__4_str.set_dual(nx_4xstr);
1476  n__4xrec.set_dual(nx_4_rec);
1477  n__4xstr.set_dual(nx_4_str);
1478  n__4xobj.set_dual(nx_4_obj);
1479 
1480  n_mt_obj.set_dual(n_mtxobj);
1481  n_mt_rec.set_dual(n_mtxrec);
1482  n_mt_str.set_dual(n_mtxstr);
1483 
1484  NIL.set_dual(XNIL);
1485 
1486  test(nx04xobj);
1487  }
1488 
1489  // Named subtypes, plus array (subtype string), tuple (subtype rec).
1490  // NOT A LATTICE as soon as you have more than 1 name.
1491  //
1492  // ~obj And named subtypes A, B
1493  // ~ary ~tup ~obj ==> A:~obj ==> A:~tup ==> A:~rec ==> A:rec ==> A:tup ==> A:obj ==> obj
1494  // ~str ~rec
1495  // str rec
1496  // ary tup
1497  // obj
1498  //
1499  // This IS a lattice for a single name (and nested names), but not for
1500  // multiple names.
1501  //
1502  @Ignore @Test public void testLattice16() {
1503  N.reset();
1504 
1505  N __obj = new N("__obj");
1506  N A_obj = new N("A_obj",__obj);
1507  N B_obj = new N("B_obj",__obj);
1508 
1509  N __ary = new N("__ary",__obj);
1510  N A_ary = new N("A_ary",__ary,A_obj);
1511  N B_ary = new N("B_ary",__ary,B_obj);
1512  N __tup = new N("__tup",__obj);
1513  N A_tup = new N("A_tup",__tup,A_obj);
1514  N B_tup = new N("B_tup",__tup,B_obj);
1515 
1516  N __str = new N("__str",__ary);
1517  N A_str = new N("A_str",__str,A_ary);
1518  N B_str = new N("B_str",__str,B_ary);
1519  N __rec = new N("__rec",__tup);
1520  N A_rec = new N("A_rec",__rec,A_tup);
1521  N B_rec = new N("B_rec",__rec,B_tup);
1522 
1523  N Axrec = new N("A~rec",A_rec);
1524  N Bxrec = new N("B~rec",B_rec);
1525  N _xrec = new N("_~rec",Axrec,Bxrec);
1526  N Axstr = new N("A~str",A_str);
1527  N Bxstr = new N("B~str",B_str);
1528  N _xstr = new N("_~str",Axstr,Bxstr);
1529 
1530  N Axtup = new N("A~tup",Axrec);
1531  N Bxtup = new N("B~tup",Bxrec);
1532  N _xtup = new N("_~tup",_xrec,Axtup,Bxtup);
1533  N Axary = new N("A~ary",Axstr);
1534  N Bxary = new N("B~ary",Bxstr);
1535  N _xary = new N("_~ary",_xstr,Axary,Bxary);
1536 
1537  N Axobj = new N("A~obj",Axary,Axtup);
1538  N Bxobj = new N("B~obj",Bxary,Bxtup);
1539  N _xobj = new N("_~obj",_xtup,_xary,Axobj,Bxobj);
1540 
1541  __obj.set_dual(_xobj);
1542  __ary .set_dual(_xary);
1543  __str .set_dual(_xstr);
1544  __tup .set_dual(_xtup);
1545  __rec .set_dual(_xrec);
1546  A_obj .set_dual(Axobj);
1547  A_ary .set_dual(Axary);
1548  A_str .set_dual(Axstr);
1549  A_tup .set_dual(Axtup);
1550  A_rec .set_dual(Axrec);
1551  B_obj .set_dual(Bxobj);
1552  B_ary .set_dual(Bxary);
1553  B_str .set_dual(Bxstr);
1554  B_tup .set_dual(Bxtup);
1555  B_rec .set_dual(Bxrec);
1556 
1557  test(_xobj);
1558  }
1559 
1560  // Named subtypes, plus array (subtype string), tuple (subtype rec). Similar
1561  // to the testLattice6 case, only pick up names at the outermost level.
1562  //
1563  // ~obj And named subtypes A, B
1564  // ~ary ~tup ~obj ==> A:~obj ==> A:~tup ==> A:~rec ==> A:rec ==> A:tup ==> A:obj ==> obj
1565  // ~str ~rec ~obj ==> B:~obj ==> B:~tup ==> B:~rec ==> B:rec ==> B:tup ==> B:obj ==> obj
1566  // str rec NO INNER EDGES, e.g. A:rec ==> rec !!!
1567  // ary tup
1568  // obj
1569  //
1570  // This IS a lattice for a single name (and nested names), but not for
1571  // multiple names.
1572  //
1573  @Test public void testLattice17() {
1574  N.reset();
1575 
1576  N __obj = new N("__obj");
1577  N A_obj = new N("A_obj",__obj);
1578  N B_obj = new N("B_obj",__obj);
1579 
1580  N __ary = new N("__ary",__obj);
1581  N A_ary = new N("A_ary",A_obj);
1582  N B_ary = new N("B_ary",B_obj);
1583  N __tup = new N("__tup",__obj);
1584  N A_tup = new N("A_tup",A_obj);
1585  N B_tup = new N("B_tup",B_obj);
1586 
1587  N __str = new N("__str",__ary);
1588  N A_str = new N("A_str",A_ary);
1589  N B_str = new N("B_str",B_ary);
1590  N __rec = new N("__rec",__tup);
1591  N A_rec = new N("A_rec",A_tup);
1592  N B_rec = new N("B_rec",B_tup);
1593 
1594  N Axrec = new N("A~rec",A_rec);
1595  N Bxrec = new N("B~rec",B_rec);
1596  N _xrec = new N("_~rec",__rec);
1597  N Axstr = new N("A~str",A_str);
1598  N Bxstr = new N("B~str",B_str);
1599  N _xstr = new N("_~str",__str);
1600 
1601  N Axtup = new N("A~tup",Axrec);
1602  N Bxtup = new N("B~tup",Bxrec);
1603  N _xtup = new N("_~tup",_xrec);
1604  N Axary = new N("A~ary",Axstr);
1605  N Bxary = new N("B~ary",Bxstr);
1606  N _xary = new N("_~ary",_xstr);
1607 
1608  N Axobj = new N("A~obj",Axary,Axtup);
1609  N Bxobj = new N("B~obj",Bxary,Bxtup);
1610  N _xobj = new N("_~obj",_xtup,_xary,Axobj,Bxobj);
1611 
1612  __obj.set_dual(_xobj);
1613  __ary .set_dual(_xary);
1614  __str .set_dual(_xstr);
1615  __tup .set_dual(_xtup);
1616  __rec .set_dual(_xrec);
1617  A_obj .set_dual(Axobj);
1618  A_ary .set_dual(Axary);
1619  A_str .set_dual(Axstr);
1620  A_tup .set_dual(Axtup);
1621  A_rec .set_dual(Axrec);
1622  B_obj .set_dual(Bxobj);
1623  B_ary .set_dual(Bxary);
1624  B_str .set_dual(Bxstr);
1625  B_tup .set_dual(Bxtup);
1626  B_rec .set_dual(Bxrec);
1627 
1628  test(_xobj);
1629 
1630  }
1631 
1632  // Open question for a future testLattice test:
1633  //
1634  // Under what circumstances can 'meet' return a NIL?
1635  //
1636  // Seems obvious that nil.meet(nil) returns nil. What about nil.meet(0:int)?
1637  // nil.meet([0]->obj)? Current theory is: Yes, provided nil was an input and
1638  // strictly not otherwise. Denies eg: [~0+4]->~obj.meet(~[0+2]->~obj) which
1639  // you might imagine returning [~0]->~obj - the nil inverse. How about
1640  // [0]->obj.meet([0]->obj) - two instances of not-nil-but-nil-equivalents?
1641  // Same question for 0:int.meet(0:int) and 0:flt.meet(0:int). And then the
1642  // same question for: 0:int.meet([0]->obj)?
1643  //
1644 }
com.cliffc.aa.TestLattice.N.N
N(String t, N... subs)
Definition: TestLattice.java:91
com.cliffc.aa.TestLattice.N._t
final String _t
Definition: TestLattice.java:85
com.cliffc.aa.TestLattice.testLattice10
void testLattice10()
Definition: TestLattice.java:911
com.cliffc.aa.TestLattice.testLattice12a
void testLattice12a()
Definition: TestLattice.java:1063
com.cliffc.aa.TestLattice.testLattice3
void testLattice3()
Definition: TestLattice.java:401
com.cliffc.aa.TestLattice.testLattice11
void testLattice11()
Definition: TestLattice.java:955
com.cliffc
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.TestLattice.N._id
final int _id
Definition: TestLattice.java:84
com.cliffc.aa.TestLattice.testLattice16
void testLattice16()
Definition: TestLattice.java:1502
com.cliffc.aa.util.Ary
Definition: Ary.java:11
com.cliffc.aa.TestLattice.testLattice8
void testLattice8()
Definition: TestLattice.java:775
com.cliffc.aa.TestLattice.testLattice6
void testLattice6()
Definition: TestLattice.java:573
com.cliffc.aa.TestLattice.N._dual
N _dual
Definition: TestLattice.java:90
com.cliffc.aa.TestLattice.N._cnt
int _cnt
Definition: TestLattice.java:89
com.cliffc.aa.TestLattice.testLattice7
void testLattice7()
Definition: TestLattice.java:711
com.cliffc.aa.TestLattice.N.reset
static void reset()
Definition: TestLattice.java:83
com.cliffc.aa.TestLattice.test
static void test(N top)
Definition: TestLattice.java:156
com.cliffc.aa.TestLattice.testLattice13
void testLattice13()
Definition: TestLattice.java:1263
com.cliffc.aa.TestLattice.N
Definition: TestLattice.java:80
com.cliffc.aa.TestLattice.N.NS
static Ary< N > NS
Definition: TestLattice.java:82
com.cliffc.aa.TestLattice.testLattice1
void testLattice1()
Definition: TestLattice.java:274
com.cliffc.aa.TestLattice.testLattice6_1
void testLattice6_1()
Definition: TestLattice.java:642
com.cliffc.aa.TestLattice.N.ID
static int ID
Definition: TestLattice.java:81
com.cliffc.aa.TestLattice.N.walk_dual
boolean walk_dual(BitSet bs)
Definition: TestLattice.java:140
com.cliffc.aa.TestLattice.testLattice12b
void testLattice12b()
Definition: TestLattice.java:1124
com.cliffc.aa.TestLattice.N._sups
final Ary< N > _sups
Definition: TestLattice.java:87
com.cliffc.aa.TestLattice.testLattice12d
void testLattice12d()
Definition: TestLattice.java:1208
com.cliffc.aa.util.SB
Tight/tiny StringBuilder wrapper.
Definition: SB.java:8
com.cliffc.aa.TestLattice.testLattice0
void testLattice0()
Definition: TestLattice.java:221
com.cliffc.aa.TestLattice.N.set_dual
void set_dual(N d)
Definition: TestLattice.java:100
com.cliffc.aa.TestLattice.N._subs
final Ary< N > _subs
Definition: TestLattice.java:86
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.TestLattice.testLattice12
void testLattice12()
Definition: TestLattice.java:1007
com.cliffc.aa.TestLattice.N.walk_set_sup
void walk_set_sup(BitSet bs)
Definition: TestLattice.java:105
com.cliffc.aa.TestLattice.testLattice14
void testLattice14()
Definition: TestLattice.java:1329
com.cliffc.aa.TestLattice.N.walk_min_edge
boolean walk_min_edge(int[] vs, N sup)
Definition: TestLattice.java:124
com.cliffc.aa.TestLattice.testLattice4
void testLattice4()
Definition: TestLattice.java:465
com.cliffc.aa.TestLattice.testLattice5
void testLattice5()
Definition: TestLattice.java:523
com.cliffc.aa.util.SB.p
SB p(String s)
Definition: SB.java:13
com.cliffc.aa.TestLattice.N.walk_print
void walk_print(BitSet bs, int indent)
Definition: TestLattice.java:112
com.cliffc.aa.TestLattice.testLattice15
void testLattice15()
Definition: TestLattice.java:1390
com.cliffc.aa.TestLattice.N._reaches
final BitSet _reaches
Definition: TestLattice.java:88
com
com.cliffc.aa.TestLattice.testLattice9
void testLattice9()
Definition: TestLattice.java:860
com.cliffc.aa.util.SB.toString
String toString()
Definition: SB.java:62
com.cliffc.aa.TestLattice
Definition: TestLattice.java:79
com.cliffc.aa.TestLattice.testLattice2
void testLattice2()
Definition: TestLattice.java:319
com.cliffc.aa.TestLattice.testLattice17
void testLattice17()
Definition: TestLattice.java:1573
com.cliffc.aa.TestLattice.N.toString
String toString()
Definition: TestLattice.java:118