137da2899SCharles.Forsythimplement Sets; 237da2899SCharles.Forsythinclude "sys.m"; 337da2899SCharles.Forsyth sys: Sys; 437da2899SCharles.Forsythinclude "draw.m"; 537da2899SCharles.Forsythinclude "sets.m"; 637da2899SCharles.Forsyth 737da2899SCharles.Forsythinit() 837da2899SCharles.Forsyth{ 937da2899SCharles.Forsyth sys = load Sys Sys->PATH; 1037da2899SCharles.Forsyth} 1137da2899SCharles.Forsyth 1237da2899SCharles.ForsythBPW: con 32; 1337da2899SCharles.ForsythSHIFT: con 5; 1437da2899SCharles.ForsythMASK: con 31; 1537da2899SCharles.Forsyth 1637da2899SCharles.Forsyth# Set adt contains: 1737da2899SCharles.Forsyth# a - array holding membership of set s for n (0 ≤ n < len a * BPW). 1837da2899SCharles.Forsyth# ∀ n: 0≤n<(len a*BPW), (s.a[n >> SHIFT] & (1 << (n & MASK)) != 0) iff s ∋ n 1937da2899SCharles.Forsyth# m - "most significant bits", extrapolate membership for n >= len a * BPW. 2037da2899SCharles.Forsyth# m is 0 if members are excluded by default, 2137da2899SCharles.Forsyth# or ~0 if members are included by default. 2237da2899SCharles.Forsyth 2337da2899SCharles.Forsythswapops := array[16] of { 2437da2899SCharles.Forsyth byte 2r0000, byte 2r0001, byte 2r0100, byte 2r0101, 2537da2899SCharles.Forsyth byte 2r0010, byte 2r0011, byte 2r0110, byte 2r0111, 2637da2899SCharles.Forsyth byte 2r1000, byte 2r1001, byte 2r1100, byte 2r1101, 2737da2899SCharles.Forsyth byte 2r1010, byte 2r1011, byte 2r1110, byte 2r1111, 2837da2899SCharles.Forsyth}; 2937da2899SCharles.Forsyth 3037da2899SCharles.ForsythSet.X(s1: self Set, o: int, s2: Set): Set 3137da2899SCharles.Forsyth{ 3237da2899SCharles.Forsyth if (len s1.a > len s2.a) { 3337da2899SCharles.Forsyth (s1, s2) = (s2, s1); 3437da2899SCharles.Forsyth o = int swapops[o & 2r1111]; 3537da2899SCharles.Forsyth } 3637da2899SCharles.Forsyth r := Set(0, array[len s2.a] of int); 3737da2899SCharles.Forsyth for (i := 0; i < len s1.a; i++) 3837da2899SCharles.Forsyth r.a[i] = op(o, s1.a[i], s2.a[i]); 3937da2899SCharles.Forsyth for (; i < len s2.a; i++) 4037da2899SCharles.Forsyth r.a[i] = op(o, s1.m, s2.a[i]); 4137da2899SCharles.Forsyth r.m = op(o, s1.m, s2.m); 4237da2899SCharles.Forsyth return r; 4337da2899SCharles.Forsyth} 4437da2899SCharles.Forsyth 4537da2899SCharles.ForsythSet.invert(s: self Set): Set 4637da2899SCharles.Forsyth{ 4737da2899SCharles.Forsyth r := Set(~s.m, array[len s.a] of int); 4837da2899SCharles.Forsyth for (i := 0; i < len s.a; i++) 4937da2899SCharles.Forsyth r.a[i] = ~s.a[i]; 5037da2899SCharles.Forsyth return r; 5137da2899SCharles.Forsyth} 5237da2899SCharles.Forsyth 5337da2899SCharles.Forsyth# copy s, ensuring that the copy is big enough to hold n. 5437da2899SCharles.Forsythcopy(s: Set, n: int): Set 5537da2899SCharles.Forsyth{ 5637da2899SCharles.Forsyth if (n >= 0) { 5737da2899SCharles.Forsyth req := (n >> SHIFT) + 1; 5837da2899SCharles.Forsyth if (req > len s.a) { 5937da2899SCharles.Forsyth a := array[req] of int; 6037da2899SCharles.Forsyth a[0:] = s.a; 6137da2899SCharles.Forsyth for (i := len s.a; i < len a; i++) 6237da2899SCharles.Forsyth a[i] = s.m; 6337da2899SCharles.Forsyth return (s.m, a); 6437da2899SCharles.Forsyth } 6537da2899SCharles.Forsyth } 6637da2899SCharles.Forsyth a: array of int; 6737da2899SCharles.Forsyth if (len s.a > 0) { 6837da2899SCharles.Forsyth a = array[len s.a] of int; 6937da2899SCharles.Forsyth a[0:] = s.a; 7037da2899SCharles.Forsyth } 7137da2899SCharles.Forsyth return (s.m, a); 7237da2899SCharles.Forsyth} 7337da2899SCharles.Forsyth 7437da2899SCharles.ForsythSet.add(s: self Set, n: int): Set 7537da2899SCharles.Forsyth{ 7637da2899SCharles.Forsyth d := n >> SHIFT; 7737da2899SCharles.Forsyth if (s.m && d >= len s.a) 7837da2899SCharles.Forsyth return s; 7937da2899SCharles.Forsyth r := copy(s, n); 8037da2899SCharles.Forsyth r.a[d] |= 1<< (n & MASK); 8137da2899SCharles.Forsyth return r; 8237da2899SCharles.Forsyth} 8337da2899SCharles.Forsyth 8437da2899SCharles.ForsythSet.addlist(s: self Set, ns: list of int): Set 8537da2899SCharles.Forsyth{ 8637da2899SCharles.Forsyth r: Set; 8737da2899SCharles.Forsyth if (s.m == 0) { 8837da2899SCharles.Forsyth max := -1; 8937da2899SCharles.Forsyth for (l := ns; l != nil; l = tl l) 9037da2899SCharles.Forsyth if (hd l > max) 9137da2899SCharles.Forsyth max = hd l; 9237da2899SCharles.Forsyth r = copy(s, max); 9337da2899SCharles.Forsyth } else 9437da2899SCharles.Forsyth r = copy(s, -1); 9537da2899SCharles.Forsyth for (; ns != nil; ns = tl ns) { 9637da2899SCharles.Forsyth n := hd ns; 9737da2899SCharles.Forsyth d := n >> SHIFT; 9837da2899SCharles.Forsyth if (d < len r.a) 9937da2899SCharles.Forsyth r.a[d] |= 1 << (n & MASK); 10037da2899SCharles.Forsyth } 10137da2899SCharles.Forsyth return r; 10237da2899SCharles.Forsyth} 10337da2899SCharles.Forsyth 10437da2899SCharles.Forsyth 10537da2899SCharles.ForsythSet.del(s: self Set, n: int): Set 10637da2899SCharles.Forsyth{ 10737da2899SCharles.Forsyth d := n >> SHIFT; 10837da2899SCharles.Forsyth if (!s.m && d >= len s.a) 10937da2899SCharles.Forsyth return s; 11037da2899SCharles.Forsyth r := copy(s, n); 11137da2899SCharles.Forsyth r.a[d] &= ~(1 << (n & MASK)); 11237da2899SCharles.Forsyth return r; 11337da2899SCharles.Forsyth} 11437da2899SCharles.Forsyth 11537da2899SCharles.ForsythSet.holds(s: self Set, n: int): int 11637da2899SCharles.Forsyth{ 11737da2899SCharles.Forsyth d := n >> SHIFT; 11837da2899SCharles.Forsyth if (d >= len s.a) 11937da2899SCharles.Forsyth return s.m; 12037da2899SCharles.Forsyth return s.a[d] & (1 << (n & MASK)); 12137da2899SCharles.Forsyth} 12237da2899SCharles.Forsyth 12337da2899SCharles.ForsythSet.limit(s: self Set): int 12437da2899SCharles.Forsyth{ 12537da2899SCharles.Forsyth for (i := len s.a - 1; i >= 0; i--) 12637da2899SCharles.Forsyth if (s.a[i] != s.m) 12737da2899SCharles.Forsyth return (i<<SHIFT) + topbit(s.m ^ s.a[i]); 12837da2899SCharles.Forsyth return 0; 12937da2899SCharles.Forsyth} 13037da2899SCharles.Forsyth 13137da2899SCharles.ForsythSet.eq(s1: self Set, s2: Set): int 13237da2899SCharles.Forsyth{ 13337da2899SCharles.Forsyth if (len s1.a > len s2.a) 13437da2899SCharles.Forsyth (s1, s2) = (s2, s1); 13537da2899SCharles.Forsyth for (i := 0; i < len s1.a; i++) 13637da2899SCharles.Forsyth if (s1.a[i] != s2.a[i]) 13737da2899SCharles.Forsyth return 0; 13837da2899SCharles.Forsyth for (; i < len s2.a; i++) 13937da2899SCharles.Forsyth if (s1.m != s2.a[i]) 14037da2899SCharles.Forsyth return 0; 14137da2899SCharles.Forsyth return s1.m == s2.m; 14237da2899SCharles.Forsyth} 14337da2899SCharles.Forsyth 14437da2899SCharles.ForsythSet.isempty(s: self Set): int 14537da2899SCharles.Forsyth{ 14637da2899SCharles.Forsyth return Set(0, nil).eq(s); 14737da2899SCharles.Forsyth} 14837da2899SCharles.Forsyth 14937da2899SCharles.ForsythSet.msb(s: self Set): int 15037da2899SCharles.Forsyth{ 15137da2899SCharles.Forsyth return s.m != 0; 15237da2899SCharles.Forsyth} 15337da2899SCharles.Forsyth 15437da2899SCharles.ForsythSet.bytes(s: self Set, n: int): array of byte 15537da2899SCharles.Forsyth{ 15637da2899SCharles.Forsyth m := (s.limit() >> 3) + 1; 15737da2899SCharles.Forsyth if(m > n) 15837da2899SCharles.Forsyth n = m; 15937da2899SCharles.Forsyth d := array[n] of byte; 16037da2899SCharles.Forsyth # XXX this could proably be made substantially faster by unrolling the 16137da2899SCharles.Forsyth # loop a little. 16237da2899SCharles.Forsyth for(i := 0; i < len d; i++){ 16337da2899SCharles.Forsyth j := i >> 2; 16437da2899SCharles.Forsyth if(j >= len s.a) 16537da2899SCharles.Forsyth d[i] = byte s.m; 16637da2899SCharles.Forsyth else 16737da2899SCharles.Forsyth d[i] = byte (s.a[j] >> ((i & 3) << 3)); 16837da2899SCharles.Forsyth } 16937da2899SCharles.Forsyth return d; 17037da2899SCharles.Forsyth} 17137da2899SCharles.Forsyth 17237da2899SCharles.Forsythbytes2set(d: array of byte): Set 17337da2899SCharles.Forsyth{ 17437da2899SCharles.Forsyth if(len d == 0) 17537da2899SCharles.Forsyth return (0, nil); 17637da2899SCharles.Forsyth a := array[(len d + 3) >> 2] of int; # round up 17737da2899SCharles.Forsyth n := len d >> 2; 17837da2899SCharles.Forsyth for(i := 0; i < n; i++){ 17937da2899SCharles.Forsyth j := i << 2; 18037da2899SCharles.Forsyth a[i] = int d[j] + (int d[j+1] << 8) + (int d[j+2] << 16) + (int d[j+3] << 24); 18137da2899SCharles.Forsyth } 18237da2899SCharles.Forsyth msb := ~(int (d[len d - 1] >> 7) - 1); 18337da2899SCharles.Forsyth j := i << 2; 18437da2899SCharles.Forsyth case len d & 3 { 18537da2899SCharles.Forsyth 0 => 18637da2899SCharles.Forsyth ; 18737da2899SCharles.Forsyth 1 => 18837da2899SCharles.Forsyth a[i] = int d[j] | (msb & int 16rffffff00); 18937da2899SCharles.Forsyth 2 => 19037da2899SCharles.Forsyth a[i] = int d[j] | (int d[j+1] << 8) | (msb & int 16rffff0000); 19137da2899SCharles.Forsyth 3 => 19237da2899SCharles.Forsyth a[i] = int d[j] | (int d[j+1] << 8) | (int d[j+2] << 16) | (msb & int 16rff000000); 19337da2899SCharles.Forsyth } 19437da2899SCharles.Forsyth return (msb, a); 19537da2899SCharles.Forsyth} 19637da2899SCharles.Forsyth 19737da2899SCharles.ForsythSet.str(s: self Set): string 19837da2899SCharles.Forsyth{ 19937da2899SCharles.Forsyth str: string; 20037da2899SCharles.Forsyth 20137da2899SCharles.Forsyth # discard all top bits that are the same as msb. 20237da2899SCharles.Forsyth sig := 0; 20337da2899SCharles.Forsythloop: 20437da2899SCharles.Forsyth for (i := len s.a - 1; i >= 0; i--) { 20537da2899SCharles.Forsyth t := 16rf << (BPW - 4); 20637da2899SCharles.Forsyth sig = 8; 20737da2899SCharles.Forsyth while (t != 0) { 20837da2899SCharles.Forsyth if ((s.m & t) != (s.a[i] & t)) 20937da2899SCharles.Forsyth break loop; 21037da2899SCharles.Forsyth sig--; 21137da2899SCharles.Forsyth t = (t >> 4) & 16r0fffffff; # logical shift right 21237da2899SCharles.Forsyth } 21337da2899SCharles.Forsyth } 21437da2899SCharles.Forsyth if (i >= 0) { 21537da2899SCharles.Forsyth top := s.a[i]; 21637da2899SCharles.Forsyth if (sig < 8) # shifting left by 32 bits is undefined. 21737da2899SCharles.Forsyth top &= (1 << (sig << 2)) - 1; 21837da2899SCharles.Forsyth str = sys->sprint("%.*ux", sig, top); 21937da2899SCharles.Forsyth for (i--; i >= 0; i--) 22037da2899SCharles.Forsyth str += sys->sprint("%.8ux", s.a[i]); 22137da2899SCharles.Forsyth } 22237da2899SCharles.Forsyth return str + ":" + string (s.m & 1); 22337da2899SCharles.Forsyth} 22437da2899SCharles.Forsyth 22537da2899SCharles.Forsythstr2set(str: string): Set 22637da2899SCharles.Forsyth{ 22737da2899SCharles.Forsyth n := len str; 22837da2899SCharles.Forsyth if (n < 2 || str[n - 2] != ':') 22937da2899SCharles.Forsyth return (0, nil); 23037da2899SCharles.Forsyth c := str[n - 1]; 23137da2899SCharles.Forsyth if (c != '0' && c != '1') 23237da2899SCharles.Forsyth return (0, nil); 23337da2899SCharles.Forsyth msb := ~(c - '1'); 23437da2899SCharles.Forsyth 23537da2899SCharles.Forsyth n -= 2; 23637da2899SCharles.Forsyth if (n == 0) 23737da2899SCharles.Forsyth return (msb, nil); 23837da2899SCharles.Forsyth req := ((n * 4 - 1) >> SHIFT) + 1; 23937da2899SCharles.Forsyth a := array[req] of int; 24037da2899SCharles.Forsyth d := 0; 24137da2899SCharles.Forsyth for (i := n; i > 0; ) { 24237da2899SCharles.Forsyth j := i - 8; 24337da2899SCharles.Forsyth if (j < 0) 24437da2899SCharles.Forsyth j = 0; 24537da2899SCharles.Forsyth a[d++] = hex2int(str[j:i], msb); 24637da2899SCharles.Forsyth i = j; 24737da2899SCharles.Forsyth } 24837da2899SCharles.Forsyth return (msb, a); 24937da2899SCharles.Forsyth} 25037da2899SCharles.Forsyth 25137da2899SCharles.ForsythSet.debugstr(s: self Set): string 25237da2899SCharles.Forsyth{ 25337da2899SCharles.Forsyth str: string; 25437da2899SCharles.Forsyth for (i := len s.a - 1; i >= 0; i--) 25537da2899SCharles.Forsyth str += sys->sprint("%ux:", s.a[i]); 25637da2899SCharles.Forsyth str += sys->sprint(":%ux", s.m); 25737da2899SCharles.Forsyth return str; 25837da2899SCharles.Forsyth} 25937da2899SCharles.Forsyth 26037da2899SCharles.Forsythset(): Set 26137da2899SCharles.Forsyth{ 26237da2899SCharles.Forsyth return (0, nil); 26337da2899SCharles.Forsyth} 26437da2899SCharles.Forsyth 26537da2899SCharles.Forsythhex2int(s: string, fill: int): int 26637da2899SCharles.Forsyth{ 26737da2899SCharles.Forsyth n := fill; 26837da2899SCharles.Forsyth for (i := 0; i < len s; i++) { 26937da2899SCharles.Forsyth c := s[i]; 27037da2899SCharles.Forsyth if (c >= '0' && c <= '9') 27137da2899SCharles.Forsyth c -= '0'; 27237da2899SCharles.Forsyth else if (c >= 'a' && c <= 'f') 27337da2899SCharles.Forsyth c -= 'a' - 10; 27437da2899SCharles.Forsyth else if (c >= 'A' && c <= 'F') 27537da2899SCharles.Forsyth c -= 'A' - 10; 27637da2899SCharles.Forsyth else 27737da2899SCharles.Forsyth c = 0; 27837da2899SCharles.Forsyth n = (n << 4) | c; 27937da2899SCharles.Forsyth } 28037da2899SCharles.Forsyth return n; 28137da2899SCharles.Forsyth} 28237da2899SCharles.Forsyth 28337da2899SCharles.Forsythop(o: int, a, b: int): int 28437da2899SCharles.Forsyth{ 28537da2899SCharles.Forsyth case o & 2r1111 { 28637da2899SCharles.Forsyth 2r0000 => return 0; 28737da2899SCharles.Forsyth 2r0001 => return ~(a | b); 28837da2899SCharles.Forsyth 2r0010 => return a & ~b; 28937da2899SCharles.Forsyth 2r0011 => return ~b; 29037da2899SCharles.Forsyth 2r0100 => return ~a & b; 29137da2899SCharles.Forsyth 2r0101 => return ~a; 29237da2899SCharles.Forsyth 2r0110 => return a ^ b; 29337da2899SCharles.Forsyth 2r0111 => return ~(a & b); 29437da2899SCharles.Forsyth 2r1000 => return a & b; 29537da2899SCharles.Forsyth 2r1001 => return ~(a ^ b); 29637da2899SCharles.Forsyth 2r1010 => return a; 29737da2899SCharles.Forsyth 2r1011 => return a | ~b; 29837da2899SCharles.Forsyth 2r1100 => return b; 299*6e425a9dSCharles.Forsyth 2r1101 => return ~a | b; 30037da2899SCharles.Forsyth 2r1110 => return a | b; 30137da2899SCharles.Forsyth 2r1111 => return ~0; 30237da2899SCharles.Forsyth } 30337da2899SCharles.Forsyth return 0; 30437da2899SCharles.Forsyth} 30537da2899SCharles.Forsyth 30637da2899SCharles.Forsythtopbit(v: int): int 30737da2899SCharles.Forsyth{ 30837da2899SCharles.Forsyth if (v == 0) 30937da2899SCharles.Forsyth return 0; 31037da2899SCharles.Forsyth (b, n, mask) := (1, 16, int 16rffff0000); 31137da2899SCharles.Forsyth while (n != 0) { 31237da2899SCharles.Forsyth if (v & mask) { 31337da2899SCharles.Forsyth b += n; 31437da2899SCharles.Forsyth v >>= n; # could return if v==0 here if we thought it worth it 31537da2899SCharles.Forsyth } 31637da2899SCharles.Forsyth n >>= 1; 31737da2899SCharles.Forsyth mask >>= n; 31837da2899SCharles.Forsyth } 31937da2899SCharles.Forsyth return b; 32037da2899SCharles.Forsyth} 32137da2899SCharles.Forsyth 32237da2899SCharles.Forsythnbits(n: int): int 32337da2899SCharles.Forsyth{ 32437da2899SCharles.Forsyth n = ((n >> 1) & 16r55555555) + (n & 16r55555555) ; 32537da2899SCharles.Forsyth n = ((n >> 2) & 16r33333333) + (n & 16r33333333) ; 32637da2899SCharles.Forsyth n = ((n >> 4) + n) & 16r0F0F0F0F ; 32737da2899SCharles.Forsyth n = ((n >> 8) + n) ; 32837da2899SCharles.Forsyth return ((n >> 16) + n) & 16rFF ; 32937da2899SCharles.Forsyth} 330