diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/chapter14/14-grammar.md | 122 | ||||
| -rw-r--r-- | docs/chapter14/Makefile | 12 | ||||
| -rw-r--r-- | docs/chapter14/README.md | 408 | ||||
| -rw-r--r-- | docs/chapter14/lattice.gv | 178 | ||||
| -rw-r--r-- | docs/chapter14/lattice.svg | 827 |
5 files changed, 1547 insertions, 0 deletions
diff --git a/docs/chapter14/14-grammar.md b/docs/chapter14/14-grammar.md new file mode 100644 index 00000000..f23f81cd --- /dev/null +++ b/docs/chapter14/14-grammar.md @@ -0,0 +1,122 @@ +# Grammar for Chapter 14 + +```antlrv4 +grammar SimpleLanguage; + +program : block EOF ; + +block : statement+ ; + + +statement + : '{' block '}' + | returnStatement + | ifStatement + | whileStatement + | breakStatement + | continueStatement + | structDeclaration + | expressionStatement + ; + + +returnStatement : 'return' expression ';' ; + +ifStatement : 'if' '(' expression ')' statement ('else' statement)? ; + +whileStatement : 'while' '(' expression ')' statement ; + +breakStatement : 'break' ';' ; + +continueStatement : 'continue' ';' ; + + +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..33374243 --- /dev/null +++ b/docs/chapter14/README.md @@ -0,0 +1,408 @@ +# Chapter 14: Numeric Types + +[Previous: Chapter 13](../chapter13/README.md) | +[Next: Chapter 15](../chapter15/README.md) + +# Table of Contents + +1. [Floating-point arithmetic](#floating-point-arithmetic) +2. [Narrow Word Types](#narrow-or-sub-word-types) +3. [Overflow handling](#overflow-handling) +4. [Integer ranges](#integer-ranges) +5. [Bitwise operations](#bitwise-operations) +6. [Precedence](#precedence) +7. [Type lattice](#type-implementation) +8. [Nodes](#nodes) + + +With structs, reference fields, and scheduling in place, this chapter extends +the numeric values they carry. We add floating-point arithmetic, narrow +integer and float types, and integer ranges. + +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. + +## Floating-point arithmetic + +Floating point values start with the `flt` type and compute IEEE754 64-bit arithmetic. +Integer expressions auto-widen to floats when involved in a float expression. + +```java +flt f = 0.5; +int x = 2; +f = f+x; // Auto-widen x to 2.0, result is 2.5 +f = f+true; // Since bools are just synonyms for integers 0,1 they auto-widen also +``` + +There is no corresponding way right now to round a `flt` back to an `int`: +```java +int x = 3.14; // error +``` + +Here is Newton's method for computing a square root: +```java +flt guess = arg; // Initial guess is just argument +while( true ) { + // Next guess from Newton's method + flt next = (arg/guess + guess)/2; + // Break if hit fixed point + if( next == guess ) break; + guess = next; +} +return guess; +``` +When run with argument 2, produces 1.414213562373095. + +Floating point operations have their own Nodes: + +| Node | Op | +|------------------------|----------------------| +| AddF, SubF, MulF, DivF | Basic binary FP ops | +| MinusF | Unary negate | +| EQF, LTF, LEF | FP compare operators | + +The parser uses [`Node.widen()`](../../src/main/java/com/seaofnodes/simple/node/Node.java) +to choose the floating-point operation and insert `ToFloatNode` conversions. +The float lattice has constants between `TOP` and `BOT`, like the integer +lattice before ranges. [`TypeFloat`](../../src/main/java/com/seaofnodes/simple/type/TypeFloat.java) +also records whether a value fits `f32`; assigning to `f32` rounds it to that +precision. Conversion from float back to integer remains a separate, pending +language feature. + + +## Narrow or sub-word types + +Narrow or sub-word 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 very 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 very 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 very 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 turns 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;` invariant 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; } +``` + +#### More Truncate + +```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 + +For general range math, visit Hackers Delight:[^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 positions are filled by replicating the value of the sign bit. | +| **Unsigned Right Shift** | `>>>` | Shifts bits to the right, any vacated bit positions are always filled with zero | + +Note `>>>` is a logical shift and not an arithmetic shift. + +Here is a sample of peephole opts on these logical operations: + +#### 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  `TypeInteger` 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  `TypeFloat` class introduced here supports +both 32-bit and 64-bit sizes. + +The integer range diagram is schematic: it shows the boolean range and its +dual as examples among the possible ranges. The other domains retain the +named structs, nullable pointers, and precise memory aliases from earlier chapters. + + + +### meet: + +The 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)); +} +``` + +This combines all values that could possibly occur within either range. +Also, the implementation is trivial. + + + +[^1]: Hacker's delight. + 4-2 Propagating Bounds through Adds and Subtracts + +The next chapter uses these numeric types for array lengths, indexing, and +element storage, including byte arrays. diff --git a/docs/chapter14/lattice.gv b/docs/chapter14/lattice.gv new file mode 100644 index 00000000..5fd97a52 --- /dev/null +++ b/docs/chapter14/lattice.gv @@ -0,0 +1,178 @@ +digraph Lattice { + rankdir=TB; + newrank=true; + // Preserve the same-rank ordering edges through cluster layout. + remincross=false; + nodesep=0.22; + ranksep=0.65; + node [shape=ellipse, style=filled, fontname="DejaVu Sans", fontsize=13]; + edge [color="#555555", arrowsize=0.6]; + + // These arrows are lattice-order edges, not use/definition edges. + TOP [label="⊤", fillcolor=black, fontcolor=white]; + BOT [label="⊥", fillcolor=black, fontcolor=white]; + + subgraph cluster_control { + label="Control"; fontname="Arial"; color="#cccccc"; + node [fillcolor="#ffff00"]; + XCTRL [label="⊤:ctrl"]; + CTRL [label="⊥:ctrl"]; + XCTRL -> CTRL; + } + + subgraph cluster_integer { + label="Integer ranges (schematic)"; fontname="Arial"; color="#cccccc"; + 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]; + + 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_CON0 -> INT_CON1 -> INT_CON [style=invis]; + + {rank=same; INT_CON0; INT_CON1; INT_CON;} + } + + subgraph cluster_float { + label="Float"; fontname="Arial"; color="#cccccc"; + 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]; + + 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_CON0 -> FLT_CON32 -> FLT_CONPI -> FLT_CON64 [style=invis]; + + + {rank=same; FLT_CON0; FLT_CON32; FLT_CONPI; FLT_CON64;} + } + + subgraph cluster_pointer { + label="Pointer = nullability × struct type"; + fontname="Arial"; color="#cccccc"; + node [fillcolor="#008000", fontcolor=white]; + PTR_TOP [label="⊤:ptr\n[*⊤:struct]"]; + PTR_BOT [label="⊥:ptr\n[*⊥:struct?]"]; + PTR_NULL [label="null"]; + PTR_ANY [label="*⊥:struct\n[ptr any struct]"]; + PTR_PERSON [label="*Person"]; + PTR_S1 [label="*s1"]; + PTR_MORE [label="*s2, …"]; + PTR_PERSON_NIL [label="*Person?"]; + PTR_S1_NIL [label="*s1?"]; + PTR_MORE_NIL [label="*s2?, …"]; + {rank=same; PTR_PERSON; PTR_S1; PTR_MORE; PTR_NULL;} + {rank=same; PTR_ANY; PTR_PERSON_NIL; PTR_S1_NIL; PTR_MORE_NIL;} + PTR_PERSON -> PTR_S1 -> PTR_MORE -> PTR_NULL [style=invis]; + PTR_ANY -> PTR_PERSON_NIL -> PTR_S1_NIL -> PTR_MORE_NIL [style=invis]; + PTR_TOP -> {PTR_PERSON PTR_S1 PTR_MORE PTR_NULL}; + {PTR_PERSON PTR_S1 PTR_MORE} -> PTR_ANY; + PTR_PERSON -> PTR_PERSON_NIL; + PTR_S1 -> PTR_S1_NIL; + PTR_MORE -> PTR_MORE_NIL; + PTR_NULL -> {PTR_PERSON_NIL PTR_S1_NIL PTR_MORE_NIL}; + {PTR_ANY PTR_PERSON_NIL PTR_S1_NIL PTR_MORE_NIL} -> PTR_BOT; + } + + subgraph cluster_struct { + label="Struct\nnamed collection of named scalar types"; + fontname="Arial"; color="#cccccc"; + node [fillcolor="#90ee90"]; + STRUCT_TOP [label="⊤:struct\n[struct top]"]; + STRUCT_BOT [label="⊥:struct\n[struct bottom]"]; + STRUCT_PERSON [label="Person\nage: int", shape=box]; + STRUCT_S1 [label="s1\nx: int", shape=box]; + STRUCT_S2 [label="s2\nx: int, y: *s1", shape=box]; + STRUCT_MORE [label="…", shape=box]; + {rank=same; STRUCT_PERSON; STRUCT_S1; STRUCT_S2; STRUCT_MORE;} + STRUCT_PERSON -> STRUCT_S1 -> STRUCT_S2 -> STRUCT_MORE [style=invis]; + STRUCT_TOP -> {STRUCT_PERSON STRUCT_S1 STRUCT_S2 STRUCT_MORE}; + {STRUCT_PERSON STRUCT_S1 STRUCT_S2 STRUCT_MORE} -> STRUCT_BOT; + } + + subgraph cluster_memory { + label="Memory\nprecise alias slices"; fontname="Arial"; color="#cccccc"; + node [fillcolor="#00008b", fontcolor=white]; + MEM_TOP [label="⊤:mem"]; + MEM_BOT [label="⊥:mem"]; + MEM_ALIAS2 [label="MEM#2"]; + MEM_ALIAS3 [label="MEM#3"]; + MEM_MORE [label="…"]; + {rank=same; MEM_ALIAS2; MEM_ALIAS3; MEM_MORE;} + MEM_ALIAS2 -> MEM_ALIAS3 -> MEM_MORE [style=invis]; + MEM_TOP -> {MEM_ALIAS2 MEM_ALIAS3 MEM_MORE}; + {MEM_ALIAS2 MEM_ALIAS3 MEM_MORE} -> MEM_BOT; + } + + subgraph cluster_tuple { + label="Tuple\ncollection of types"; + fontname="Arial"; color="#cccccc"; + node [fillcolor="#ffc0cb"]; + TUPLE_TOP [label="⊤:tuple"]; + TUPLE_BOT [label="⊥:tuple"]; + // Each black element stands for a recursively nested type lattice. + TUPLE1 [shape=plain, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> + <TR><TD BGCOLOR="#ffc0cb">tuple</TD></TR> + <TR><TD BGCOLOR="black"><FONT COLOR="white">type</FONT></TD></TR> + </TABLE> + >]; + TUPLE2 [shape=plain, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> + <TR><TD BGCOLOR="#ffc0cb">tuple</TD></TR> + <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=plain, label=< + <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" CELLPADDING="4"> + <TR><TD BGCOLOR="#ffc0cb">tuple</TD></TR> + <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> + >]; + {rank=same; TUPLE1; TUPLE2; TUPLEN;} + TUPLE1 -> TUPLE2 -> TUPLEN [style=invis]; + TUPLE_TOP -> {TUPLE1 TUPLE2 TUPLEN}; + {TUPLE1 TUPLE2 TUPLEN} -> TUPLE_BOT; + } + + TOP -> {XCTRL INT_TOP FLT_TOP PTR_TOP STRUCT_TOP MEM_TOP TUPLE_TOP}; + {CTRL INT_BOT FLT_BOT PTR_BOT STRUCT_BOT MEM_BOT TUPLE_BOT} -> BOT; + {rank=same; XCTRL; INT_TOP; FLT_TOP; PTR_TOP; STRUCT_TOP; MEM_TOP; TUPLE_TOP;} + {rank=same; CTRL; INT_BOT; FLT_BOT; PTR_BOT; STRUCT_BOT; MEM_BOT; TUPLE_BOT;} + XCTRL -> INT_TOP -> FLT_TOP -> PTR_TOP -> STRUCT_TOP -> MEM_TOP -> TUPLE_TOP [style=invis]; +} diff --git a/docs/chapter14/lattice.svg b/docs/chapter14/lattice.svg new file mode 100644 index 00000000..9db77f7a --- /dev/null +++ b/docs/chapter14/lattice.svg @@ -0,0 +1,827 @@ +<?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="2191pt" height="881pt" + viewBox="0.00 0.00 2191.00 880.78" 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 876.78)"> +<title>Lattice</title> +<polygon fill="white" stroke="none" points="-4,4 -4,-876.78 2187,-876.78 2187,4 -4,4"/> +<g id="clust1" class="cluster"> +<title>cluster_control</title> +<polygon fill="none" stroke="#cccccc" points="8,-85.99 8,-802.04 98,-802.04 98,-85.99 8,-85.99"/> +<text text-anchor="middle" x="53" y="-784.74" font-family="Arial" font-size="14.00">Control</text> +</g> +<g id="clust2" class="cluster"> +<title>cluster_integer</title> +<polygon fill="none" stroke="#cccccc" points="106,-85.99 106,-802.04 372,-802.04 372,-85.99 106,-85.99"/> +<text text-anchor="middle" x="239" y="-784.74" font-family="Arial" font-size="14.00">Integer ranges (schematic)</text> +</g> +<g id="clust4" class="cluster"> +<title>cluster_float</title> +<polygon fill="none" stroke="#cccccc" points="380,-85.99 380,-802.04 864,-802.04 864,-85.99 380,-85.99"/> +<text text-anchor="middle" x="622" y="-784.74" font-family="Arial" font-size="14.00">Float</text> +</g> +<g id="clust6" class="cluster"> +<title>cluster_pointer</title> +<polygon fill="none" stroke="#cccccc" points="872,-75 872,-813.03 1353,-813.03 1353,-75 872,-75"/> +<text text-anchor="middle" x="1112.5" y="-795.73" font-family="Arial" font-size="14.00">Pointer = nullability × struct type</text> +</g> +<g id="clust13" class="cluster"> +<title>cluster_struct</title> +<polygon fill="none" stroke="#cccccc" points="1361,-75 1361,-828.78 1697,-828.78 1697,-75 1361,-75"/> +<text text-anchor="middle" x="1529" y="-811.48" font-family="Arial" font-size="14.00">Struct</text> +<text text-anchor="middle" x="1529" y="-795.73" font-family="Arial" font-size="14.00">named collection of named scalar types</text> +</g> +<g id="clust17" class="cluster"> +<title>cluster_memory</title> +<polygon fill="none" stroke="#cccccc" points="1705,-85.99 1705,-817.79 1987,-817.79 1987,-85.99 1705,-85.99"/> +<text text-anchor="middle" x="1846" y="-800.49" font-family="Arial" font-size="14.00">Memory</text> +<text text-anchor="middle" x="1846" y="-784.74" font-family="Arial" font-size="14.00">precise alias slices</text> +</g> +<g id="clust21" class="cluster"> +<title>cluster_tuple</title> +<polygon fill="none" stroke="#cccccc" points="1995,-85.99 1995,-817.79 2175,-817.79 2175,-85.99 1995,-85.99"/> +<text text-anchor="middle" x="2085" y="-800.49" font-family="Arial" font-size="14.00">Tuple</text> +<text text-anchor="middle" x="2085" y="-784.74" font-family="Arial" font-size="14.00">collection of types</text> +</g> +<!-- TOP --> +<g id="node1" class="node"> +<title>TOP</title> +<ellipse fill="black" stroke="black" cx="1093" cy="-854.78" rx="27" ry="18"/> +<text text-anchor="middle" x="1093" y="-850.68" font-family="DejaVu Sans" font-size="13.00" fill="white">⊤</text> +</g> +<!-- XCTRL --> +<g id="node3" class="node"> +<title>XCTRL</title> +<ellipse fill="#ffff00" stroke="black" cx="53" cy="-752.29" rx="36.51" ry="18"/> +<text text-anchor="middle" x="53" y="-748.19" font-family="DejaVu Sans" font-size="13.00">⊤:ctrl</text> +</g> +<!-- TOP->XCTRL --> +<g id="edge77" class="edge"> +<title>TOP->XCTRL</title> +<path fill="none" stroke="#555555" d="M1065.75,-853.81C910.7,-853.87 145.18,-852.94 102,-828.78 82.14,-817.67 69.01,-794.76 61.39,-777.08"/> +<polygon fill="#555555" stroke="#555555" points="63.43,-776.52 59.22,-771.76 59.54,-778.1 63.43,-776.52"/> +</g> +<!-- INT_TOP --> +<g id="node5" class="node"> +<title>INT_TOP</title> +<ellipse fill="lightblue" stroke="black" cx="330" cy="-752.29" rx="33.95" ry="18"/> +<text text-anchor="start" x="313.12" y="-749.19" font-family="DejaVu Sans" font-weight="bold" font-size="13.00">⊤</text> +<text text-anchor="start" x="325.12" y="-749.19" font-family="DejaVu Sans" font-size="13.00">:int</text> +</g> +<!-- TOP->INT_TOP --> +<g id="edge78" class="edge"> +<title>TOP->INT_TOP</title> +<path fill="none" stroke="#555555" d="M1065.76,-853.55C938.37,-852.39 406.27,-846.49 376,-828.78 356.7,-817.5 344.47,-794.61 337.51,-776.98"/> +<polygon fill="#555555" stroke="#555555" points="339.61,-776.59 335.55,-771.7 335.67,-778.05 339.61,-776.59"/> +</g> +<!-- FLT_TOP --> +<g id="node14" class="node"> +<title>FLT_TOP</title> +<ellipse fill="aqua" stroke="black" cx="720" cy="-752.29" rx="31.39" ry="18"/> +<text text-anchor="start" x="705" y="-749.19" font-family="DejaVu Sans" font-weight="bold" font-size="13.00">⊤</text> +<text text-anchor="start" x="717" y="-749.19" font-family="DejaVu Sans" font-size="13.00">:flt</text> +</g> +<!-- TOP->FLT_TOP --> +<g id="edge79" class="edge"> +<title>TOP->FLT_TOP</title> +<path fill="none" stroke="#555555" d="M1065.71,-853.88C1022.73,-853.35 937.09,-849.49 868,-828.78 822.79,-815.23 774.91,-788.16 746.24,-770.39"/> +<polygon fill="#555555" stroke="#555555" points="747.56,-768.74 741.36,-767.33 745.33,-772.3 747.56,-768.74"/> +</g> +<!-- PTR_TOP --> +<g id="node22" class="node"> +<title>PTR_TOP</title> +<ellipse fill="#008000" stroke="black" cx="1093" cy="-752.29" rx="61.7" ry="28.99"/> +<text text-anchor="middle" x="1093" y="-756.44" font-family="DejaVu Sans" font-size="13.00" fill="white">⊤:ptr</text> +<text text-anchor="middle" x="1093" y="-739.94" font-family="DejaVu Sans" font-size="13.00" fill="white">[*⊤:struct]</text> +</g> +<!-- TOP->PTR_TOP --> +<g id="edge80" class="edge"> +<title>TOP->PTR_TOP</title> +<path fill="none" stroke="#555555" d="M1093,-836.74C1093,-823.62 1093,-805.05 1093,-788.76"/> +<polygon fill="#555555" stroke="#555555" points="1095.1,-788.97 1093,-782.97 1090.9,-788.97 1095.1,-788.97"/> +</g> +<!-- STRUCT_TOP --> +<g id="node32" class="node"> +<title>STRUCT_TOP</title> +<ellipse fill="#90ee90" stroke="black" cx="1480" cy="-752.29" rx="64.35" ry="28.99"/> +<text text-anchor="middle" x="1480" y="-756.44" font-family="DejaVu Sans" font-size="13.00">⊤:struct</text> +<text text-anchor="middle" x="1480" y="-739.94" font-family="DejaVu Sans" font-size="13.00">[struct top]</text> +</g> +<!-- TOP->STRUCT_TOP --> +<g id="edge81" class="edge"> +<title>TOP->STRUCT_TOP</title> +<path fill="none" stroke="#555555" d="M1119.97,-852.78C1178.13,-850.35 1313.55,-843.3 1357,-828.78 1388.2,-818.36 1419.74,-798.78 1443.07,-782.17"/> +<polygon fill="#555555" stroke="#555555" points="1444.26,-783.9 1447.9,-778.68 1441.8,-780.49 1444.26,-783.9"/> +</g> +<!-- MEM_TOP --> +<g id="node38" class="node"> +<title>MEM_TOP</title> +<ellipse fill="#00008b" stroke="black" cx="1807" cy="-752.29" rx="44.7" ry="18"/> +<text text-anchor="middle" x="1807" y="-748.19" font-family="DejaVu Sans" font-size="13.00" fill="white">⊤:mem</text> +</g> +<!-- TOP->MEM_TOP --> +<g id="edge82" class="edge"> +<title>TOP->MEM_TOP</title> +<path fill="none" stroke="#555555" d="M1120.14,-853.58C1230.92,-852.61 1645.66,-847.74 1701,-828.78 1734.02,-817.47 1765.78,-792.33 1785.79,-774.16"/> +<polygon fill="#555555" stroke="#555555" points="1787.02,-775.88 1790,-770.26 1784.17,-772.8 1787.02,-775.88"/> +</g> +<!-- TUPLE_TOP --> +<g id="node43" class="node"> +<title>TUPLE_TOP</title> +<ellipse fill="#ffc0cb" stroke="black" cx="2048" cy="-752.29" rx="44.7" ry="18"/> +<text text-anchor="middle" x="2048" y="-748.19" font-family="DejaVu Sans" font-size="13.00">⊤:tuple</text> +</g> +<!-- TOP->TUPLE_TOP --> +<g id="edge83" class="edge"> +<title>TOP->TUPLE_TOP</title> +<path fill="none" stroke="#555555" d="M1120.01,-853.69C1265.56,-853.09 1951.36,-849.22 1991,-828.78 2012.45,-817.73 2028.06,-794.49 2037.46,-776.7"/> +<polygon fill="#555555" stroke="#555555" points="2039.12,-778.07 2039.96,-771.77 2035.37,-776.17 2039.12,-778.07"/> +</g> +<!-- BOT --> +<g id="node2" class="node"> +<title>BOT</title> +<ellipse fill="black" stroke="black" cx="1158" cy="-18" rx="27" ry="18"/> +<text text-anchor="middle" x="1158" y="-13.9" font-family="DejaVu Sans" font-size="13.00" fill="white">⊥</text> +</g> +<!-- CTRL --> +<g id="node4" class="node"> +<title>CTRL</title> +<ellipse fill="#ffff00" stroke="black" cx="53" cy="-111.99" rx="36.51" ry="18"/> +<text text-anchor="middle" x="53" y="-107.89" font-family="DejaVu Sans" font-size="13.00">⊥:ctrl</text> +</g> +<!-- XCTRL->CTRL --> +<g id="edge1" class="edge"> +<title>XCTRL->CTRL</title> +<path fill="none" stroke="#555555" d="M53,-733.84C53,-699.39 53,-620.21 53,-553.64 53,-553.64 53,-553.64 53,-292.98 53,-237.49 53,-172.38 53,-137.7"/> +<polygon fill="#555555" stroke="#555555" points="55.1,-137.88 53,-131.88 50.9,-137.88 55.1,-137.88"/> +</g> +<!-- XCTRL->INT_TOP --> +<!-- CTRL->BOT --> +<g id="edge84" class="edge"> +<title>CTRL->BOT</title> +<path fill="none" stroke="#555555" d="M68.82,-95.67C77.79,-87.99 89.68,-79.4 102,-75 199.9,-40.01 951.33,-23.1 1123.11,-19.66"/> +<polygon fill="#555555" stroke="#555555" points="1123.14,-21.76 1129.1,-19.55 1123.06,-17.57 1123.14,-21.76"/> +</g> +<!-- INT_HI --> +<g id="node7" class="node"> +<title>INT_HI</title> +<ellipse fill="lightblue" stroke="black" cx="303" cy="-658.3" rx="61.08" ry="18"/> +<text text-anchor="middle" x="303" y="-654.2" font-family="DejaVu Sans" font-size="13.00">max < min</text> +</g> +<!-- INT_TOP->INT_HI --> +<g id="edge2" class="edge"> +<title>INT_TOP->INT_HI</title> +<path fill="none" stroke="#555555" d="M325.05,-734.42C320.88,-720.2 314.85,-699.69 310.16,-683.69"/> +<polygon fill="#555555" stroke="#555555" points="312.24,-683.31 308.53,-678.14 308.21,-684.49 312.24,-683.31"/> +</g> +<!-- INT_TOP->FLT_TOP --> +<!-- INT_BOT --> +<g id="node6" class="node"> +<title>INT_BOT</title> +<ellipse fill="lightblue" stroke="black" cx="316" cy="-111.99" rx="33.95" ry="18"/> +<text text-anchor="start" x="299.12" y="-108.89" font-family="DejaVu Sans" font-weight="bold" font-size="13.00">⊥</text> +<text text-anchor="start" x="311.12" y="-108.89" font-family="DejaVu Sans" font-size="13.00">:int</text> +</g> +<!-- INT_BOT->BOT --> +<g id="edge85" class="edge"> +<title>INT_BOT->BOT</title> +<path fill="none" stroke="#555555" d="M334.62,-96.69C345.94,-88.82 361.06,-79.72 376,-75 518.37,-30.04 991.01,-21.01 1123.31,-19.35"/> +<polygon fill="#555555" stroke="#555555" points="1123.32,-21.45 1129.3,-19.28 1123.27,-17.25 1123.32,-21.45"/> +</g> +<!-- INT_XBOOL --> +<g id="node8" class="node"> +<title>INT_XBOOL</title> +<ellipse fill="lightblue" stroke="black" cx="211" cy="-552.64" rx="31.39" ry="18"/> +<text text-anchor="middle" x="211" y="-548.54" font-family="DejaVu Sans" font-size="13.00">1...0</text> +</g> +<!-- INT_HI->INT_XBOOL --> +<g id="edge3" class="edge"> +<title>INT_HI->INT_XBOOL</title> +<path fill="none" stroke="#555555" d="M288.22,-640.65C272.25,-622.65 246.77,-593.94 229.48,-574.47"/> +<polygon fill="#555555" stroke="#555555" points="231.4,-573.46 225.85,-570.37 228.26,-576.25 231.4,-573.46"/> +</g> +<!-- INT_CON --> +<g id="node9" class="node"> +<title>INT_CON</title> +<ellipse fill="lightblue" stroke="black" cx="309" cy="-411.98" rx="54.93" ry="18"/> +<text text-anchor="middle" x="309" y="-407.88" font-family="DejaVu Sans" font-size="13.00">constants</text> +</g> +<!-- INT_HI->INT_CON --> +<g id="edge6" class="edge"> +<title>INT_HI->INT_CON</title> +<path fill="none" stroke="#555555" d="M303.42,-640.12C304.47,-597.64 307.17,-487.54 308.39,-437.9"/> +<polygon fill="#555555" stroke="#555555" points="310.49,-438.03 308.53,-431.98 306.29,-437.93 310.49,-438.03"/> +</g> +<!-- INT_CON0 --> +<g id="node10" class="node"> +<title>INT_CON0</title> +<ellipse fill="lightblue" stroke="black" cx="141" cy="-411.98" rx="27" ry="18"/> +<text text-anchor="middle" x="141" y="-407.88" font-family="DejaVu Sans" font-size="13.00">0</text> +</g> +<!-- INT_XBOOL->INT_CON0 --> +<g id="edge4" class="edge"> +<title>INT_XBOOL->INT_CON0</title> +<path fill="none" stroke="#555555" d="M202.56,-534.92C190.09,-510.21 166.7,-463.9 152.62,-436.01"/> +<polygon fill="#555555" stroke="#555555" points="154.52,-435.1 149.94,-430.69 150.77,-436.99 154.52,-435.1"/> +</g> +<!-- INT_CON1 --> +<g id="node11" class="node"> +<title>INT_CON1</title> +<ellipse fill="lightblue" stroke="black" cx="211" cy="-411.98" rx="27" ry="18"/> +<text text-anchor="middle" x="211" y="-407.88" font-family="DejaVu Sans" font-size="13.00">1</text> +</g> +<!-- INT_XBOOL->INT_CON1 --> +<g id="edge5" class="edge"> +<title>INT_XBOOL->INT_CON1</title> +<path fill="none" stroke="#555555" d="M211,-534.36C211,-510.07 211,-465.7 211,-437.86"/> +<polygon fill="#555555" stroke="#555555" points="213.1,-437.99 211,-431.99 208.9,-437.99 213.1,-437.99"/> +</g> +<!-- INT_LO --> +<g id="node13" class="node"> +<title>INT_LO</title> +<ellipse fill="lightblue" stroke="black" cx="303" cy="-208.48" rx="61.08" ry="18"/> +<text text-anchor="middle" x="303" y="-204.38" font-family="DejaVu Sans" font-size="13.00">max > min</text> +</g> +<!-- INT_CON->INT_LO --> +<g id="edge10" class="edge"> +<title>INT_CON->INT_LO</title> +<path fill="none" stroke="#555555" d="M308.49,-393.8C307.43,-358.13 304.98,-275.9 303.74,-234.4"/> +<polygon fill="#555555" stroke="#555555" points="305.84,-234.35 303.56,-228.42 301.64,-234.48 305.84,-234.35"/> +</g> +<!-- INT_CON0->INT_CON1 --> +<!-- INT_BOOL --> +<g id="node12" class="node"> +<title>INT_BOOL</title> +<ellipse fill="lightblue" stroke="black" cx="211" cy="-293.98" rx="31.39" ry="18"/> +<text text-anchor="middle" x="211" y="-289.88" font-family="DejaVu Sans" font-size="13.00">0...1</text> +</g> +<!-- INT_CON0->INT_BOOL --> +<g id="edge7" class="edge"> +<title>INT_CON0->INT_BOOL</title> +<path fill="none" stroke="#555555" d="M150.73,-394.85C162.84,-374.8 183.57,-340.43 197.28,-317.71"/> +<polygon fill="#555555" stroke="#555555" points="199.04,-318.87 200.34,-312.64 195.44,-316.7 199.04,-318.87"/> +</g> +<!-- INT_CON1->INT_CON --> +<!-- INT_CON1->INT_BOOL --> +<g id="edge8" class="edge"> +<title>INT_CON1->INT_BOOL</title> +<path fill="none" stroke="#555555" d="M211,-393.62C211,-374.05 211,-342.1 211,-319.88"/> +<polygon fill="#555555" stroke="#555555" points="213.1,-319.98 211,-313.98 208.9,-319.98 213.1,-319.98"/> +</g> +<!-- INT_BOOL->INT_LO --> +<g id="edge9" class="edge"> +<title>INT_BOOL->INT_LO</title> +<path fill="none" stroke="#555555" d="M227.03,-278.44C241.55,-265.26 263.13,-245.67 279.59,-230.73"/> +<polygon fill="#555555" stroke="#555555" points="280.8,-232.47 283.83,-226.88 277.98,-229.36 280.8,-232.47"/> +</g> +<!-- INT_LO->INT_BOT --> +<g id="edge11" class="edge"> +<title>INT_LO->INT_BOT</title> +<path fill="none" stroke="#555555" d="M305.38,-190.15C307.42,-175.37 310.37,-153.94 312.64,-137.42"/> +<polygon fill="#555555" stroke="#555555" points="314.69,-137.94 313.42,-131.71 310.53,-137.37 314.69,-137.94"/> +</g> +<!-- FLT_CON64 --> +<g id="node16" class="node"> +<title>FLT_CON64</title> +<ellipse fill="aqua" stroke="black" cx="790" cy="-552.64" rx="65.94" ry="40.66"/> +<text text-anchor="middle" x="790" y="-565.04" font-family="DejaVu Sans" font-size="13.00">64b consts</text> +<text text-anchor="middle" x="790" y="-548.54" font-family="DejaVu Sans" font-size="13.00">[excludes</text> +<text text-anchor="middle" x="790" y="-532.04" font-family="DejaVu Sans" font-size="13.00">32b consts]</text> +</g> +<!-- FLT_TOP->FLT_CON64 --> +<g id="edge14" class="edge"> +<title>FLT_TOP->FLT_CON64</title> +<path fill="none" stroke="#555555" d="M725.97,-734.44C736.43,-704.9 758.41,-642.83 773.68,-599.71"/> +<polygon fill="#555555" stroke="#555555" points="775.64,-600.48 775.66,-594.12 771.68,-599.08 775.64,-600.48"/> +</g> +<!-- FLT_CONPI --> +<g id="node18" class="node"> +<title>FLT_CONPI</title> +<ellipse fill="aqua" stroke="black" cx="651" cy="-552.64" rx="56.98" ry="18"/> +<text text-anchor="middle" x="651" y="-548.54" font-family="DejaVu Sans" font-size="13.00">3.14159...</text> +</g> +<!-- FLT_TOP->FLT_CONPI --> +<g id="edge15" class="edge"> +<title>FLT_TOP->FLT_CONPI</title> +<path fill="none" stroke="#555555" d="M714.12,-734.44C701.88,-699.39 673.65,-618.52 659.46,-577.88"/> +<polygon fill="#555555" stroke="#555555" points="661.52,-577.42 657.56,-572.44 657.56,-578.8 661.52,-577.42"/> +</g> +<!-- FLT_X32 --> +<g id="node19" class="node"> +<title>FLT_X32</title> +<ellipse fill="aqua" stroke="black" cx="518" cy="-658.3" rx="32.93" ry="18"/> +<text text-anchor="middle" x="518" y="-654.2" font-family="DejaVu Sans" font-size="13.00">~f32</text> +</g> +<!-- FLT_TOP->FLT_X32 --> +<g id="edge18" class="edge"> +<title>FLT_TOP->FLT_X32</title> +<path fill="none" stroke="#555555" d="M696.03,-740.38C659.58,-723.78 590.16,-692.16 549.62,-673.7"/> +<polygon fill="#555555" stroke="#555555" points="550.59,-671.83 544.26,-671.26 548.85,-675.66 550.59,-671.83"/> +</g> +<!-- FLT_TOP->PTR_TOP --> +<!-- FLT_BOT --> +<g id="node15" class="node"> +<title>FLT_BOT</title> +<ellipse fill="aqua" stroke="black" cx="720" cy="-111.99" rx="31.39" ry="18"/> +<text text-anchor="start" x="705" y="-108.89" font-family="DejaVu Sans" font-weight="bold" font-size="13.00">⊥</text> +<text text-anchor="start" x="717" y="-108.89" font-family="DejaVu Sans" font-size="13.00">:flt</text> +</g> +<!-- FLT_BOT->BOT --> +<g id="edge86" class="edge"> +<title>FLT_BOT->BOT</title> +<path fill="none" stroke="#555555" d="M748.28,-103.69C778,-96.11 826.14,-84.12 868,-75 960.59,-54.81 1070.63,-34.59 1124.67,-24.9"/> +<polygon fill="#555555" stroke="#555555" points="1124.89,-26.99 1130.43,-23.87 1124.15,-22.86 1124.89,-26.99"/> +</g> +<!-- FLT_CON64->FLT_BOT --> +<g id="edge16" class="edge"> +<title>FLT_CON64->FLT_BOT</title> +<path fill="none" stroke="#555555" d="M783.66,-511.94C769.47,-423.02 735.48,-210 723.92,-137.58"/> +<polygon fill="#555555" stroke="#555555" points="726.01,-137.32 722.99,-131.73 721.86,-137.98 726.01,-137.32"/> +</g> +<!-- FLT_CON32 --> +<g id="node17" class="node"> +<title>FLT_CON32</title> +<ellipse fill="aqua" stroke="black" cx="518" cy="-552.64" rx="60.05" ry="18"/> +<text text-anchor="middle" x="518" y="-548.54" font-family="DejaVu Sans" font-size="13.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="518" cy="-411.98" rx="27" ry="18"/> +<text text-anchor="middle" x="518" y="-407.88" font-family="DejaVu Sans" font-size="13.00">f32</text> +</g> +<!-- FLT_CON32->FLT_32 --> +<g id="edge22" class="edge"> +<title>FLT_CON32->FLT_32</title> +<path fill="none" stroke="#555555" d="M518,-534.36C518,-510.07 518,-465.7 518,-437.86"/> +<polygon fill="#555555" stroke="#555555" points="520.1,-437.99 518,-431.99 515.9,-437.99 520.1,-437.99"/> +</g> +<!-- FLT_CONPI->FLT_BOT --> +<g id="edge17" class="edge"> +<title>FLT_CONPI->FLT_BOT</title> +<path fill="none" stroke="#555555" d="M653.75,-534.18C664.5,-465.79 703.78,-216.13 716.2,-137.13"/> +<polygon fill="#555555" stroke="#555555" points="718.23,-137.78 717.08,-131.53 714.08,-137.13 718.23,-137.78"/> +</g> +<!-- FLT_CONPI->FLT_CON64 --> +<!-- FLT_X32->FLT_CON32 --> +<g id="edge20" class="edge"> +<title>FLT_X32->FLT_CON32</title> +<path fill="none" stroke="#555555" d="M518,-640.18C518,-623.4 518,-597.64 518,-578.58"/> +<polygon fill="#555555" stroke="#555555" points="520.1,-578.64 518,-572.64 515.9,-578.64 520.1,-578.64"/> +</g> +<!-- FLT_CON0 --> +<g id="node20" class="node"> +<title>FLT_CON0</title> +<ellipse fill="aqua" stroke="black" cx="415" cy="-552.64" rx="27" ry="18"/> +<text text-anchor="middle" x="415" y="-548.54" font-family="DejaVu Sans" font-size="13.00">0.</text> +</g> +<!-- FLT_X32->FLT_CON0 --> +<g id="edge19" class="edge"> +<title>FLT_X32->FLT_CON0</title> +<path fill="none" stroke="#555555" d="M501.38,-642.45C487.36,-629.74 466.92,-610.77 450,-593.3 444.13,-587.24 437.97,-580.42 432.47,-574.17"/> +<polygon fill="#555555" stroke="#555555" points="434.16,-572.91 428.64,-569.77 431,-575.67 434.16,-572.91"/> +</g> +<!-- FLT_CON0->FLT_CON32 --> +<!-- FLT_CON0->FLT_32 --> +<g id="edge21" class="edge"> +<title>FLT_CON0->FLT_32</title> +<path fill="none" stroke="#555555" d="M426.62,-536.01C445.1,-511.12 481.26,-462.44 502.13,-434.35"/> +<polygon fill="#555555" stroke="#555555" points="503.79,-435.63 505.68,-429.57 500.42,-433.13 503.79,-435.63"/> +</g> +<!-- FLT_32->FLT_BOT --> +<g id="edge23" class="edge"> +<title>FLT_32->FLT_BOT</title> +<path fill="none" stroke="#555555" d="M528.58,-395.38C562.1,-345.93 666.07,-192.55 705.04,-135.05"/> +<polygon fill="#555555" stroke="#555555" points="706.56,-136.56 708.19,-130.41 703.08,-134.2 706.56,-136.56"/> +</g> +<!-- PTR_NULL --> +<g id="node24" class="node"> +<title>PTR_NULL</title> +<ellipse fill="#008000" stroke="black" cx="1219" cy="-658.3" rx="27.3" ry="18"/> +<text text-anchor="middle" x="1219" y="-654.2" font-family="DejaVu Sans" font-size="13.00" fill="white">null</text> +</g> +<!-- PTR_TOP->PTR_NULL --> +<g id="edge33" class="edge"> +<title>PTR_TOP->PTR_NULL</title> +<path fill="none" stroke="#555555" d="M1125.78,-727.36C1147.49,-711.51 1175.48,-691.07 1195.1,-676.75"/> +<polygon fill="#555555" stroke="#555555" points="1196.33,-678.45 1199.93,-673.22 1193.85,-675.06 1196.33,-678.45"/> +</g> +<!-- PTR_PERSON --> +<g id="node26" class="node"> +<title>PTR_PERSON</title> +<ellipse fill="#008000" stroke="black" cx="962" cy="-658.3" rx="45.72" ry="18"/> +<text text-anchor="middle" x="962" y="-654.2" font-family="DejaVu Sans" font-size="13.00" fill="white">*Person</text> +</g> +<!-- PTR_TOP->PTR_PERSON --> +<g id="edge34" class="edge"> +<title>PTR_TOP->PTR_PERSON</title> +<path fill="none" stroke="#555555" d="M1059.26,-727.6C1037.69,-712.45 1010.05,-693.04 989.76,-678.79"/> +<polygon fill="#555555" stroke="#555555" points="991.06,-677.14 984.95,-675.41 988.65,-680.58 991.06,-677.14"/> +</g> +<!-- PTR_S1 --> +<g id="node27" class="node"> +<title>PTR_S1</title> +<ellipse fill="#008000" stroke="black" cx="1051" cy="-658.3" rx="27" ry="18"/> +<text text-anchor="middle" x="1051" y="-654.2" font-family="DejaVu Sans" font-size="13.00" fill="white">*s1</text> +</g> +<!-- PTR_TOP->PTR_S1 --> +<g id="edge35" class="edge"> +<title>PTR_TOP->PTR_S1</title> +<path fill="none" stroke="#555555" d="M1080.4,-723.69C1074.4,-710.56 1067.32,-695.04 1061.6,-682.53"/> +<polygon fill="#555555" stroke="#555555" points="1063.62,-681.88 1059.22,-677.29 1059.8,-683.62 1063.62,-681.88"/> +</g> +<!-- PTR_MORE --> +<g id="node28" class="node"> +<title>PTR_MORE</title> +<ellipse fill="#008000" stroke="black" cx="1135" cy="-658.3" rx="40.6" ry="18"/> +<text text-anchor="middle" x="1135" y="-654.2" font-family="DejaVu Sans" font-size="13.00" fill="white">*s2, …</text> +</g> +<!-- PTR_TOP->PTR_MORE --> +<g id="edge36" class="edge"> +<title>PTR_TOP->PTR_MORE</title> +<path fill="none" stroke="#555555" d="M1105.6,-723.69C1111.55,-710.65 1118.59,-695.25 1124.28,-682.78"/> +<polygon fill="#555555" stroke="#555555" points="1126.08,-683.9 1126.66,-677.57 1122.26,-682.15 1126.08,-683.9"/> +</g> +<!-- PTR_TOP->STRUCT_TOP --> +<!-- PTR_BOT --> +<g id="node23" class="node"> +<title>PTR_BOT</title> +<ellipse fill="#008000" stroke="black" cx="1158" cy="-111.99" rx="66.47" ry="28.99"/> +<text text-anchor="middle" x="1158" y="-116.14" font-family="DejaVu Sans" font-size="13.00" fill="white">⊥:ptr</text> +<text text-anchor="middle" x="1158" y="-99.64" font-family="DejaVu Sans" font-size="13.00" fill="white">[*⊥:struct?]</text> +</g> +<!-- PTR_BOT->BOT --> +<g id="edge87" class="edge"> +<title>PTR_BOT->BOT</title> +<path fill="none" stroke="#555555" d="M1158,-82.64C1158,-70.25 1158,-55.86 1158,-43.89"/> +<polygon fill="#555555" stroke="#555555" points="1160.1,-43.94 1158,-37.94 1155.9,-43.94 1160.1,-43.94"/> +</g> +<!-- PTR_PERSON_NIL --> +<g id="node29" class="node"> +<title>PTR_PERSON_NIL</title> +<ellipse fill="#008000" stroke="black" cx="1111" cy="-552.64" rx="50.33" ry="18"/> +<text text-anchor="middle" x="1111" y="-548.54" font-family="DejaVu Sans" font-size="13.00" fill="white">*Person?</text> +</g> +<!-- PTR_NULL->PTR_PERSON_NIL --> +<g id="edge43" class="edge"> +<title>PTR_NULL->PTR_PERSON_NIL</title> +<path fill="none" stroke="#555555" d="M1203.98,-642.89C1185.68,-625.32 1154.58,-595.47 1133.44,-575.18"/> +<polygon fill="#555555" stroke="#555555" points="1134.9,-573.67 1129.12,-571.03 1131.99,-576.7 1134.9,-573.67"/> +</g> +<!-- PTR_S1_NIL --> +<g id="node30" class="node"> +<title>PTR_S1_NIL</title> +<ellipse fill="#008000" stroke="black" cx="1208" cy="-552.64" rx="30.37" ry="18"/> +<text text-anchor="middle" x="1208" y="-548.54" font-family="DejaVu Sans" font-size="13.00" fill="white">*s1?</text> +</g> +<!-- PTR_NULL->PTR_S1_NIL --> +<g id="edge44" class="edge"> +<title>PTR_NULL->PTR_S1_NIL</title> +<path fill="none" stroke="#555555" d="M1217.18,-640.18C1215.39,-623.3 1212.64,-597.33 1210.61,-578.24"/> +<polygon fill="#555555" stroke="#555555" points="1212.7,-578.03 1209.98,-572.29 1208.52,-578.48 1212.7,-578.03"/> +</g> +<!-- PTR_MORE_NIL --> +<g id="node31" class="node"> +<title>PTR_MORE_NIL</title> +<ellipse fill="#008000" stroke="black" cx="1300" cy="-552.64" rx="45.21" ry="18"/> +<text text-anchor="middle" x="1300" y="-548.54" font-family="DejaVu Sans" font-size="13.00" fill="white">*s2?, …</text> +</g> +<!-- PTR_NULL->PTR_MORE_NIL --> +<g id="edge45" class="edge"> +<title>PTR_NULL->PTR_MORE_NIL</title> +<path fill="none" stroke="#555555" d="M1230.95,-642C1244.59,-624.55 1267.02,-595.85 1282.6,-575.91"/> +<polygon fill="#555555" stroke="#555555" points="1284.22,-577.24 1286.26,-571.22 1280.92,-574.65 1284.22,-577.24"/> +</g> +<!-- PTR_ANY --> +<g id="node25" class="node"> +<title>PTR_ANY</title> +<ellipse fill="#008000" stroke="black" cx="962" cy="-552.64" rx="82.38" ry="28.99"/> +<text text-anchor="middle" x="962" y="-556.79" font-family="DejaVu Sans" font-size="13.00" fill="white">*⊥:struct</text> +<text text-anchor="middle" x="962" y="-540.29" font-family="DejaVu Sans" font-size="13.00" fill="white">[ptr any struct]</text> +</g> +<!-- PTR_ANY->PTR_BOT --> +<g id="edge46" class="edge"> +<title>PTR_ANY->PTR_BOT</title> +<path fill="none" stroke="#555555" d="M974.56,-523.53C1008.99,-446.47 1104.84,-231.98 1142.51,-147.66"/> +<polygon fill="#555555" stroke="#555555" points="1144.4,-148.58 1144.93,-142.25 1140.56,-146.87 1144.4,-148.58"/> +</g> +<!-- PTR_ANY->PTR_PERSON_NIL --> +<!-- PTR_PERSON->PTR_ANY --> +<g id="edge37" class="edge"> +<title>PTR_PERSON->PTR_ANY</title> +<path fill="none" stroke="#555555" d="M962,-640.18C962,-626.3 962,-606.26 962,-588.96"/> +<polygon fill="#555555" stroke="#555555" points="964.1,-589.25 962,-583.25 959.9,-589.25 964.1,-589.25"/> +</g> +<!-- PTR_PERSON->PTR_S1 --> +<!-- PTR_PERSON->PTR_PERSON_NIL --> +<g id="edge40" class="edge"> +<title>PTR_PERSON->PTR_PERSON_NIL</title> +<path fill="none" stroke="#555555" d="M983.67,-642.23C1009.89,-623.98 1054.1,-593.22 1082.92,-573.18"/> +<polygon fill="#555555" stroke="#555555" points="1083.85,-575.09 1087.58,-569.94 1081.45,-571.64 1083.85,-575.09"/> +</g> +<!-- PTR_S1->PTR_ANY --> +<g id="edge38" class="edge"> +<title>PTR_S1->PTR_ANY</title> +<path fill="none" stroke="#555555" d="M1038.25,-642.45C1025.79,-627.94 1006.41,-605.36 990.3,-586.6"/> +<polygon fill="#555555" stroke="#555555" points="991.91,-585.25 986.4,-582.07 988.72,-587.99 991.91,-585.25"/> +</g> +<!-- PTR_S1->PTR_MORE --> +<!-- PTR_S1->PTR_S1_NIL --> +<g id="edge41" class="edge"> +<title>PTR_S1->PTR_S1_NIL</title> +<path fill="none" stroke="#555555" d="M1072.08,-646.82C1101.29,-632.14 1152.34,-605.85 1169,-593.3 1176.35,-587.76 1183.64,-580.85 1189.88,-574.36"/> +<polygon fill="#555555" stroke="#555555" points="1191.26,-575.96 1193.83,-570.14 1188.2,-573.09 1191.26,-575.96"/> +</g> +<!-- PTR_MORE->PTR_NULL --> +<!-- PTR_MORE->PTR_ANY --> +<g id="edge39" class="edge"> +<title>PTR_MORE->PTR_ANY</title> +<path fill="none" stroke="#555555" d="M1111.67,-643.32C1085.45,-627.61 1042.2,-601.69 1008.92,-581.75"/> +<polygon fill="#555555" stroke="#555555" points="1010.35,-580.16 1004.12,-578.88 1008.19,-583.77 1010.35,-580.16"/> +</g> +<!-- PTR_MORE->PTR_MORE_NIL --> +<g id="edge42" class="edge"> +<title>PTR_MORE->PTR_MORE_NIL</title> +<path fill="none" stroke="#555555" d="M1160.16,-643.83C1182.97,-631.38 1217.31,-612.02 1246,-593.3 1255.42,-587.15 1265.42,-579.99 1274.23,-573.46"/> +<polygon fill="#555555" stroke="#555555" points="1275.36,-575.24 1278.9,-569.97 1272.84,-571.88 1275.36,-575.24"/> +</g> +<!-- PTR_PERSON_NIL->PTR_BOT --> +<g id="edge47" class="edge"> +<title>PTR_PERSON_NIL->PTR_BOT</title> +<path fill="none" stroke="#555555" d="M1112.87,-534.18C1119.87,-468.84 1144.61,-238.01 1154.18,-148.67"/> +<polygon fill="#555555" stroke="#555555" points="1156.26,-148.92 1154.81,-142.73 1152.09,-148.47 1156.26,-148.92"/> +</g> +<!-- PTR_PERSON_NIL->PTR_S1_NIL --> +<!-- PTR_S1_NIL->PTR_BOT --> +<g id="edge48" class="edge"> +<title>PTR_S1_NIL->PTR_BOT</title> +<path fill="none" stroke="#555555" d="M1206.04,-534.45C1198.64,-469.49 1172.28,-238.26 1162.08,-148.74"/> +<polygon fill="#555555" stroke="#555555" points="1164.16,-148.51 1161.4,-142.79 1159.99,-148.99 1164.16,-148.51"/> +</g> +<!-- PTR_S1_NIL->PTR_MORE_NIL --> +<!-- PTR_MORE_NIL->PTR_BOT --> +<g id="edge49" class="edge"> +<title>PTR_MORE_NIL->PTR_BOT</title> +<path fill="none" stroke="#555555" d="M1294.43,-534.45C1273.34,-469.29 1198.07,-236.78 1169.3,-147.89"/> +<polygon fill="#555555" stroke="#555555" points="1171.38,-147.49 1167.53,-142.43 1167.38,-148.78 1171.38,-147.49"/> +</g> +<!-- STRUCT_PERSON --> +<g id="node34" class="node"> +<title>STRUCT_PERSON</title> +<polygon fill="#90ee90" stroke="black" points="1436.5,-228.98 1369.5,-228.98 1369.5,-187.98 1436.5,-187.98 1436.5,-228.98"/> +<text text-anchor="middle" x="1403" y="-212.63" font-family="DejaVu Sans" font-size="13.00">Person</text> +<text text-anchor="middle" x="1403" y="-196.13" font-family="DejaVu Sans" font-size="13.00">age: int</text> +</g> +<!-- STRUCT_TOP->STRUCT_PERSON --> +<g id="edge53" class="edge"> +<title>STRUCT_TOP->STRUCT_PERSON</title> +<path fill="none" stroke="#555555" d="M1468.98,-723.31C1455.09,-685.46 1433,-615.54 1433,-553.64 1433,-553.64 1433,-553.64 1433,-410.98 1433,-347.98 1418.48,-275.1 1409.64,-236.59"/> +<polygon fill="#555555" stroke="#555555" points="1411.7,-236.2 1408.3,-230.83 1407.61,-237.15 1411.7,-236.2"/> +</g> +<!-- STRUCT_S1 --> +<g id="node35" class="node"> +<title>STRUCT_S1</title> +<polygon fill="#90ee90" stroke="black" points="1507,-228.98 1453,-228.98 1453,-187.98 1507,-187.98 1507,-228.98"/> +<text text-anchor="middle" x="1480" y="-212.63" font-family="DejaVu Sans" font-size="13.00">s1</text> +<text text-anchor="middle" x="1480" y="-196.13" font-family="DejaVu Sans" font-size="13.00">x: int</text> +</g> +<!-- STRUCT_TOP->STRUCT_S1 --> +<g id="edge54" class="edge"> +<title>STRUCT_TOP->STRUCT_S1</title> +<path fill="none" stroke="#555555" d="M1480,-722.82C1480,-684.41 1480,-613.86 1480,-553.64 1480,-553.64 1480,-553.64 1480,-410.98 1480,-348.51 1480,-275.13 1480,-236.47"/> +<polygon fill="#555555" stroke="#555555" points="1482.1,-236.73 1480,-230.73 1477.9,-236.73 1482.1,-236.73"/> +</g> +<!-- STRUCT_S2 --> +<g id="node36" class="node"> +<title>STRUCT_S2</title> +<polygon fill="#90ee90" stroke="black" points="1619.12,-228.98 1522.88,-228.98 1522.88,-187.98 1619.12,-187.98 1619.12,-228.98"/> +<text text-anchor="middle" x="1571" y="-212.63" font-family="DejaVu Sans" font-size="13.00">s2</text> +<text text-anchor="middle" x="1571" y="-196.13" font-family="DejaVu Sans" font-size="13.00">x: int, y: *s1</text> +</g> +<!-- STRUCT_TOP->STRUCT_S2 --> +<g id="edge55" class="edge"> +<title>STRUCT_TOP->STRUCT_S2</title> +<path fill="none" stroke="#555555" d="M1492.66,-723.47C1508.62,-685.79 1534,-616.07 1534,-553.64 1534,-553.64 1534,-553.64 1534,-410.98 1534,-347.63 1551.91,-274.88 1562.81,-236.49"/> +<polygon fill="#555555" stroke="#555555" points="1564.83,-237.08 1564.47,-230.74 1560.79,-235.92 1564.83,-237.08"/> +</g> +<!-- STRUCT_MORE --> +<g id="node37" class="node"> +<title>STRUCT_MORE</title> +<polygon fill="#90ee90" stroke="black" points="1689,-226.48 1635,-226.48 1635,-190.48 1689,-190.48 1689,-226.48"/> +<text text-anchor="middle" x="1662" y="-204.38" font-family="DejaVu Sans" font-size="13.00">…</text> +</g> +<!-- STRUCT_TOP->STRUCT_MORE --> +<g id="edge56" class="edge"> +<title>STRUCT_TOP->STRUCT_MORE</title> +<path fill="none" stroke="#555555" d="M1509.78,-726.19C1547.31,-691.55 1607,-625.22 1607,-553.64 1607,-553.64 1607,-553.64 1607,-410.98 1607,-344.76 1634.99,-270.47 1651.04,-233.33"/> +<polygon fill="#555555" stroke="#555555" points="1652.79,-234.56 1653.28,-228.22 1648.94,-232.87 1652.79,-234.56"/> +</g> +<!-- STRUCT_TOP->MEM_TOP --> +<!-- STRUCT_BOT --> +<g id="node33" class="node"> +<title>STRUCT_BOT</title> +<ellipse fill="#90ee90" stroke="black" cx="1480" cy="-111.99" rx="82.91" ry="28.99"/> +<text text-anchor="middle" x="1480" y="-116.14" font-family="DejaVu Sans" font-size="13.00">⊥:struct</text> +<text text-anchor="middle" x="1480" y="-99.64" font-family="DejaVu Sans" font-size="13.00">[struct bottom]</text> +</g> +<!-- STRUCT_BOT->BOT --> +<g id="edge88" class="edge"> +<title>STRUCT_BOT->BOT</title> +<path fill="none" stroke="#555555" d="M1417.46,-92.56C1398.09,-86.88 1376.68,-80.65 1357,-75 1298.06,-58.08 1229.14,-38.8 1189.83,-27.85"/> +<polygon fill="#555555" stroke="#555555" points="1190.64,-25.89 1184.3,-26.31 1189.52,-29.94 1190.64,-25.89"/> +</g> +<!-- STRUCT_PERSON->STRUCT_BOT --> +<g id="edge57" class="edge"> +<title>STRUCT_PERSON->STRUCT_BOT</title> +<path fill="none" stroke="#555555" d="M1418.95,-187.9C1428.91,-175.69 1441.97,-159.66 1453.46,-145.57"/> +<polygon fill="#555555" stroke="#555555" points="1454.82,-147.22 1456.98,-141.24 1451.56,-144.57 1454.82,-147.22"/> +</g> +<!-- STRUCT_PERSON->STRUCT_S1 --> +<!-- STRUCT_S1->STRUCT_BOT --> +<g id="edge58" class="edge"> +<title>STRUCT_S1->STRUCT_BOT</title> +<path fill="none" stroke="#555555" d="M1480,-187.9C1480,-176.5 1480,-161.78 1480,-148.41"/> +<polygon fill="#555555" stroke="#555555" points="1482.1,-148.66 1480,-142.66 1477.9,-148.66 1482.1,-148.66"/> +</g> +<!-- STRUCT_S1->STRUCT_S2 --> +<!-- STRUCT_S2->STRUCT_BOT --> +<g id="edge59" class="edge"> +<title>STRUCT_S2->STRUCT_BOT</title> +<path fill="none" stroke="#555555" d="M1552.14,-187.9C1540.18,-175.48 1524.43,-159.12 1510.69,-144.86"/> +<polygon fill="#555555" stroke="#555555" points="1512.46,-143.67 1506.78,-140.8 1509.43,-146.58 1512.46,-143.67"/> +</g> +<!-- STRUCT_S2->STRUCT_MORE --> +<!-- STRUCT_MORE->STRUCT_BOT --> +<g id="edge60" class="edge"> +<title>STRUCT_MORE->STRUCT_BOT</title> +<path fill="none" stroke="#555555" d="M1634.54,-192.06C1632,-190.67 1629.45,-189.29 1627,-187.98 1596.23,-171.57 1561.48,-153.81 1533.49,-139.69"/> +<polygon fill="#555555" stroke="#555555" points="1534.55,-137.87 1528.25,-137.05 1532.67,-141.62 1534.55,-137.87"/> +</g> +<!-- MEM_ALIAS2 --> +<g id="node40" class="node"> +<title>MEM_ALIAS2</title> +<ellipse fill="#00008b" stroke="black" cx="1758" cy="-293.98" rx="45.21" ry="18"/> +<text text-anchor="middle" x="1758" y="-289.88" font-family="DejaVu Sans" font-size="13.00" fill="white">MEM#2</text> +</g> +<!-- MEM_TOP->MEM_ALIAS2 --> +<g id="edge63" class="edge"> +<title>MEM_TOP->MEM_ALIAS2</title> +<path fill="none" stroke="#555555" d="M1805.14,-733.96C1797.62,-663.94 1769.47,-401.76 1760.65,-319.7"/> +<polygon fill="#555555" stroke="#555555" points="1762.75,-319.58 1760.02,-313.84 1758.58,-320.03 1762.75,-319.58"/> +</g> +<!-- MEM_ALIAS3 --> +<g id="node41" class="node"> +<title>MEM_ALIAS3</title> +<ellipse fill="#00008b" stroke="black" cx="1864" cy="-293.98" rx="45.21" ry="18"/> +<text text-anchor="middle" x="1864" y="-289.88" font-family="DejaVu Sans" font-size="13.00" fill="white">MEM#3</text> +</g> +<!-- MEM_TOP->MEM_ALIAS3 --> +<g id="edge64" class="edge"> +<title>MEM_TOP->MEM_ALIAS3</title> +<path fill="none" stroke="#555555" d="M1809.16,-733.96C1817.91,-663.94 1850.66,-401.76 1860.91,-319.7"/> +<polygon fill="#555555" stroke="#555555" points="1862.99,-320.05 1861.65,-313.83 1858.82,-319.53 1862.99,-320.05"/> +</g> +<!-- MEM_MORE --> +<g id="node42" class="node"> +<title>MEM_MORE</title> +<ellipse fill="#00008b" stroke="black" cx="1952" cy="-293.98" rx="27" ry="18"/> +<text text-anchor="middle" x="1952" y="-289.88" font-family="DejaVu Sans" font-size="13.00" fill="white">…</text> +</g> +<!-- MEM_TOP->MEM_MORE --> +<g id="edge65" class="edge"> +<title>MEM_TOP->MEM_MORE</title> +<path fill="none" stroke="#555555" d="M1812.51,-733.96C1834.85,-663.64 1918.78,-399.51 1944.48,-318.66"/> +<polygon fill="#555555" stroke="#555555" points="1946.37,-319.64 1946.18,-313.29 1942.36,-318.37 1946.37,-319.64"/> +</g> +<!-- MEM_TOP->TUPLE_TOP --> +<!-- MEM_BOT --> +<g id="node39" class="node"> +<title>MEM_BOT</title> +<ellipse fill="#00008b" stroke="black" cx="1811" cy="-111.99" rx="44.7" ry="18"/> +<text text-anchor="middle" x="1811" y="-107.89" font-family="DejaVu Sans" font-size="13.00" fill="white">⊥:mem</text> +</g> +<!-- MEM_BOT->BOT --> +<g id="edge89" class="edge"> +<title>MEM_BOT->BOT</title> +<path fill="none" stroke="#555555" d="M1779.72,-98.78C1757.97,-90.77 1728.12,-80.77 1701,-75 1511.81,-34.78 1279.16,-23.1 1192.59,-20.01"/> +<polygon fill="#555555" stroke="#555555" points="1192.74,-17.92 1186.67,-19.81 1192.59,-22.11 1192.74,-17.92"/> +</g> +<!-- MEM_ALIAS2->MEM_BOT --> +<g id="edge66" class="edge"> +<title>MEM_ALIAS2->MEM_BOT</title> +<path fill="none" stroke="#555555" d="M1763.08,-275.72C1772.58,-243.47 1793.04,-173.99 1803.9,-137.12"/> +<polygon fill="#555555" stroke="#555555" points="1805.83,-138 1805.51,-131.65 1801.8,-136.81 1805.83,-138"/> +</g> +<!-- MEM_ALIAS2->MEM_ALIAS3 --> +<!-- MEM_ALIAS3->MEM_BOT --> +<g id="edge67" class="edge"> +<title>MEM_ALIAS3->MEM_BOT</title> +<path fill="none" stroke="#555555" d="M1858.92,-275.72C1849.42,-243.47 1828.96,-173.99 1818.1,-137.12"/> +<polygon fill="#555555" stroke="#555555" points="1820.2,-136.81 1816.49,-131.65 1816.17,-138 1820.2,-136.81"/> +</g> +<!-- MEM_ALIAS3->MEM_MORE --> +<!-- MEM_MORE->MEM_BOT --> +<g id="edge68" class="edge"> +<title>MEM_MORE->MEM_BOT</title> +<path fill="none" stroke="#555555" d="M1939.98,-277.64C1915.01,-245.76 1857.44,-172.28 1828.41,-135.22"/> +<polygon fill="#555555" stroke="#555555" points="1830.29,-134.21 1824.94,-130.79 1826.99,-136.8 1830.29,-134.21"/> +</g> +<!-- TUPLE1 --> +<g id="node45" class="node"> +<title>TUPLE1</title> +<polygon fill="#ffc0cb" stroke="none" points="2046.88,-438.48 2003.12,-438.48 2003.12,-385.48 2046.88,-385.48 2046.88,-438.48"/> +<polygon fill="#ffc0cb" stroke="none" points="2003.12,-411.98 2003.12,-438.48 2046.88,-438.48 2046.88,-411.98 2003.12,-411.98"/> +<polygon fill="none" stroke="black" points="2003.12,-411.98 2003.12,-438.48 2046.88,-438.48 2046.88,-411.98 2003.12,-411.98"/> +<text text-anchor="start" x="2008.12" y="-421.13" font-family="DejaVu Sans" font-size="13.00">tuple</text> +<polygon fill="black" stroke="none" points="2003.12,-385.48 2003.12,-411.98 2046.88,-411.98 2046.88,-385.48 2003.12,-385.48"/> +<polygon fill="none" stroke="black" points="2003.12,-385.48 2003.12,-411.98 2046.88,-411.98 2046.88,-385.48 2003.12,-385.48"/> +<text text-anchor="start" x="2010.38" y="-394.63" font-family="DejaVu Sans" font-size="13.00" fill="white">type</text> +</g> +<!-- TUPLE_TOP->TUPLE1 --> +<g id="edge71" class="edge"> +<title>TUPLE_TOP->TUPLE1</title> +<path fill="none" stroke="#555555" d="M2046.83,-734.05C2043.18,-680.39 2031.99,-515.78 2027.21,-445.42"/> +<polygon fill="#555555" stroke="#555555" points="2029.31,-445.47 2026.81,-439.63 2025.12,-445.75 2029.31,-445.47"/> +</g> +<!-- TUPLE2 --> +<g id="node46" class="node"> +<title>TUPLE2</title> +<polygon fill="#ffc0cb" stroke="none" points="2106.88,-451.73 2063.12,-451.73 2063.12,-372.23 2106.88,-372.23 2106.88,-451.73"/> +<polygon fill="#ffc0cb" stroke="none" points="2063.12,-425.23 2063.12,-451.73 2106.88,-451.73 2106.88,-425.23 2063.12,-425.23"/> +<polygon fill="none" stroke="black" points="2063.12,-425.23 2063.12,-451.73 2106.88,-451.73 2106.88,-425.23 2063.12,-425.23"/> +<text text-anchor="start" x="2068.12" y="-434.38" font-family="DejaVu Sans" font-size="13.00">tuple</text> +<polygon fill="black" stroke="none" points="2063.12,-398.73 2063.12,-425.23 2106.88,-425.23 2106.88,-398.73 2063.12,-398.73"/> +<polygon fill="none" stroke="black" points="2063.12,-398.73 2063.12,-425.23 2106.88,-425.23 2106.88,-398.73 2063.12,-398.73"/> +<text text-anchor="start" x="2070.38" y="-407.88" font-family="DejaVu Sans" font-size="13.00" fill="white">type</text> +<polygon fill="black" stroke="none" points="2063.12,-372.23 2063.12,-398.73 2106.88,-398.73 2106.88,-372.23 2063.12,-372.23"/> +<polygon fill="none" stroke="black" points="2063.12,-372.23 2063.12,-398.73 2106.88,-398.73 2106.88,-372.23 2063.12,-372.23"/> +<text text-anchor="start" x="2070.38" y="-381.38" font-family="DejaVu Sans" font-size="13.00" fill="white">type</text> +</g> +<!-- TUPLE_TOP->TUPLE2 --> +<g id="edge72" class="edge"> +<title>TUPLE_TOP->TUPLE2</title> +<path fill="none" stroke="#555555" d="M2049.89,-734.05C2055.41,-683.57 2071.67,-534.87 2079.98,-458.86"/> +<polygon fill="#555555" stroke="#555555" points="2082.03,-459.43 2080.6,-453.24 2077.86,-458.97 2082.03,-459.43"/> +</g> +<!-- TUPLEN --> +<g id="node47" class="node"> +<title>TUPLEN</title> +<polygon fill="#ffc0cb" stroke="none" points="2166.88,-464.98 2123.12,-464.98 2123.12,-358.98 2166.88,-358.98 2166.88,-464.98"/> +<polygon fill="#ffc0cb" stroke="none" points="2123.12,-438.48 2123.12,-464.98 2166.88,-464.98 2166.88,-438.48 2123.12,-438.48"/> +<polygon fill="none" stroke="black" points="2123.12,-438.48 2123.12,-464.98 2166.88,-464.98 2166.88,-438.48 2123.12,-438.48"/> +<text text-anchor="start" x="2128.12" y="-447.63" font-family="DejaVu Sans" font-size="13.00">tuple</text> +<polygon fill="black" stroke="none" points="2123.12,-411.98 2123.12,-438.48 2166.88,-438.48 2166.88,-411.98 2123.12,-411.98"/> +<polygon fill="none" stroke="black" points="2123.12,-411.98 2123.12,-438.48 2166.88,-438.48 2166.88,-411.98 2123.12,-411.98"/> +<text text-anchor="start" x="2130.38" y="-421.13" font-family="DejaVu Sans" font-size="13.00" fill="white">type</text> +<polygon fill="black" stroke="none" points="2123.12,-385.48 2123.12,-411.98 2166.88,-411.98 2166.88,-385.48 2123.12,-385.48"/> +<polygon fill="none" stroke="black" points="2123.12,-385.48 2123.12,-411.98 2166.88,-411.98 2166.88,-385.48 2123.12,-385.48"/> +<text text-anchor="start" x="2138.62" y="-394.63" font-family="DejaVu Sans" font-size="13.00" fill="white">…</text> +<polygon fill="black" stroke="none" points="2123.12,-358.98 2123.12,-385.48 2166.88,-385.48 2166.88,-358.98 2123.12,-358.98"/> +<polygon fill="none" stroke="black" points="2123.12,-358.98 2123.12,-385.48 2166.88,-385.48 2166.88,-358.98 2123.12,-358.98"/> +<text text-anchor="start" x="2130.38" y="-368.13" font-family="DejaVu Sans" font-size="13.00" fill="white">type</text> +</g> +<!-- TUPLE_TOP->TUPLEN --> +<g id="edge73" class="edge"> +<title>TUPLE_TOP->TUPLEN</title> +<path fill="none" stroke="#555555" d="M2052.94,-734.05C2066.64,-686.28 2105.56,-550.54 2128.17,-471.69"/> +<polygon fill="#555555" stroke="#555555" points="2130.12,-472.51 2129.75,-466.17 2126.08,-471.35 2130.12,-472.51"/> +</g> +<!-- TUPLE_BOT --> +<g id="node44" class="node"> +<title>TUPLE_BOT</title> +<ellipse fill="#ffc0cb" stroke="black" cx="2066" cy="-111.99" rx="44.7" ry="18"/> +<text text-anchor="middle" x="2066" y="-107.89" font-family="DejaVu Sans" font-size="13.00">⊥:tuple</text> +</g> +<!-- TUPLE_BOT->BOT --> +<g id="edge90" class="edge"> +<title>TUPLE_BOT->BOT</title> +<path fill="none" stroke="#555555" d="M2041.91,-96.52C2027.63,-88.7 2008.88,-79.7 1991,-75 1836.4,-34.32 1329.78,-22.17 1192.55,-19.58"/> +<polygon fill="#555555" stroke="#555555" points="1192.72,-17.49 1186.68,-19.47 1192.64,-21.69 1192.72,-17.49"/> +</g> +<!-- TUPLE1->TUPLE_BOT --> +<g id="edge74" class="edge"> +<title>TUPLE1->TUPLE_BOT</title> +<path fill="none" stroke="#555555" d="M2028.5,-385.58C2036.28,-328.98 2054.97,-193.16 2062.63,-137.46"/> +<polygon fill="#555555" stroke="#555555" points="2064.7,-137.88 2063.43,-131.65 2060.53,-137.3 2064.7,-137.88"/> +</g> +<!-- TUPLE1->TUPLE2 --> +<!-- TUPLE2->TUPLE_BOT --> +<g id="edge75" class="edge"> +<title>TUPLE2->TUPLE_BOT</title> +<path fill="none" stroke="#555555" d="M2082.54,-372.33C2078.57,-310.17 2070.89,-189.71 2067.58,-137.79"/> +<polygon fill="#555555" stroke="#555555" points="2069.68,-137.72 2067.2,-131.86 2065.49,-137.98 2069.68,-137.72"/> +</g> +<!-- TUPLE2->TUPLEN --> +<!-- TUPLEN->TUPLE_BOT --> +<g id="edge76" class="edge"> +<title>TUPLEN->TUPLE_BOT</title> +<path fill="none" stroke="#555555" d="M2131.24,-359.08C2114.03,-294.18 2085.29,-185.76 2072.49,-137.48"/> +<polygon fill="#555555" stroke="#555555" points="2074.53,-136.98 2070.97,-131.72 2070.47,-138.06 2074.53,-136.98"/> +</g> +</g> +</svg> |
