diff options
| author | Cliff Click <cliffc@acm.org> | 2024-08-06 13:09:38 +0100 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-08-10 11:11:18 -0700 |
| commit | c920fc35d7c7600a5c7fbe898572ae0a7b2aa4cc (patch) | |
| tree | 6800126f6615206602eceaf65b8039f71021ec6a /docs | |
| parent | c7dd16e7158b0fda0ea56e888ab3cfb95dd365e2 (diff) | |
| download | Simple-c920fc35d7c7600a5c7fbe898572ae0a7b2aa4cc.tar.gz Simple-c920fc35d7c7600a5c7fbe898572ae0a7b2aa4cc.zip | |
Chapter 14: Narrow types
Co-authored-by: Thalia Archibald <thalia@archibald.dev>
Co-authored-by: Tamás Hadházy <85063808+Hels15@users.noreply.github.com>
Co-authored-by: Dibyendu Majumdar <mobile@majumdar.org.uk>
Co-authored-by: tannal <tannal2409@gmail.com>
Co-authored-by: hadha <helsgithub15@gmail.com>
Co-authored-by: XmiliaH <45106915+XmiliaH@users.noreply.github.com>
Co-authored-by: RobertObkircher <robert.obkircher@gmail.com>
Co-authored-by: Robert Obkircher <robert.obkircher@gmail.com>
Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/chapter14/14-grammar.md | 124 | ||||
| -rw-r--r-- | docs/chapter14/Makefile | 12 | ||||
| -rw-r--r-- | docs/chapter14/README.md | 350 | ||||
| -rw-r--r-- | docs/chapter14/lattice.gv | 202 | ||||
| -rw-r--r-- | docs/chapter14/lattice.svg | 691 |
5 files changed, 1379 insertions, 0 deletions
diff --git a/docs/chapter14/14-grammar.md b/docs/chapter14/14-grammar.md new file mode 100644 index 00000000..a6d4df42 --- /dev/null +++ b/docs/chapter14/14-grammar.md @@ -0,0 +1,124 @@ +# Grammar for Chapter 14 + +```antlrv4 +grammar SimpleLanguage; + +program : block EOF ; + +block : statement+ ; + + +statement + : '{' block '}' + | returnStatement + | ifStatement + | whileStatement + | breakStatement + | continueStatement + | metaStatement + | structDeclaration + | expressionStatement + ; + + +returnStatement : 'return' expression ';' ; + +ifStatement : 'if' '(' expression ')' statement ('else' statement)? ; + +whileStatement : 'while' '(' expression ')' statement ; + +breakStatement : 'break' ';' ; + +continueStatement : 'continue' ';' ; + +metaStatement : '#showGraph' ';' ; + +structDeclaration : 'struct' IDENTIFIER '{' fields '}' ; + +fields : field+ ; + +field : type IDENTIFIER ';' ; + + +expressionStatement + : type IDENTIFIER ';' + | type IDENTIFIER '=' expression ';' + | IDENTIFIER '=' expression ';' + | expression + ; + +PRIMTYPE + : 'int' + | 'i8' + | 'i16' + | 'i32' + | 'i64' + | 'u8' + | 'u16' + | 'u32' + | 'flt' + | 'f32' + | 'f64' + | 'bool' + ; + +type + : PRIMTYPE + | typeName ('?')? + ; + +typeName : IDENTIFIER ; + + +expression : bitWiseExpression ; + +bitWiseExpression + : comparisonExpression ( '&' | '|' | '^' ) comparisonExpression)* + ; + +comparisonExpression + : shiftExpression (('==' | '!='| '>'| '<'| '>='| '<=') shiftExpression)* + ; + +shiftExpression + : additiveExpression ( '<<' | '>>>' | '>>' ) additiveExpression)* + ; + +additiveExpression + : multiplicativeExpression (('+' | '-') multiplicativeExpression)* + ; + +multiplicativeExpression + : unaryExpression (('*' | '/') unaryExpression)* + ; + +unaryExpression + : ('-') unaryExpression + | '!' unaryExpression + | primaryExpression postFix* + ; + +primaryExpression + : INTEGER_LITERAL + | '(' expression ')' + | 'true' + | 'false' + | 'null' + | newExpression + | IDENTIFIER + ; + +newExpression : 'new' IDENTIFIER ; + +postFix : '.' IDENTIFIER [ '=' expression ] ; + +INTEGER_LITERAL + : [1-9]DIGIT* + | [0] + ; + +IDENTIFIER : NON_DIGIT (NON_DIGIT | DIGIT)* ; + +NON_DIGIT: [a-zA-Z_]; +DIGIT: [0-9]; +``` diff --git a/docs/chapter14/Makefile b/docs/chapter14/Makefile new file mode 100644 index 00000000..12659b8f --- /dev/null +++ b/docs/chapter14/Makefile @@ -0,0 +1,12 @@ +GV := $(wildcard *.gv) +SVG := $(patsubst %.gv,%.svg,$(GV)) + +.PHONY: all +all: $(SVG) + +%.svg: %.gv + dot -Tsvg $< > $@ + +.PHONY: clean +clean: + @rm -f $(SVG) diff --git a/docs/chapter14/README.md b/docs/chapter14/README.md new file mode 100644 index 00000000..49b0c5b9 --- /dev/null +++ b/docs/chapter14/README.md @@ -0,0 +1,350 @@ +# Chapter 14: Narrow types + +# Table of Contents + +1. [Narrow Word Types](#narrow-or-sub-word-types) +2. [OverFlow handling](#overflow-handling) +3. [Integer ranges](#integer-ranges) +4. [Bitwise operations](#examples) +5. [Precedence](#precedence) +6. [Type lattice](#type-implementation) +7. [Nodes](#nodes) + + +In this chapter, we add sub-word integer types. + +You can also read [this chapter](https://github.com/SeaOfNodes/Simple/tree/linear-chapter14) in a linear Git revision history on the [linear](https://github.com/SeaOfNodes/Simple/tree/linear) branch and [compare](https://github.com/SeaOfNodes/Simple/compare/linear-chapter13...linear-chapter14) it to the previous chapter. + +## Narrow or sub-word types + +Narrow or sub-worded integer types refer to integer data types that occupy less memory (fewer bits) than the standard or "full-width"(Typically 32, or 64 bits) integer types provided by a system or programming language. + + +As a prelude to arrays, especially arrays of bytes common in all networking +codes, Simple needs some way to manipulate sub-word integer types. +Computations are always done in 64 bits for both integer and float ops, but +will be truncated (rounded) on a variable or field assignment, and (sign) +extended on a load. + +```java +i8 x = 123456789; +if( x != 21 ) + return false; +return true; +``` + +The variable `x` is limited to 8 bits signed. Assigning the vary large value +`123456789` (hex `0x75BCD15`) simply truncates to 8 bits yielding `21 (0x15)`. +The value is sign-extended on a load. + +```java +i16 x = 123456789; +if( x != -13035 ) + return false; +return true; +``` + +The variable `x` is limited to 16 bits signed. Assigning the vary large value +`0x75BCD15` simply truncates to 16 bits yielding `0xCD15`. The value is +sign-extended on a load yielding `-13035 (0xFFFF FFFF FFFF CD15)`. + +```java +u16 x = 123456789; +if( x != 52501 ) + return false; +return true; +``` + +The variable `x` is limited to 16 bits unsigned. Assigning the vary large value +`0x75BCD15` simply truncates to 16 bits yielding `0xCD15`. The value is +zero-extended on a load yielding `52501 (0x0000 0000 0000 CD15)`. + +Similarly, floats can be limited to IEEE754 32-bit standard format and will be +rounded when assigned, and inflated to 64-bits when loaded. + +The complete list of primitive types is now: + +| Data Type | Size (Bits) | Description | +|-----------|-------------|--------------------------------------------------------------| +| `int`, `i64` | 64 | 64-bit signed integer, matching modern hardware. | +| `u64` | 64 | **Not implemented**, hints at behavior beyond 64-bit. | +| `i32` | 32 | 32-bit signed integer, sign-extended on load. | +| `u32` | 32 | 32-bit unsigned integer, zero-extended on load. | +| `i16` | 16 | 16-bit signed integer, sign-extended on load. | +| `u16` | 16 | 16-bit unsigned integer, zero-extended on load. | +| `i8` | 8 | 8-bit signed integer, sign-extended on load. | +| `u8` | 8 | 8-bit unsigned integer, zero-extended on load. | +| `i1` | 1 | 1-bit signed integer, sign-extended on load. | +| `u1` | 1 | 1-bit unsigned integer, zero-extended on load. | +| `bool` | 1 | Alias for `u1`. | +| `flt`, `f64`| 64 | IEEE 754 64-bit floating-point number, often called a double. | +| `f32` | 32 | IEEE 754 32-bit floating-point number. | + +## Overflow handling + +An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold. +There are several cases of overflow: + +#### Unsigned(fixed-width) integer overflow: + +```java +u8 a = 255; +u8 b = a + 1; // match u8 type against expr.type +// a = 256 +// u8 = [0...255] +return b; +``` +The expression type does not match the type that was provided. expr: ConstantNode(256) t: u8(0, 255) +```java +private Node parseExpressionStatement() { + Type t = type(); // u8 = [0...255] + ... + // expr.type = TypeInteger(256); + // Auto-narrow wide ints to narrow ints + expr = zsMask(expr,t); +} +``` +Since it is unsigned we just do a bitmask on the new value that overflows the specified type: +The operands to the "bitwise AND" are the values(256) and the mask(255, max boundary). +This is called truncating. + +`ZsMask:` +```java + // zero/sign extend. "i" is limited to either classic unsigned (min==0) or + // classic signed (min=minus-power-of-2); max=power-of-2-minus-1. +private Node zsMask(Node val, Type t ) { + if( !(val._type instanceof TypeInteger tval && t instanceof TypeInteger t0 && !tval.isa(t0)) ) { + if( !(val._type instanceof TypeFloat tval && t instanceof TypeFloat t0 && !tval.isa(t0)) ) + return val; + // Float rounding + return new RoundF32Node(val).peephole(); + } + if( t0._min==0 ) // Unsigned + return new AndNode(val,new ConstantNode(TypeInteger.constant(t0._max)).peephole()).peephole(); + // Signed extension + int shift = Long.numberOfLeadingZeros(t0._max)-1; + Node shf = new ConstantNode(TypeInteger.constant(shift)).peephole(); + if( shf._type==TypeInteger.ZERO ) + return val; + return new SarNode(new ShlNode(val,shf.keep()).peephole(),shf.unkeep()).peephole(); +} +``` + +The truncation is done by the `AndNode`: +```java +... +if( t0._min==0 ) // Unsigned + return new AndNode(val,con(t0._max)).peephole(); +``` +Since they are constants, after calling peephole it truns into`256 & 255` = 0; +Output: +``` +return 0; +``` + +#### Maximum integer overflow +```java +i64 a = 9223372036854775807; +i64 b = a + 1; +return b; +``` +When we are computing the addition, we make sure they don't overflow: + +`AddNode.overflow:` +```java +private static boolean overflow( long x, long y ) { + if( (x ^ y ) < 0 ) return false; // unequal signs, never overflow + return (x ^ (x + y)) < 0; // sum has unequal signs, so overflow +} +``` +`AddNode.compute` +```java +... +// Fold ranges like {0-1} + {2-3} into {2-4}. +if( !overflow(i1._min,i2._min) && + !overflow(i1._max,i2._max) ) + return TypeInteger.make(i1._min+i2._min,i1._max+i2._max); +``` +Here **x + y** overflows and becomes **negative**, x ^ negative = negative. Any negative number is less than 0, so it returns true. +If it **overflows** we just return the bottom type of TypeInteger. +``` + return TypeInteger.BOT; // [] +``` +However, in our case we are dealing with constants, so we just allow the overflow naturally here: +```java +// i1: 9223372036854775807 +// i2: 1 +// i1 + i2 will overflow. +return TypeInteger.constant(i1.value()+i2.value()); // -9223372036854775808; +``` + +#### Adding constant ranges +```java +u8 a = 12; +u8 b = 13; +u8 c = 124; +u8 d = a + b + c; +return d; +``` +if `is_con` is true, then generally we can state: `min = max`. +Such that: +```java +public static TypeInteger make(boolean is_con, long con) { + return make(is_con ? con : (con==0 ? Long.MAX_VALUE : Long.MIN_VALUE), + is_con ? con : (con==0 ? Long.MIN_VALUE : Long.MAX_VALUE)); +``` +- This results in: +```java +return make(con, con); +``` + +`value()` is only called in constants, e.g `_min == _max;` invariants holds, then since +both `min_` and `max_` are equal, we can return either one. + +This is the same as regular additions: +```java +public long value() { assert isConstant(); return _min; } +``` + +#### Truncate(2) + +```java +u8 a = arg; // arg & 255 +u8 b = arg; // arg & 255(same as a) +u8 c = a + b; // (arg&255)*2, type = TypeInteger.BOT +return c; // (((arg&255)*2)&255), type = TypeInteger.U8 +``` + +Same as before, **arg** turns into **(arg&255)**, this node is then inserted into the **GVN** table and **b** retrieves this value. +The AddNode peephole will change them into `((arg&255)*2`, and put on extra mask +on the expression to keep it in the valid boundaries. + + +## Integer ranges +Link hacker's delight here. + +For range math, visit:[^1] +## Bitwise operations +We support the following bitwise operators: +And `&`, Or `|`, Xor `^`, Shift left `<<`, Shift right `>>`, Shift right zero `>>>` + +| Operator | Symbol | Description | +|--------------------------|---------|---------------------------------------------------------------------------------------------------------| +| **And** | `&` | Performs a bitwise AND operation. | +| **Or** | `\|` | Performs a bitwise OR (inclusive OR) operation. | +| **Xor** | `^` | Performs a bitwise XOR (exclusive OR) operation. | +| **Shift Left** | `<<` | Shifts bits to the left, filling with zeros. | +| **Shift Right** | `>>` | Shifts bits to the right, any vacated bit postions are filled by replicating the value of the sign bit. | +| **Unsigned Right Shift** | `>>>` | Shifts bits to the right, any vacated bit postions are always filled with zero | + +Note `>>>` is a logical shift and not an arithmetic shift. + +#### AndNode: + +##### lhs & -1 = lhs; +```java +// And of -1. We do not check for (-1&x) because this will already +// canonicalize to (x&-1) +if( t2.isConstant() && t2 instanceof TypeInteger i && i.value()==-1 ) +return lhs; + +``` + +#### OrNode: +##### lhs | 0 = lhs; +```java +// Or of 0. We do not check for (0|x) because this will already +// canonicalize to (x|0) +if( t2.isConstant() && t2 instanceof TypeInteger i && i.value()==0 ) +return lhs; + +``` + +#### Shift right +lhs >> 0 = lhs; +```java +// Sar of 0. +if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 ) + return lhs; +``` + +#### Shift left +lhs << 0 = lhs; +```java +// Shl of 0. +if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 ) + return lhs; + +``` +#### Unsigned right shift +lhs >>> 0 = lhs; +```java +// Shr of 0. +if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 ) +return lhs; +``` + +#### XorNode: +##### lhs ^ 0 = lhs; +```java +// Xor of 0. We do not check for (0^x) because this will already +// canonicalize to (x^0) +if( t2.isConstant() && t2 instanceof TypeInteger i && i.value()==0 ) + return lhs; + +``` +### precedence + +Bitwise operators have the lowest precedence, e.g +``` +arg + 123 & 3 = (arg + 123) & 3 +``` + +## Type Implementation + +The <font style="background-color:lightblue">TypeInteger type</font> class is +reworked to support a full range of min/max values. At this time, only some +power-of-2 sized ranges are exposed to the programmer but the optimizer +internally supports all ranges. The MEET operation takes the min-of-mins and +max-of-maxes. The DUAL operation inverts the min and max. + +Example: the constant `0` has `[0...0]`. + +Example: the `bool` type has the range `[0...1]`. + +Example: the `u8` type has the range `[0...255]`. + +Example: the `i8` type has the range `[-128...127]`. + +Example: the `dual` of `bool` is `[1...0]` (just swap min and max). + +The <font style="background-color:aqua">TypeFloat</font> class is also reworked to support 32-bit and 64-bit sizes. + + + +### meet: + +Meet of two ranges: +```java +@Override +public Type xmeet(Type other) { +// Invariant from caller: 'this' != 'other' and same class (TypeInteger) +TypeInteger i = (TypeInteger)other; // Contract +return make(Math.min(_min,i._min), Math.max(_max,i._max)); +} +``` +Combine all values that could possibly occur within either range. + +## Nodes + +Added this Chapter are some bit-manipulation Nodes representing common hardware +ops to mask, shift, sign-extend and round bits. The truncation and extension +logic uses these. They are otherwise very similar to the previous +`Add/Sub/Mul/Div` Nodes but with slightly different constant math and +slightly different `idealize()` calls. + + + +[^1]: Hacker's delight. + 4-2 Propagating Bounds through Add's and Subtract's + diff --git a/docs/chapter14/lattice.gv b/docs/chapter14/lattice.gv new file mode 100644 index 00000000..f16a9768 --- /dev/null +++ b/docs/chapter14/lattice.gv @@ -0,0 +1,202 @@ +digraph Lattice { + compound = true; + // Define nodes + splines=false; + node [shape=circle, style=filled]; + nodesep=0.6; + + TOP [label=<<B>⊤</B >>, fillcolor=black, fontcolor=white]; + BOT [label=<<B>⊥</B>>, fillcolor=black, fontcolor=white]; + + // ---------------------- + // Control + XCTRL [label=<<B>⊤</B >:ctrl>, fillcolor=yellow, shape=oval]; + CTRL [label=<<B>⊥</B>:ctrl>, fillcolor=yellow, shape=oval]; + + TOP -> XCTRL; + XCTRL -> CTRL; + CTRL -> BOT; + + // ---------------------- + // Integers + INT_TOP [label=<<B>⊤</B >:int>, fillcolor=lightblue, shape=oval]; + INT_BOT [label=<<B>⊥</B>:int>, fillcolor=lightblue, shape=oval]; + + INT_HI [label="max < min" , fillcolor=lightblue, shape=oval]; + INT_XBOOL [label="1...0", fillcolor=lightblue, shape=oval]; + INT_CON [label="constants", fillcolor=lightblue, shape=oval]; + INT_CON0 [label="0", fillcolor=lightblue]; + INT_CON1 [label="1", fillcolor=lightblue]; + INT_BOOL [label="0...1", fillcolor=lightblue,shape=oval]; + INT_LO [label="max > min" , fillcolor=lightblue, shape=oval]; + + TOP -> INT_TOP; + INT_TOP -> INT_HI; + INT_HI -> INT_XBOOL; + INT_XBOOL -> INT_CON0; + INT_XBOOL -> INT_CON1; + INT_HI -> INT_CON; + INT_CON0 -> INT_BOOL; + INT_CON1 -> INT_BOOL; + INT_BOOL -> INT_LO; + INT_CON -> INT_LO; + INT_LO -> INT_BOT; + INT_BOT -> BOT; + + INT_CON0 -> INT_CON1 -> INT_CON [style=invis]; + + // ---------------------- + // Floats + FLT_TOP [label=<<B>⊤</B >:flt>, fillcolor=aqua, shape=oval]; + FLT_BOT [label=<<B>⊥</B>:flt>, fillcolor=aqua, shape=oval]; + + FLT_CON64 [label="64b consts\n[excludes\n32b consts]" , fillcolor=aqua, shape=oval]; + FLT_CON32 [label="32b consts", fillcolor=aqua, shape=oval]; + FLT_CONPI [label="3.14159...", fillcolor=aqua, shape=oval]; + FLT_X32 [label="~f32", fillcolor=aqua]; + FLT_CON0 [label="0." , fillcolor=aqua]; + FLT_32 [label="f32" , fillcolor=aqua]; + + TOP -> FLT_TOP; + FLT_TOP -> FLT_CON64 + FLT_TOP -> FLT_CONPI + FLT_CON64 -> FLT_BOT + FLT_CONPI -> FLT_BOT + + FLT_TOP -> FLT_X32; + FLT_X32 -> FLT_CON0; + FLT_X32 -> FLT_CON32; + FLT_CON0 -> FLT_32; + FLT_CON32 -> FLT_32; + FLT_32 -> FLT_BOT + + FLT_BOT -> BOT; + + FLT_CON0 -> FLT_CON32 -> FLT_CONPI -> FLT_CON64 [style=invis]; + + + // ---------------------- + // Pointers, just a boolean nil/not and a struct + PTR [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TR><TD BGCOLOR="green"><FONT color="white">*ptr</FONT></TD></TR> + <TR><TD BGCOLOR="lightgreen">struct</TD></TR> + </TABLE> + >]; + PTR0 [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TR><TD BGCOLOR="green"><FONT color="white">*ptr?</FONT></TD></TR> + <TR><TD BGCOLOR="lightgreen">struct</TD></TR> + </TABLE> + >]; + + TOP -> PTR; + PTR -> PTR0; + PTR0 -> BOT; + + // ---------------------- + // Structs + STRUCT_TOP [label=<<B>⊤</B >:struct>, fillcolor=lightgreen, shape=oval]; + STRUCT_BOT [label=<<B>⊥</B>:struct>, fillcolor=lightgreen, shape=oval]; + + STRUCT_S1 [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR> + </TABLE> + >]; + STRUCT_S2 [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR> + <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR> + </TABLE> + >]; + STRUCT_SN [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR> + <TR><TD BGCOLOR="lightgreen">... </TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR> + <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR> + </TABLE> + >]; + + + TOP -> STRUCT_TOP; + STRUCT_TOP -> STRUCT_S1; + STRUCT_TOP -> STRUCT_S2; + STRUCT_TOP -> STRUCT_SN; + STRUCT_S1 -> STRUCT_BOT; + STRUCT_S2 -> STRUCT_BOT; + STRUCT_SN -> STRUCT_BOT; + STRUCT_BOT -> BOT; + + STRUCT_S1 -> STRUCT_S2 -> STRUCT_SN [style=invis]; + + // ---------------------- + // Memory + MEM_TOP [label=<<B>⊤</B >:mem>, fillcolor=blue, fontcolor=white, shape=oval]; + MEM_BOT [label=<<B>⊥</B>:mem>, fillcolor=blue, fontcolor=white, shape=oval]; + MEM_ALIAS1 [label="#1" , fillcolor=blue, fontcolor=white]; + MEM_ALIASDOTS [label="..." , fillcolor=blue, fontcolor=white, shape=oval]; + MEM_ALIASN [label="#n" , fillcolor=blue, fontcolor=white]; + + TOP -> MEM_TOP; + MEM_TOP -> MEM_ALIAS1; + MEM_TOP -> MEM_ALIASDOTS; + MEM_TOP -> MEM_ALIASN; + MEM_ALIAS1 -> MEM_BOT; + MEM_ALIASDOTS -> MEM_BOT; + MEM_ALIASN -> MEM_BOT; + MEM_BOT -> BOT; + + MEM_ALIAS1 -> MEM_ALIASDOTS -> MEM_ALIASN [style=invis]; + + // ---------------------- + // Tuples + + TUPLE_TOP [label=<<B>⊤</B >:tuple>, fillcolor=pink, shape=oval]; + TUPLE_BOT [label=<<B>⊥</B>:tuple>, fillcolor=pink, shape=oval]; + + TUPLE1 [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TH><TD BGCOLOR="pink">Tuple</TD></TH> + <TR><TD BGCOLOR="black" ><FONT color="white">type</FONT></TD></TR> + </TABLE> + >]; + TUPLE2 [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TH><TD BGCOLOR="pink">Tuple</TD></TH> + <TR><TD BGCOLOR="black" ><FONT color="white">type</FONT></TD></TR> + <TR><TD BGCOLOR="black" ><FONT color="white">type</FONT></TD></TR> + </TABLE> + >]; + TUPLEN [shape=none, fillcolor=none, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> + <TH><TD BGCOLOR="pink">Tuple</TD></TH> + <TR><TD BGCOLOR="black" ><FONT color="white">type</FONT></TD></TR> + <TR><TD BGCOLOR="black" ><FONT color="white">...</FONT></TD></TR> + <TR><TD BGCOLOR="black" ><FONT color="white">type</FONT></TD></TR> + </TABLE> + >]; + + + TOP -> TUPLE_TOP; + TUPLE_TOP -> TUPLE1; + TUPLE_TOP -> TUPLE2; + TUPLE_TOP -> TUPLEN; + TUPLE1 -> TUPLE_BOT; + TUPLE2 -> TUPLE_BOT; + TUPLEN -> TUPLE_BOT; + TUPLE_BOT -> BOT; + + // ---------------------- + // Additional customization + {rank=same; TOP;} + {rank=same; INT_TOP; FLT_TOP; XCTRL; PTR; STRUCT_TOP; MEM_TOP; TUPLE_TOP} + {rank=same; INT_CON; INT_CON0; INT_CON1; + FLT_CON32; FLT_CON64; FLT_CON0; FLT_CONPI; + STRUCT_S1; STRUCT_S2; STRUCT_SN; + MEM_ALIAS1; MEM_ALIASDOTS; MEM_ALIASN; + TUPLE1; TUPLE2; TUPLEN; + } + {rank=same; INT_BOT; FLT_BOT; CTRL; PTR0; STRUCT_BOT; MEM_BOT; TUPLE_BOT} + {rank=same; BOT;} +} diff --git a/docs/chapter14/lattice.svg b/docs/chapter14/lattice.svg new file mode 100644 index 00000000..99f74ed0 --- /dev/null +++ b/docs/chapter14/lattice.svg @@ -0,0 +1,691 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 12.2.0 (20241103.1931)
+ -->
+<!-- Title: Lattice Pages: 1 -->
+<svg width="1800pt" height="760pt"
+ viewBox="0.00 0.00 1800.00 759.54" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 755.54)">
+<title>Lattice</title>
+<polygon fill="white" stroke="none" points="-4,4 -4,-755.54 1796,-755.54 1796,4 -4,4"/>
+<!-- TOP -->
+<g id="node1" class="node">
+<title>TOP</title>
+<ellipse fill="black" stroke="black" cx="829" cy="-730.42" rx="21.12" ry="21.12"/>
+<text text-anchor="start" x="821.12" y="-725.99" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00" fill="white">⊤</text>
+</g>
+<!-- XCTRL -->
+<g id="node3" class="node">
+<title>XCTRL</title>
+<ellipse fill="yellow" stroke="black" cx="45" cy="-646.79" rx="36.51" ry="18"/>
+<text text-anchor="start" x="26.25" y="-642.74" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="42" y="-642.74" font-family="Times New Roman,serif" font-size="14.00">:ctrl</text>
+</g>
+<!-- TOP->XCTRL -->
+<g id="edge1" class="edge">
+<title>TOP->XCTRL</title>
+<path fill="none" stroke="black" d="M807.62,-727.19C702.73,-716.27 241.49,-668.25 91.97,-652.68"/>
+<polygon fill="black" stroke="black" points="92.33,-649.2 82.02,-651.65 91.61,-656.16 92.33,-649.2"/>
+</g>
+<!-- INT_TOP -->
+<g id="node5" class="node">
+<title>INT_TOP</title>
+<ellipse fill="lightblue" stroke="black" cx="404" cy="-646.79" rx="33.95" ry="18"/>
+<text text-anchor="start" x="387.12" y="-642.74" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="402.88" y="-642.74" font-family="Times New Roman,serif" font-size="14.00">:int</text>
+</g>
+<!-- TOP->INT_TOP -->
+<g id="edge4" class="edge">
+<title>TOP->INT_TOP</title>
+<path fill="none" stroke="black" d="M808.21,-725.42C742.28,-712.76 536.86,-673.31 446.91,-656.03"/>
+<polygon fill="black" stroke="black" points="447.74,-652.63 437.26,-654.18 446.42,-659.5 447.74,-652.63"/>
+</g>
+<!-- FLT_TOP -->
+<g id="node14" class="node">
+<title>FLT_TOP</title>
+<ellipse fill="aqua" stroke="black" cx="636" cy="-646.79" rx="32.41" ry="18"/>
+<text text-anchor="start" x="620.25" y="-642.74" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="636" y="-642.74" font-family="Times New Roman,serif" font-size="14.00">:flt</text>
+</g>
+<!-- TOP->FLT_TOP -->
+<g id="edge18" class="edge">
+<title>TOP->FLT_TOP</title>
+<path fill="none" stroke="black" d="M809.79,-721.29C777.65,-707.7 712.5,-680.14 671.73,-662.91"/>
+<polygon fill="black" stroke="black" points="673.15,-659.7 662.58,-659.03 670.42,-666.15 673.15,-659.7"/>
+</g>
+<!-- PTR -->
+<g id="node22" class="node">
+<title>PTR</title>
+<polygon fill="none" stroke="none" points="856,-673.29 802,-673.29 802,-620.29 856,-620.29 856,-673.29"/>
+<polygon fill="green" stroke="none" points="811,-646.79 811,-669.29 847,-669.29 847,-646.79 811,-646.79"/>
+<polygon fill="none" stroke="black" points="811,-646.79 811,-669.29 847,-669.29 847,-646.79 811,-646.79"/>
+<text text-anchor="start" x="818.12" y="-652.99" font-family="Times New Roman,serif" font-size="14.00" fill="white">*ptr</text>
+<polygon fill="lightgreen" stroke="none" points="811,-624.29 811,-646.79 847,-646.79 847,-624.29 811,-624.29"/>
+<polygon fill="none" stroke="black" points="811,-624.29 811,-646.79 847,-646.79 847,-624.29 811,-624.29"/>
+<text text-anchor="start" x="814" y="-630.49" font-family="Times New Roman,serif" font-size="14.00">struct</text>
+</g>
+<!-- TOP->PTR -->
+<g id="edge33" class="edge">
+<title>TOP->PTR</title>
+<path fill="none" stroke="black" d="M829,-708.82C829,-701.44 829,-692.87 829,-684.54"/>
+<polygon fill="black" stroke="black" points="832.5,-684.57 829,-674.57 825.5,-684.57 832.5,-684.57"/>
+</g>
+<!-- STRUCT_TOP -->
+<g id="node24" class="node">
+<title>STRUCT_TOP</title>
+<ellipse fill="lightgreen" stroke="black" cx="997" cy="-646.79" rx="44.7" ry="18"/>
+<text text-anchor="start" x="972.25" y="-642.74" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="988" y="-642.74" font-family="Times New Roman,serif" font-size="14.00">:struct</text>
+</g>
+<!-- TOP->STRUCT_TOP -->
+<g id="edge36" class="edge">
+<title>TOP->STRUCT_TOP</title>
+<path fill="none" stroke="black" d="M847.95,-720.21C874.78,-707.18 924.42,-683.06 959.01,-666.25"/>
+<polygon fill="black" stroke="black" points="960.39,-669.47 967.86,-661.95 957.34,-663.17 960.39,-669.47"/>
+</g>
+<!-- MEM_TOP -->
+<g id="node29" class="node">
+<title>MEM_TOP</title>
+<ellipse fill="blue" stroke="black" cx="1346" cy="-646.79" rx="43.67" ry="18"/>
+<text text-anchor="start" x="1322" y="-642.74" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00" fill="white">⊤</text>
+<text text-anchor="start" x="1337.75" y="-642.74" font-family="Times New Roman,serif" font-size="14.00" fill="white">:mem</text>
+</g>
+<!-- TOP->MEM_TOP -->
+<g id="edge46" class="edge">
+<title>TOP->MEM_TOP</title>
+<path fill="none" stroke="black" d="M849.91,-726.12C925.08,-714.25 1183.05,-673.52 1294.28,-655.96"/>
+<polygon fill="black" stroke="black" points="1294.7,-659.44 1304.03,-654.42 1293.61,-652.52 1294.7,-659.44"/>
+</g>
+<!-- TUPLE_TOP -->
+<g id="node34" class="node">
+<title>TUPLE_TOP</title>
+<ellipse fill="pink" stroke="black" cx="1619" cy="-646.79" rx="42.65" ry="18"/>
+<text text-anchor="start" x="1595.75" y="-642.74" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="1611.5" y="-642.74" font-family="Times New Roman,serif" font-size="14.00">:tuple</text>
+</g>
+<!-- TOP->TUPLE_TOP -->
+<g id="edge56" class="edge">
+<title>TOP->TUPLE_TOP</title>
+<path fill="none" stroke="black" d="M850.13,-727.23C953.9,-716.51 1410.83,-669.3 1566.7,-653.2"/>
+<polygon fill="black" stroke="black" points="1566.73,-656.71 1576.32,-652.2 1566.01,-649.75 1566.73,-656.71"/>
+</g>
+<!-- BOT -->
+<g id="node2" class="node">
+<title>BOT</title>
+<ellipse fill="black" stroke="black" cx="829" cy="-21.12" rx="21.12" ry="21.12"/>
+<text text-anchor="start" x="821.12" y="-16.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00" fill="white">⊥</text>
+</g>
+<!-- CTRL -->
+<g id="node4" class="node">
+<title>CTRL</title>
+<ellipse fill="yellow" stroke="black" cx="44" cy="-104.75" rx="36.51" ry="18"/>
+<text text-anchor="start" x="25.25" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="41" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:ctrl</text>
+</g>
+<!-- XCTRL->CTRL -->
+<g id="edge2" class="edge">
+<title>XCTRL->CTRL</title>
+<path fill="none" stroke="black" d="M44.97,-628.45C44.82,-548.91 44.24,-233.44 44.05,-134.55"/>
+<polygon fill="black" stroke="black" points="47.56,-134.6 44.04,-124.6 40.56,-134.61 47.56,-134.6"/>
+</g>
+<!-- CTRL->BOT -->
+<g id="edge3" class="edge">
+<title>CTRL->BOT</title>
+<path fill="none" stroke="black" d="M79.77,-100.03C211.83,-86.3 670.83,-38.57 796.8,-25.47"/>
+<polygon fill="black" stroke="black" points="796.84,-28.99 806.43,-24.47 796.12,-22.02 796.84,-28.99"/>
+</g>
+<!-- INT_HI -->
+<g id="node7" class="node">
+<title>INT_HI</title>
+<ellipse fill="lightblue" stroke="black" cx="203" cy="-566.29" rx="52.89" ry="18"/>
+<text text-anchor="middle" x="203" y="-561.24" font-family="Times New Roman,serif" font-size="14.00">max < min</text>
+</g>
+<!-- INT_TOP->INT_HI -->
+<g id="edge5" class="edge">
+<title>INT_TOP->INT_HI</title>
+<path fill="none" stroke="black" d="M377.31,-635.37C344.15,-622.42 287.09,-600.13 247.33,-584.6"/>
+<polygon fill="black" stroke="black" points="248.85,-581.44 238.26,-581.06 246.31,-587.96 248.85,-581.44"/>
+</g>
+<!-- INT_BOT -->
+<g id="node6" class="node">
+<title>INT_BOT</title>
+<ellipse fill="lightblue" stroke="black" cx="404" cy="-104.75" rx="33.95" ry="18"/>
+<text text-anchor="start" x="387.12" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="402.88" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:int</text>
+</g>
+<!-- INT_BOT->BOT -->
+<g id="edge15" class="edge">
+<title>INT_BOT->BOT</title>
+<path fill="none" stroke="black" d="M435.6,-97.68C514.28,-82.57 718.3,-43.39 797.2,-28.23"/>
+<polygon fill="black" stroke="black" points="797.68,-31.7 806.84,-26.38 796.36,-24.83 797.68,-31.7"/>
+</g>
+<!-- INT_XBOOL -->
+<g id="node8" class="node">
+<title>INT_XBOOL</title>
+<ellipse fill="lightblue" stroke="black" cx="97" cy="-483.97" rx="27.81" ry="18"/>
+<text text-anchor="middle" x="97" y="-478.92" font-family="Times New Roman,serif" font-size="14.00">1...0</text>
+</g>
+<!-- INT_HI->INT_XBOOL -->
+<g id="edge6" class="edge">
+<title>INT_HI->INT_XBOOL</title>
+<path fill="none" stroke="black" d="M182.06,-549.42C165.21,-536.65 141.43,-518.64 123.29,-504.9"/>
+<polygon fill="black" stroke="black" points="125.68,-502.32 115.6,-499.07 121.46,-507.89 125.68,-502.32"/>
+</g>
+<!-- INT_CON -->
+<g id="node9" class="node">
+<title>INT_CON</title>
+<ellipse fill="lightblue" stroke="black" cx="203" cy="-370.65" rx="45.21" ry="18"/>
+<text text-anchor="middle" x="203" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">constants</text>
+</g>
+<!-- INT_HI->INT_CON -->
+<g id="edge9" class="edge">
+<title>INT_HI->INT_CON</title>
+<path fill="none" stroke="black" d="M203,-547.89C203,-514.02 203,-441.56 203,-400.55"/>
+<polygon fill="black" stroke="black" points="206.5,-400.66 203,-390.66 199.5,-400.66 206.5,-400.66"/>
+</g>
+<!-- INT_CON0 -->
+<g id="node10" class="node">
+<title>INT_CON0</title>
+<ellipse fill="lightblue" stroke="black" cx="18" cy="-370.65" rx="18" ry="18"/>
+<text text-anchor="middle" x="18" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">0</text>
+</g>
+<!-- INT_XBOOL->INT_CON0 -->
+<g id="edge7" class="edge">
+<title>INT_XBOOL->INT_CON0</title>
+<path fill="none" stroke="black" d="M85.68,-467.02C72.29,-448.15 49.88,-416.57 34.54,-394.96"/>
+<polygon fill="black" stroke="black" points="37.56,-393.17 28.92,-387.04 31.86,-397.22 37.56,-393.17"/>
+</g>
+<!-- INT_CON1 -->
+<g id="node11" class="node">
+<title>INT_CON1</title>
+<ellipse fill="lightblue" stroke="black" cx="97" cy="-370.65" rx="18" ry="18"/>
+<text text-anchor="middle" x="97" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">1</text>
+</g>
+<!-- INT_XBOOL->INT_CON1 -->
+<g id="edge8" class="edge">
+<title>INT_XBOOL->INT_CON1</title>
+<path fill="none" stroke="black" d="M97,-465.58C97,-448.1 97,-420.85 97,-400.2"/>
+<polygon fill="black" stroke="black" points="100.5,-400.44 97,-390.44 93.5,-400.44 100.5,-400.44"/>
+</g>
+<!-- INT_LO -->
+<g id="node13" class="node">
+<title>INT_LO</title>
+<ellipse fill="lightblue" stroke="black" cx="203" cy="-185.25" rx="52.89" ry="18"/>
+<text text-anchor="middle" x="203" y="-180.2" font-family="Times New Roman,serif" font-size="14.00">max > min</text>
+</g>
+<!-- INT_CON->INT_LO -->
+<g id="edge13" class="edge">
+<title>INT_CON->INT_LO</title>
+<path fill="none" stroke="black" d="M203,-352.2C203,-320.06 203,-253.57 203,-214.9"/>
+<polygon fill="black" stroke="black" points="206.5,-215.14 203,-205.14 199.5,-215.14 206.5,-215.14"/>
+</g>
+<!-- INT_CON0->INT_CON1 -->
+<!-- INT_BOOL -->
+<g id="node12" class="node">
+<title>INT_BOOL</title>
+<ellipse fill="lightblue" stroke="black" cx="97" cy="-262.45" rx="27.81" ry="18"/>
+<text text-anchor="middle" x="97" y="-257.4" font-family="Times New Roman,serif" font-size="14.00">0...1</text>
+</g>
+<!-- INT_CON0->INT_BOOL -->
+<g id="edge10" class="edge">
+<title>INT_CON0->INT_BOOL</title>
+<path fill="none" stroke="black" d="M28.33,-355.77C41.09,-338.61 63.05,-309.09 78.7,-288.06"/>
+<polygon fill="black" stroke="black" points="81.32,-290.39 84.48,-280.28 75.71,-286.21 81.32,-290.39"/>
+</g>
+<!-- INT_CON1->INT_CON -->
+<!-- INT_CON1->INT_BOOL -->
+<g id="edge11" class="edge">
+<title>INT_CON1->INT_BOOL</title>
+<path fill="none" stroke="black" d="M97,-352.59C97,-336.35 97,-311.6 97,-292.3"/>
+<polygon fill="black" stroke="black" points="100.5,-292.34 97,-282.34 93.5,-292.34 100.5,-292.34"/>
+</g>
+<!-- INT_BOOL->INT_LO -->
+<g id="edge12" class="edge">
+<title>INT_BOOL->INT_LO</title>
+<path fill="none" stroke="black" d="M114.98,-248.69C130.47,-237.7 153.19,-221.59 171.67,-208.48"/>
+<polygon fill="black" stroke="black" points="173.51,-211.46 179.65,-202.82 169.46,-205.75 173.51,-211.46"/>
+</g>
+<!-- INT_LO->INT_BOT -->
+<g id="edge14" class="edge">
+<title>INT_LO->INT_BOT</title>
+<path fill="none" stroke="black" d="M236.64,-171.11C272.65,-157.05 329.61,-134.8 366.9,-120.24"/>
+<polygon fill="black" stroke="black" points="367.88,-123.61 375.92,-116.72 365.33,-117.09 367.88,-123.61"/>
+</g>
+<!-- FLT_CON64 -->
+<g id="node16" class="node">
+<title>FLT_CON64</title>
+<ellipse fill="aqua" stroke="black" cx="709" cy="-370.65" rx="55.33" ry="40.66"/>
+<text text-anchor="middle" x="709" y="-382.1" font-family="Times New Roman,serif" font-size="14.00">64b consts</text>
+<text text-anchor="middle" x="709" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">[excludes</text>
+<text text-anchor="middle" x="709" y="-349.1" font-family="Times New Roman,serif" font-size="14.00">32b consts]</text>
+</g>
+<!-- FLT_TOP->FLT_CON64 -->
+<g id="edge19" class="edge">
+<title>FLT_TOP->FLT_CON64</title>
+<path fill="none" stroke="black" d="M640.79,-628.67C651.74,-587.25 678.94,-484.36 695.5,-421.74"/>
+<polygon fill="black" stroke="black" points="698.8,-422.94 697.97,-412.38 692.03,-421.15 698.8,-422.94"/>
+</g>
+<!-- FLT_CONPI -->
+<g id="node18" class="node">
+<title>FLT_CONPI</title>
+<ellipse fill="aqua" stroke="black" cx="562" cy="-370.65" rx="48.79" ry="18"/>
+<text text-anchor="middle" x="562" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">3.14159...</text>
+</g>
+<!-- FLT_TOP->FLT_CONPI -->
+<g id="edge20" class="edge">
+<title>FLT_TOP->FLT_CONPI</title>
+<path fill="none" stroke="black" d="M631.14,-628.67C618.63,-581.96 585.17,-457.11 569.85,-399.95"/>
+<polygon fill="black" stroke="black" points="573.23,-399.05 567.27,-390.3 566.47,-400.86 573.23,-399.05"/>
+</g>
+<!-- FLT_X32 -->
+<g id="node19" class="node">
+<title>FLT_X32</title>
+<ellipse fill="aqua" stroke="black" cx="420" cy="-483.97" rx="28.32" ry="28.32"/>
+<text text-anchor="middle" x="420" y="-478.92" font-family="Times New Roman,serif" font-size="14.00">~f32</text>
+</g>
+<!-- FLT_TOP->FLT_X32 -->
+<g id="edge23" class="edge">
+<title>FLT_TOP->FLT_X32</title>
+<path fill="none" stroke="black" d="M616.45,-632.06C579.12,-603.92 497.39,-542.31 451.99,-508.09"/>
+<polygon fill="black" stroke="black" points="454.19,-505.36 444.09,-502.13 449.97,-510.95 454.19,-505.36"/>
+</g>
+<!-- FLT_BOT -->
+<g id="node15" class="node">
+<title>FLT_BOT</title>
+<ellipse fill="aqua" stroke="black" cx="636" cy="-104.75" rx="32.41" ry="18"/>
+<text text-anchor="start" x="620.25" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="636" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:flt</text>
+</g>
+<!-- FLT_BOT->BOT -->
+<g id="edge29" class="edge">
+<title>FLT_BOT->BOT</title>
+<path fill="none" stroke="black" d="M661.23,-93.08C696.76,-78.05 761.4,-50.72 799.23,-34.72"/>
+<polygon fill="black" stroke="black" points="800.35,-38.04 808.2,-30.92 797.63,-31.59 800.35,-38.04"/>
+</g>
+<!-- FLT_CON64->FLT_BOT -->
+<g id="edge21" class="edge">
+<title>FLT_CON64->FLT_BOT</title>
+<path fill="none" stroke="black" d="M697.99,-330.56C683.16,-276.52 657.1,-181.62 644,-133.89"/>
+<polygon fill="black" stroke="black" points="647.39,-133 641.36,-124.29 640.64,-134.86 647.39,-133"/>
+</g>
+<!-- FLT_CON32 -->
+<g id="node17" class="node">
+<title>FLT_CON32</title>
+<ellipse fill="aqua" stroke="black" cx="420" cy="-370.65" rx="50.33" ry="18"/>
+<text text-anchor="middle" x="420" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">32b consts</text>
+</g>
+<!-- FLT_CON32->FLT_CONPI -->
+<!-- FLT_32 -->
+<g id="node21" class="node">
+<title>FLT_32</title>
+<ellipse fill="aqua" stroke="black" cx="420" cy="-262.45" rx="23.2" ry="23.2"/>
+<text text-anchor="middle" x="420" y="-257.4" font-family="Times New Roman,serif" font-size="14.00">f32</text>
+</g>
+<!-- FLT_CON32->FLT_32 -->
+<g id="edge27" class="edge">
+<title>FLT_CON32->FLT_32</title>
+<path fill="none" stroke="black" d="M420,-352.59C420,-337.77 420,-315.87 420,-297.49"/>
+<polygon fill="black" stroke="black" points="423.5,-297.54 420,-287.54 416.5,-297.54 423.5,-297.54"/>
+</g>
+<!-- FLT_CONPI->FLT_BOT -->
+<g id="edge22" class="edge">
+<title>FLT_CONPI->FLT_BOT</title>
+<path fill="none" stroke="black" d="M567.09,-352.38C579.71,-307.01 612.57,-188.95 627.9,-133.86"/>
+<polygon fill="black" stroke="black" points="631.26,-134.83 630.57,-124.26 624.52,-132.95 631.26,-134.83"/>
+</g>
+<!-- FLT_CONPI->FLT_CON64 -->
+<!-- FLT_X32->FLT_CON32 -->
+<g id="edge25" class="edge">
+<title>FLT_X32->FLT_CON32</title>
+<path fill="none" stroke="black" d="M420,-455.17C420,-438.48 420,-417.3 420,-400.44"/>
+<polygon fill="black" stroke="black" points="423.5,-400.57 420,-390.57 416.5,-400.57 423.5,-400.57"/>
+</g>
+<!-- FLT_CON0 -->
+<g id="node20" class="node">
+<title>FLT_CON0</title>
+<ellipse fill="aqua" stroke="black" cx="309" cy="-370.65" rx="18.08" ry="18.08"/>
+<text text-anchor="middle" x="309" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">0.</text>
+</g>
+<!-- FLT_X32->FLT_CON0 -->
+<g id="edge24" class="edge">
+<title>FLT_X32->FLT_CON0</title>
+<path fill="none" stroke="black" d="M400.41,-463.33C380.48,-443.34 349.72,-412.49 329.47,-392.18"/>
+<polygon fill="black" stroke="black" points="332.11,-389.87 322.57,-385.26 327.15,-394.82 332.11,-389.87"/>
+</g>
+<!-- FLT_CON0->FLT_CON32 -->
+<!-- FLT_CON0->FLT_32 -->
+<g id="edge26" class="edge">
+<title>FLT_CON0->FLT_32</title>
+<path fill="none" stroke="black" d="M321.73,-357.47C339.61,-340.37 372.5,-308.9 395.28,-287.1"/>
+<polygon fill="black" stroke="black" points="397.56,-289.76 402.37,-280.32 392.72,-284.71 397.56,-289.76"/>
+</g>
+<!-- FLT_32->FLT_BOT -->
+<g id="edge28" class="edge">
+<title>FLT_32->FLT_BOT</title>
+<path fill="none" stroke="black" d="M438.79,-248.73C476.56,-221.15 561.91,-158.84 606.94,-125.97"/>
+<polygon fill="black" stroke="black" points="608.93,-128.85 614.94,-120.12 604.8,-123.19 608.93,-128.85"/>
+</g>
+<!-- PTR0 -->
+<g id="node23" class="node">
+<title>PTR0</title>
+<polygon fill="none" stroke="none" points="856,-131.25 802,-131.25 802,-78.25 856,-78.25 856,-131.25"/>
+<polygon fill="green" stroke="none" points="811,-104.75 811,-127.25 847,-127.25 847,-104.75 811,-104.75"/>
+<polygon fill="none" stroke="black" points="811,-104.75 811,-127.25 847,-127.25 847,-104.75 811,-104.75"/>
+<text text-anchor="start" x="815.12" y="-110.95" font-family="Times New Roman,serif" font-size="14.00" fill="white">*ptr?</text>
+<polygon fill="lightgreen" stroke="none" points="811,-82.25 811,-104.75 847,-104.75 847,-82.25 811,-82.25"/>
+<polygon fill="none" stroke="black" points="811,-82.25 811,-104.75 847,-104.75 847,-82.25 811,-82.25"/>
+<text text-anchor="start" x="814" y="-88.45" font-family="Times New Roman,serif" font-size="14.00">struct</text>
+</g>
+<!-- PTR->PTR0 -->
+<g id="edge34" class="edge">
+<title>PTR->PTR0</title>
+<path fill="none" stroke="black" d="M829,-620.65C829,-532.47 829,-245.72 829,-142.34"/>
+<polygon fill="black" stroke="black" points="832.5,-142.46 829,-132.46 825.5,-142.46 832.5,-142.46"/>
+</g>
+<!-- PTR0->BOT -->
+<g id="edge35" class="edge">
+<title>PTR0->BOT</title>
+<path fill="none" stroke="black" d="M829,-78.37C829,-70.63 829,-62.03 829,-53.93"/>
+<polygon fill="black" stroke="black" points="832.5,-54.09 829,-44.09 825.5,-54.09 832.5,-54.09"/>
+</g>
+<!-- STRUCT_S1 -->
+<g id="node26" class="node">
+<title>STRUCT_S1</title>
+<polygon fill="none" stroke="none" points="979.88,-388.65 894.12,-388.65 894.12,-352.65 979.88,-352.65 979.88,-388.65"/>
+<polygon fill="lightgreen" stroke="none" points="902.12,-359.4 902.12,-381.9 932.88,-381.9 932.88,-359.4 902.12,-359.4"/>
+<polygon fill="none" stroke="black" points="902.12,-359.4 902.12,-381.9 932.88,-381.9 932.88,-359.4 902.12,-359.4"/>
+<text text-anchor="start" x="905.12" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_0" gradientUnits="userSpaceOnUse" x1="938.59" y1="-378.61" x2="966.16" y2="-362.7" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_0)" stroke="none" points="932.88,-359.4 932.88,-381.9 971.88,-381.9 971.88,-359.4 932.88,-359.4"/>
+<polygon fill="none" stroke="black" points="932.88,-359.4 932.88,-381.9 971.88,-381.9 971.88,-359.4 932.88,-359.4"/>
+<text text-anchor="start" x="935.88" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+</g>
+<!-- STRUCT_TOP->STRUCT_S1 -->
+<g id="edge37" class="edge">
+<title>STRUCT_TOP->STRUCT_S1</title>
+<path fill="none" stroke="black" d="M993.06,-628.67C982.89,-581.85 955.66,-456.51 943.28,-399.54"/>
+<polygon fill="black" stroke="black" points="946.74,-398.99 941.19,-389.96 939.9,-400.47 946.74,-398.99"/>
+</g>
+<!-- STRUCT_S2 -->
+<g id="node27" class="node">
+<title>STRUCT_S2</title>
+<polygon fill="none" stroke="none" points="1108.88,-397.15 1023.12,-397.15 1023.12,-344.15 1108.88,-344.15 1108.88,-397.15"/>
+<polygon fill="lightgreen" stroke="none" points="1031.12,-370.65 1031.12,-393.15 1061.88,-393.15 1061.88,-370.65 1031.12,-370.65"/>
+<polygon fill="none" stroke="black" points="1031.12,-370.65 1031.12,-393.15 1061.88,-393.15 1061.88,-370.65 1031.12,-370.65"/>
+<text text-anchor="start" x="1034.12" y="-376.85" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_1" gradientUnits="userSpaceOnUse" x1="1067.59" y1="-389.86" x2="1095.16" y2="-373.95" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_1)" stroke="none" points="1061.88,-370.65 1061.88,-393.15 1100.88,-393.15 1100.88,-370.65 1061.88,-370.65"/>
+<polygon fill="none" stroke="black" points="1061.88,-370.65 1061.88,-393.15 1100.88,-393.15 1100.88,-370.65 1061.88,-370.65"/>
+<text text-anchor="start" x="1064.88" y="-376.85" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1031.12,-348.15 1031.12,-370.65 1061.88,-370.65 1061.88,-348.15 1031.12,-348.15"/>
+<polygon fill="none" stroke="black" points="1031.12,-348.15 1031.12,-370.65 1061.88,-370.65 1061.88,-348.15 1031.12,-348.15"/>
+<text text-anchor="start" x="1034.12" y="-354.35" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_2" gradientUnits="userSpaceOnUse" x1="1067.59" y1="-367.36" x2="1095.16" y2="-351.45" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_2)" stroke="none" points="1061.88,-348.15 1061.88,-370.65 1100.88,-370.65 1100.88,-348.15 1061.88,-348.15"/>
+<polygon fill="none" stroke="black" points="1061.88,-348.15 1061.88,-370.65 1100.88,-370.65 1100.88,-348.15 1061.88,-348.15"/>
+<text text-anchor="start" x="1064.88" y="-354.35" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+</g>
+<!-- STRUCT_TOP->STRUCT_S2 -->
+<g id="edge38" class="edge">
+<title>STRUCT_TOP->STRUCT_S2</title>
+<path fill="none" stroke="black" d="M1001.53,-628.67C1012.68,-584.04 1041.67,-468.04 1056.68,-407.95"/>
+<polygon fill="black" stroke="black" points="1060,-409.09 1059.03,-398.54 1053.21,-407.39 1060,-409.09"/>
+</g>
+<!-- STRUCT_SN -->
+<g id="node28" class="node">
+<title>STRUCT_SN</title>
+<polygon fill="none" stroke="none" points="1237.88,-408.4 1152.12,-408.4 1152.12,-332.9 1237.88,-332.9 1237.88,-408.4"/>
+<polygon fill="lightgreen" stroke="none" points="1160.12,-381.9 1160.12,-404.4 1190.88,-404.4 1190.88,-381.9 1160.12,-381.9"/>
+<polygon fill="none" stroke="black" points="1160.12,-381.9 1160.12,-404.4 1190.88,-404.4 1190.88,-381.9 1160.12,-381.9"/>
+<text text-anchor="start" x="1163.12" y="-388.1" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_3" gradientUnits="userSpaceOnUse" x1="1196.59" y1="-401.11" x2="1224.16" y2="-385.2" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_3)" stroke="none" points="1190.88,-381.9 1190.88,-404.4 1229.88,-404.4 1229.88,-381.9 1190.88,-381.9"/>
+<polygon fill="none" stroke="black" points="1190.88,-381.9 1190.88,-404.4 1229.88,-404.4 1229.88,-381.9 1190.88,-381.9"/>
+<text text-anchor="start" x="1193.88" y="-388.1" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1160.12,-359.4 1160.12,-381.9 1190.88,-381.9 1190.88,-359.4 1160.12,-359.4"/>
+<polygon fill="none" stroke="black" points="1160.12,-359.4 1160.12,-381.9 1190.88,-381.9 1190.88,-359.4 1160.12,-359.4"/>
+<text text-anchor="start" x="1166.12" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">...  </text>
+<defs>
+<linearGradient id="l_4" gradientUnits="userSpaceOnUse" x1="1196.59" y1="-378.61" x2="1224.16" y2="-362.7" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_4)" stroke="none" points="1190.88,-359.4 1190.88,-381.9 1229.88,-381.9 1229.88,-359.4 1190.88,-359.4"/>
+<polygon fill="none" stroke="black" points="1190.88,-359.4 1190.88,-381.9 1229.88,-381.9 1229.88,-359.4 1190.88,-359.4"/>
+<text text-anchor="start" x="1193.88" y="-365.6" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1160.12,-336.9 1160.12,-359.4 1190.88,-359.4 1190.88,-336.9 1160.12,-336.9"/>
+<polygon fill="none" stroke="black" points="1160.12,-336.9 1160.12,-359.4 1190.88,-359.4 1190.88,-336.9 1160.12,-336.9"/>
+<text text-anchor="start" x="1163.12" y="-343.1" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_5" gradientUnits="userSpaceOnUse" x1="1196.59" y1="-356.11" x2="1224.16" y2="-340.2" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_5)" stroke="none" points="1190.88,-336.9 1190.88,-359.4 1229.88,-359.4 1229.88,-336.9 1190.88,-336.9"/>
+<polygon fill="none" stroke="black" points="1190.88,-336.9 1190.88,-359.4 1229.88,-359.4 1229.88,-336.9 1190.88,-336.9"/>
+<text text-anchor="start" x="1193.88" y="-343.1" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+</g>
+<!-- STRUCT_TOP->STRUCT_SN -->
+<g id="edge39" class="edge">
+<title>STRUCT_TOP->STRUCT_SN</title>
+<path fill="none" stroke="black" d="M1009.69,-629.1C1039.89,-586.98 1116.85,-479.64 1161.52,-417.35"/>
+<polygon fill="black" stroke="black" points="1164.27,-419.52 1167.25,-409.35 1158.58,-415.44 1164.27,-419.52"/>
+</g>
+<!-- STRUCT_BOT -->
+<g id="node25" class="node">
+<title>STRUCT_BOT</title>
+<ellipse fill="lightgreen" stroke="black" cx="995" cy="-104.75" rx="44.7" ry="18"/>
+<text text-anchor="start" x="970.25" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="986" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:struct</text>
+</g>
+<!-- STRUCT_BOT->BOT -->
+<g id="edge43" class="edge">
+<title>STRUCT_BOT->BOT</title>
+<path fill="none" stroke="black" d="M967.59,-90.27C937.27,-75.36 888.65,-51.46 857.79,-36.28"/>
+<polygon fill="black" stroke="black" points="859.56,-33.25 849.04,-31.98 856.47,-39.53 859.56,-33.25"/>
+</g>
+<!-- STRUCT_S1->STRUCT_BOT -->
+<g id="edge40" class="edge">
+<title>STRUCT_S1->STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M940.9,-352.79C950.72,-307.77 976.56,-189.3 988.62,-133.98"/>
+<polygon fill="black" stroke="black" points="992.01,-134.88 990.72,-124.36 985.17,-133.38 992.01,-134.88"/>
+</g>
+<!-- STRUCT_S1->STRUCT_S2 -->
+<!-- STRUCT_S2->STRUCT_BOT -->
+<g id="edge41" class="edge">
+<title>STRUCT_S2->STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M1058.93,-344.18C1045.59,-294.22 1016.79,-186.34 1002.86,-134.18"/>
+<polygon fill="black" stroke="black" points="1006.24,-133.28 1000.28,-124.52 999.48,-135.08 1006.24,-133.28"/>
+</g>
+<!-- STRUCT_S2->STRUCT_SN -->
+<!-- STRUCT_SN->STRUCT_BOT -->
+<g id="edge42" class="edge">
+<title>STRUCT_SN->STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M1166.77,-333.12C1125.77,-278.61 1050.75,-178.87 1014.99,-131.32"/>
+<polygon fill="black" stroke="black" points="1017.9,-129.37 1009.09,-123.48 1012.3,-133.58 1017.9,-129.37"/>
+</g>
+<!-- MEM_ALIAS1 -->
+<g id="node31" class="node">
+<title>MEM_ALIAS1</title>
+<ellipse fill="blue" stroke="black" cx="1301" cy="-370.65" rx="20.13" ry="20.13"/>
+<text text-anchor="middle" x="1301" y="-365.6" font-family="Times New Roman,serif" font-size="14.00" fill="white">#1</text>
+</g>
+<!-- MEM_TOP->MEM_ALIAS1 -->
+<g id="edge47" class="edge">
+<title>MEM_TOP->MEM_ALIAS1</title>
+<path fill="none" stroke="black" d="M1343.05,-628.67C1335.53,-582.52 1315.58,-460.09 1306.11,-402.04"/>
+<polygon fill="black" stroke="black" points="1309.57,-401.48 1304.51,-392.17 1302.66,-402.6 1309.57,-401.48"/>
+</g>
+<!-- MEM_ALIASDOTS -->
+<g id="node32" class="node">
+<title>MEM_ALIASDOTS</title>
+<ellipse fill="blue" stroke="black" cx="1391" cy="-370.65" rx="27" ry="18"/>
+<text text-anchor="middle" x="1391" y="-365.6" font-family="Times New Roman,serif" font-size="14.00" fill="white">...</text>
+</g>
+<!-- MEM_TOP->MEM_ALIASDOTS -->
+<g id="edge48" class="edge">
+<title>MEM_TOP->MEM_ALIASDOTS</title>
+<path fill="none" stroke="black" d="M1348.95,-628.67C1356.56,-581.96 1376.91,-457.11 1386.23,-399.95"/>
+<polygon fill="black" stroke="black" points="1389.64,-400.76 1387.79,-390.33 1382.73,-399.64 1389.64,-400.76"/>
+</g>
+<!-- MEM_ALIASN -->
+<g id="node33" class="node">
+<title>MEM_ALIASN</title>
+<ellipse fill="blue" stroke="black" cx="1481" cy="-370.65" rx="20.13" ry="20.13"/>
+<text text-anchor="middle" x="1481" y="-365.6" font-family="Times New Roman,serif" font-size="14.00" fill="white">#n</text>
+</g>
+<!-- MEM_TOP->MEM_ALIASN -->
+<g id="edge49" class="edge">
+<title>MEM_TOP->MEM_ALIASN</title>
+<path fill="none" stroke="black" d="M1354.86,-628.67C1377.84,-581.67 1439.5,-455.54 1467.2,-398.89"/>
+<polygon fill="black" stroke="black" points="1470.2,-400.72 1471.44,-390.2 1463.91,-397.64 1470.2,-400.72"/>
+</g>
+<!-- MEM_BOT -->
+<g id="node30" class="node">
+<title>MEM_BOT</title>
+<ellipse fill="blue" stroke="black" cx="1346" cy="-104.75" rx="43.67" ry="18"/>
+<text text-anchor="start" x="1322" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00" fill="white">⊥</text>
+<text text-anchor="start" x="1337.75" y="-100.7" font-family="Times New Roman,serif" font-size="14.00" fill="white">:mem</text>
+</g>
+<!-- MEM_BOT->BOT -->
+<g id="edge53" class="edge">
+<title>MEM_BOT->BOT</title>
+<path fill="none" stroke="black" d="M1305.86,-97.41C1206.64,-81.75 951.34,-41.44 861.15,-27.2"/>
+<polygon fill="black" stroke="black" points="861.94,-23.78 851.52,-25.68 860.85,-30.7 861.94,-23.78"/>
+</g>
+<!-- MEM_ALIAS1->MEM_BOT -->
+<g id="edge50" class="edge">
+<title>MEM_ALIAS1->MEM_BOT</title>
+<path fill="none" stroke="black" d="M1304.38,-350.67C1312.23,-304.29 1331.71,-189.17 1340.97,-134.49"/>
+<polygon fill="black" stroke="black" points="1344.41,-135.12 1342.63,-124.67 1337.51,-133.95 1344.41,-135.12"/>
+</g>
+<!-- MEM_ALIAS1->MEM_ALIASDOTS -->
+<!-- MEM_ALIASDOTS->MEM_BOT -->
+<g id="edge51" class="edge">
+<title>MEM_ALIASDOTS->MEM_BOT</title>
+<path fill="none" stroke="black" d="M1387.91,-352.38C1380.25,-307.12 1360.35,-189.52 1350.99,-134.26"/>
+<polygon fill="black" stroke="black" points="1354.49,-133.92 1349.37,-124.65 1347.58,-135.09 1354.49,-133.92"/>
+</g>
+<!-- MEM_ALIASDOTS->MEM_ALIASN -->
+<!-- MEM_ALIASN->MEM_BOT -->
+<g id="edge52" class="edge">
+<title>MEM_ALIASN->MEM_BOT</title>
+<path fill="none" stroke="black" d="M1471.72,-352.38C1448.54,-306.73 1388,-187.47 1360.26,-132.83"/>
+<polygon fill="black" stroke="black" points="1363.5,-131.48 1355.85,-124.15 1357.26,-134.65 1363.5,-131.48"/>
+</g>
+<!-- TUPLE1 -->
+<g id="node36" class="node">
+<title>TUPLE1</title>
+<polygon fill="none" stroke="none" points="1598,-397.15 1544,-397.15 1544,-344.15 1598,-344.15 1598,-397.15"/>
+<polygon fill="pink" stroke="none" points="1552.25,-370.65 1552.25,-393.15 1589.75,-393.15 1589.75,-370.65 1552.25,-370.65"/>
+<polygon fill="none" stroke="black" points="1552.25,-370.65 1552.25,-393.15 1589.75,-393.15 1589.75,-370.65 1552.25,-370.65"/>
+<text text-anchor="start" x="1555.25" y="-376.85" font-family="Times New Roman,serif" font-size="14.00">Tuple</text>
+<polygon fill="black" stroke="none" points="1552.25,-348.15 1552.25,-370.65 1589.75,-370.65 1589.75,-348.15 1552.25,-348.15"/>
+<polygon fill="none" stroke="black" points="1552.25,-348.15 1552.25,-370.65 1589.75,-370.65 1589.75,-348.15 1552.25,-348.15"/>
+<text text-anchor="start" x="1559.38" y="-354.35" font-family="Times New Roman,serif" font-size="14.00" fill="white">type</text>
+</g>
+<!-- TUPLE_TOP->TUPLE1 -->
+<g id="edge57" class="edge">
+<title>TUPLE_TOP->TUPLE1</title>
+<path fill="none" stroke="black" d="M1615.85,-628.67C1608.11,-584.13 1588.01,-468.52 1577.55,-408.33"/>
+<polygon fill="black" stroke="black" points="1581.01,-407.81 1575.85,-398.56 1574.12,-409.01 1581.01,-407.81"/>
+</g>
+<!-- TUPLE2 -->
+<g id="node37" class="node">
+<title>TUPLE2</title>
+<polygon fill="none" stroke="none" points="1695,-408.4 1641,-408.4 1641,-332.9 1695,-332.9 1695,-408.4"/>
+<polygon fill="pink" stroke="none" points="1649.25,-381.9 1649.25,-404.4 1686.75,-404.4 1686.75,-381.9 1649.25,-381.9"/>
+<polygon fill="none" stroke="black" points="1649.25,-381.9 1649.25,-404.4 1686.75,-404.4 1686.75,-381.9 1649.25,-381.9"/>
+<text text-anchor="start" x="1652.25" y="-388.1" font-family="Times New Roman,serif" font-size="14.00">Tuple</text>
+<polygon fill="black" stroke="none" points="1649.25,-359.4 1649.25,-381.9 1686.75,-381.9 1686.75,-359.4 1649.25,-359.4"/>
+<polygon fill="none" stroke="black" points="1649.25,-359.4 1649.25,-381.9 1686.75,-381.9 1686.75,-359.4 1649.25,-359.4"/>
+<text text-anchor="start" x="1656.38" y="-365.6" font-family="Times New Roman,serif" font-size="14.00" fill="white">type</text>
+<polygon fill="black" stroke="none" points="1649.25,-336.9 1649.25,-359.4 1686.75,-359.4 1686.75,-336.9 1649.25,-336.9"/>
+<polygon fill="none" stroke="black" points="1649.25,-336.9 1649.25,-359.4 1686.75,-359.4 1686.75,-336.9 1649.25,-336.9"/>
+<text text-anchor="start" x="1656.38" y="-343.1" font-family="Times New Roman,serif" font-size="14.00" fill="white">type</text>
+</g>
+<!-- TUPLE_TOP->TUPLE2 -->
+<g id="edge58" class="edge">
+<title>TUPLE_TOP->TUPLE2</title>
+<path fill="none" stroke="black" d="M1622.22,-628.67C1629.67,-586.65 1648.35,-481.4 1659.41,-419.08"/>
+<polygon fill="black" stroke="black" points="1662.81,-419.91 1661.11,-409.46 1655.92,-418.69 1662.81,-419.91"/>
+</g>
+<!-- TUPLEN -->
+<g id="node38" class="node">
+<title>TUPLEN</title>
+<polygon fill="none" stroke="none" points="1792,-419.65 1738,-419.65 1738,-321.65 1792,-321.65 1792,-419.65"/>
+<polygon fill="pink" stroke="none" points="1746.25,-393.15 1746.25,-415.65 1783.75,-415.65 1783.75,-393.15 1746.25,-393.15"/>
+<polygon fill="none" stroke="black" points="1746.25,-393.15 1746.25,-415.65 1783.75,-415.65 1783.75,-393.15 1746.25,-393.15"/>
+<text text-anchor="start" x="1749.25" y="-399.35" font-family="Times New Roman,serif" font-size="14.00">Tuple</text>
+<polygon fill="black" stroke="none" points="1746.25,-370.65 1746.25,-393.15 1783.75,-393.15 1783.75,-370.65 1746.25,-370.65"/>
+<polygon fill="none" stroke="black" points="1746.25,-370.65 1746.25,-393.15 1783.75,-393.15 1783.75,-370.65 1746.25,-370.65"/>
+<text text-anchor="start" x="1753.38" y="-376.85" font-family="Times New Roman,serif" font-size="14.00" fill="white">type</text>
+<polygon fill="black" stroke="none" points="1746.25,-348.15 1746.25,-370.65 1783.75,-370.65 1783.75,-348.15 1746.25,-348.15"/>
+<polygon fill="none" stroke="black" points="1746.25,-348.15 1746.25,-370.65 1783.75,-370.65 1783.75,-348.15 1746.25,-348.15"/>
+<text text-anchor="start" x="1759.38" y="-354.35" font-family="Times New Roman,serif" font-size="14.00" fill="white">...</text>
+<polygon fill="black" stroke="none" points="1746.25,-325.65 1746.25,-348.15 1783.75,-348.15 1783.75,-325.65 1746.25,-325.65"/>
+<polygon fill="none" stroke="black" points="1746.25,-325.65 1746.25,-348.15 1783.75,-348.15 1783.75,-325.65 1746.25,-325.65"/>
+<text text-anchor="start" x="1753.38" y="-331.85" font-family="Times New Roman,serif" font-size="14.00" fill="white">type</text>
+</g>
+<!-- TUPLE_TOP->TUPLEN -->
+<g id="edge59" class="edge">
+<title>TUPLE_TOP->TUPLEN</title>
+<path fill="none" stroke="black" d="M1628.36,-629.1C1649.26,-589.55 1700.57,-492.51 1734.02,-429.24"/>
+<polygon fill="black" stroke="black" points="1736.95,-431.2 1738.53,-420.73 1730.76,-427.93 1736.95,-431.2"/>
+</g>
+<!-- TUPLE_BOT -->
+<g id="node35" class="node">
+<title>TUPLE_BOT</title>
+<ellipse fill="pink" stroke="black" cx="1619" cy="-104.75" rx="42.65" ry="18"/>
+<text text-anchor="start" x="1595.75" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="1611.5" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:tuple</text>
+</g>
+<!-- TUPLE_BOT->BOT -->
+<g id="edge63" class="edge">
+<title>TUPLE_BOT->BOT</title>
+<path fill="none" stroke="black" d="M1577.91,-99.5C1438.76,-85.13 986.93,-38.44 861.54,-25.49"/>
+<polygon fill="black" stroke="black" points="861.93,-22.01 851.62,-24.46 861.21,-28.97 861.93,-22.01"/>
+</g>
+<!-- TUPLE1->TUPLE_BOT -->
+<g id="edge60" class="edge">
+<title>TUPLE1->TUPLE_BOT</title>
+<path fill="none" stroke="black" d="M1575.78,-344.18C1584.8,-294.22 1604.27,-186.34 1613.69,-134.18"/>
+<polygon fill="black" stroke="black" points="1617.09,-135.01 1615.43,-124.55 1610.21,-133.77 1617.09,-135.01"/>
+</g>
+<!-- TUPLE2->TUPLE_BOT -->
+<g id="edge61" class="edge">
+<title>TUPLE2->TUPLE_BOT</title>
+<path fill="none" stroke="black" d="M1661.08,-333.12C1651.23,-279.67 1633.37,-182.73 1624.42,-134.16"/>
+<polygon fill="black" stroke="black" points="1627.87,-133.59 1622.62,-124.39 1620.99,-134.86 1627.87,-133.59"/>
+</g>
+<!-- TUPLEN->TUPLE_BOT -->
+<g id="edge62" class="edge">
+<title>TUPLEN->TUPLE_BOT</title>
+<path fill="none" stroke="black" d="M1738.22,-321.88C1707.66,-266.22 1658.74,-177.12 1634.15,-132.34"/>
+<polygon fill="black" stroke="black" points="1637.34,-130.87 1629.45,-123.79 1631.2,-134.24 1637.34,-130.87"/>
+</g>
+</g>
+</svg>
|
