doc/ref: remove ranges from spec

With the addition of unary operators, ranges are superfluous.

Advantages:
- less things to learn
- removes a level of operator precedence
- removes an operator
- removes somewhat complicated semantics
  for ranges of two different types

Change-Id: Ia705bf578ef5a5d2a49620b2cfc5190c881d1b06
diff --git a/doc/ref/impl.md b/doc/ref/impl.md
index 2db4fc5..59a1ca6 100644
--- a/doc/ref/impl.md
+++ b/doc/ref/impl.md
@@ -67,7 +67,7 @@
 3.14
 string
 "Hello"
-0..10
+>=0
 <8
 re("Hello .*!")
 ```
@@ -304,8 +304,8 @@
 function `f` for `string` returns `"foo"` for `f("foo")` and `_|_` for `f(1)`.
 Constraint functions may take other constraint functions as arguments to
 produce a more restricting constraint function.
-For instance, the constraint function `f` for `0..8` returns `5` for `f(5)`,
-`5..8` for `f(5..10)`, and `_|_` for `f("foo")`.
+For instance, the constraint function `f` for `<=8` returns `5` for `f(5)`,
+`>=5 & <=8` for `f(>=5)`, and `_|_` for `f("foo")`.
 
 
 Constraint functions play a special role in unification.
diff --git a/doc/ref/spec.md b/doc/ref/spec.md
index 34049aa..0b56d40 100644
--- a/doc/ref/spec.md
+++ b/doc/ref/spec.md
@@ -273,7 +273,7 @@
 -    mod   ||    <     <=    [    ]
 *    quo   !     >     >=    {    }
 /    rem   &     :     <-    ;    ,
-%    _|_   |     =     ...   ..   .
+%    _|_   |     =           ...  .
 ```
 <!-- :: for "is-a" definitions -->
 
@@ -857,7 +857,7 @@
 ### Bounds
 
 A _bound_, syntactically_ a [unary expression](#Operands), defines
-a (possibly infinite) disjunction of concrete values than can be represented
+an infinite disjunction of concrete values than can be represented
 as a single comparison.
 
 For any [comparison operator](#Comparison-operators) `op` except `==`,
@@ -867,7 +867,7 @@
 2 & >=2 & <=5           // 2, where 2 is either an int or float.
 2.5 & >=1 & <=5         // 2.5
 2 & >=1.0 & <3.0        // 2.0
-2 & 1..3.0              // 2.0
+2 & >1 & <3.0           // 2.0
 2.5 & int & >1 & <5     // _|_
 2.5 & float & >1 & <5   // 2.5
 int & 2 & >1.0 & <3.0   // _|_
@@ -878,32 +878,6 @@
 ```
 
 
-### Ranges
-
-A _range type_, syntactically a [binary expression](#Operands), defines
-a (possibly infinite) disjunction of concrete values that can be represented
-as a contiguous range.
-A concrete value `c` unifies with `a..b` if `a <= c` and `c <= b`.
-Ranges can be defined on numbers and strings.
-
-A range of numbers `a..b` defines an inclusive range for integers and
-floating-point numbers.
-
-Remember that an integer literal represents both an `int` and `float`:
-```
-2   & 1..5          // 2, where 2 is either an int or float.
-2.5 & 1..5          // 2.5
-2 & 1.0..3.0        // 2.0
-2 & 1..3.0          // 2.0
-2.5 & int & 1..5    // _|_
-2.5 & float & 1..5  // 2.5
-int & 2 & 1.0..3.0  // _|_
-2.5 & (int & 1)..5  // _|_
-0..7 & 3..10        // 3..7
-"foo" & "a".."n"    // "foo"
-```
-
-
 ### Structs
 
 A _struct_ is a set of elements called _fields_, each of
@@ -965,20 +939,21 @@
 ```
 
 ```
-Expression                  Result
-{a: int, a: 1}               {a: int(1)}
-{a: int} & {a: 1}            {a: int(1)}
-{a: 1..7} & {a: 5..9}        {a: 5..7}
-{a: 1..7, a: 5..9}           {a: 5..7}
+Expression                             Result
+{a: int, a: 1}                         {a: int(1)}
+{a: int} & {a: 1}                      {a: int(1)}
+{a: >=1 & <=7} & {a: >=5 & <=9}        {a: >=5 & <=7}
+{a: >=1 & <=7, a: >=5 & <=9}           {a: >=5 & <=7}
 
-{a: 1} & {b: 2}              {a: 1, b: 2}
-{a: 1, b: int} & {b: 2}      {a: 1, b: int(2)}
+{a: 1} & {b: 2}                        {a: 1, b: 2}
+{a: 1, b: int} & {b: 2}                {a: 1, b: int(2)}
 
-{a: 1} & {a: 2}              _|_
+{a: 1} & {a: 2}                        _|_
 ```
 
 In addition to fields, a struct literal may also define aliases.
-Aliases name values that can be referred to within the [scope](#declarations-and-scopes) of their
+Aliases name values that can be referred to
+within the [scope](#declarations-and-scopes) of their
 definition, but are not part of the struct: aliases are irrelevant to
 the partial ordering of values and are not emitted as part of any
 generated data.
@@ -1136,19 +1111,19 @@
 
 Derived   Value
 number    int | float
-uint      0..int
-uint8     0..255
-int8      -128..127
-uint16    0..65536
-int16     -32_768...32_767
-rune      0..0x10FFFF
-uint32    0..4_294_967_296
-int32     -2_147_483_648..2_147_483_647
-uint64    0..18_446_744_073_709_551_615
-int64     -9_223_372_036_854_775_808..9_223_372_036_854_775_807
-uint128   340_282_366_920_938_463_463_374_607_431_768_211_455
-int128    -170_141_183_460_469_231_731_687_303_715_884_105_728..
-           170_141_183_460_469_231_731_687_303_715_884_105_727
+uint      >=0
+uint8     >=0 & <=255
+int8      >=-128 & <=127
+uint16    >=0 & <=65536
+int16     >=-32_768 & <=32_767
+rune      >=0 & <=0x10FFFF
+uint32    >=0 & <=4_294_967_296
+int32     >=-2_147_483_648 & <=2_147_483_647
+uint64    >=0 & <=18_446_744_073_709_551_615
+int64     >=-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807
+uint128   >=0 & <=340_282_366_920_938_463_463_374_607_431_768_211_455
+int128    >=-170_141_183_460_469_231_731_687_303_715_884_105_728 &
+           <=170_141_183_460_469_231_731_687_303_715_884_105_727
 ```
 
 
@@ -1412,7 +1387,7 @@
 Expression = UnaryExpr | Expression binary_op Expression .
 UnaryExpr  = PrimaryExpr | unary_op UnaryExpr .
 
-binary_op  = "|" | "&" | "||" | "&&" | "==" | rel_op | add_op | mul_op | ".."  .
+binary_op  = "|" | "&" | "||" | "&&" | "==" | rel_op | add_op | mul_op  .
 rel_op     = "!=" | "<" | "<=" | ">" | ">=" .
 add_op     = "+" | "-" .
 mul_op     = "*" | "/" | "%" | "div" | "mod" | "quo" | "rem" .
@@ -1436,14 +1411,13 @@
 Unary operators have the highest precedence.
 
 There are eight precedence levels for binary operators.
-The `..` operator (range) binds strongest, followed by
-multiplication operators, addition operators, comparison operators,
+Multiplication operators binds strongest, followed by
+addition operators, comparison operators,
 `&&` (logical AND), `||` (logical OR), `&` (unification),
 and finally `|` (disjunction):
 
 ```
 Precedence    Operator
-    8             ..
     7             *  /  %  div mod quo rem
     6             +  -
     5             ==  !=  <  <=  >  >=
@@ -1579,8 +1553,8 @@
 Suggestion from jba:
 Multiplication should distribute over disjunction,
 so int(1)..int(3) * [x] = [x] | [x, x] | [x, x, x].
-The hard part is figuring out what 1..3 * [x] means,
-since 1..3 includes many floats.
+The hard part is figuring out what (>=1 & <=3) * [x] means,
+since  >=1 & <=3 includes many floats.
 (mpvl: could constrain arguments to parameter types, but needs to be
 done consistently.)
 -->
@@ -1641,11 +1615,11 @@
 <!-- jba
 I think I know what `3 < a` should mean if
 
-    a: 1..5
-    
+    a: >=1 & <=5
+
 It should be a constraint on `a` that can be evaluated once `a`'s value is known more precisely.
 
-But what does `3 < 1..5` mean? We'll never get more information, so it must have a definite value.
+But what does `3 < (>=1 & <=5)` mean? We'll never get more information, so it must have a definite value.
 -->
 
 #### Logical operators
diff --git a/doc/tutorial/basics/lists.md b/doc/tutorial/basics/lists.md
index f583308..dd1889f 100644
--- a/doc/tutorial/basics/lists.md
+++ b/doc/tutorial/basics/lists.md
@@ -10,7 +10,7 @@
 additional, possibly typed elements.
 
 In the example we define `IP` to be a list of `4` elements of type `uint8`, which
-is a predeclared value of `0..255`.
+is a predeclared value of `>=0 & <=255`.
 `PrivateIP` defines the IP ranges defined for private use.
 Note that as it is already defined to be an `IP`, the length of the list
 is already fixed at `4` and we do not have to specify a value for all elements.
@@ -25,7 +25,7 @@
 IP: 4 * [ uint8 ]
 
 PrivateIP: IP
-PrivateIP: [10, ...uint8] | [192, 168, ...] | [172, 16..32, ...]
+PrivateIP: [10, ...uint8] | [192, 168, ...] | [172, >=16 & <=32, ...]
 
 myIP: PrivateIP
 myIP: [10, 2, 3, 4]
@@ -36,11 +36,11 @@
 
 <!-- result -->
 ```
-IP: [0..255, 0..255, 0..255, 0..255]
+IP: [>=0 & <=255, >=0 & <=255, >=0 & <=255, >=0 & <=255]
 PrivateIP:
-    [10, 0..255, 0..255, 0..255] |
-    [192, 168, 0..255, 0..255] |
-    [172, 16..32, 0..255, 0..255]
+    [10, >=0 & <=255, >=0 & <=255, >=0 & <=255] |
+    [192, 168, >=0 & <=255, >=0 & <=255] |
+    [172, >=16 & <=32, >=0 & <=255, >=0 & <=255]
 
 myIP:   [10, 2, 3, 4]
 yourIP: _|_
diff --git a/doc/tutorial/basics/rangedef.md b/doc/tutorial/basics/rangedef.md
index 39da35b..7553558 100644
--- a/doc/tutorial/basics/rangedef.md
+++ b/doc/tutorial/basics/rangedef.md
@@ -11,19 +11,19 @@
 integers to common values.
 
 ```
-uint      0..int
-uint8     0..255
-int8      -128..127
-uint16    0..65536
-int16     -32_768...32_767
-rune      0..0x10FFFF
-uint32    0..4_294_967_296
-int32     -2_147_483_648..2_147_483_647
-uint64    0..18_446_744_073_709_551_615
-int64     -9_223_372_036_854_775_808..9_223_372_036_854_775_807
-int128    -170_141_183_460_469_231_731_687_303_715_884_105_728..
-              170_141_183_460_469_231_731_687_303_715_884_105_727
-uint128   0..340_282_366_920_938_463_463_374_607_431_768_211_455
+uint      >=0
+uint8     >=0 & <=255
+int8      >=-128 & <=127
+uint16    >=0 & <=65536
+int16     >=-32_768 & <=.32_767
+rune      >=0 & <=0x10FFFF
+uint32    >=0 & <=4_294_967_296
+int32     >=-2_147_483_648 & <=2_147_483_647
+uint64    >=0 & <=18_446_744_073_709_551_615
+int64     >=-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807
+int128    >=-170_141_183_460_469_231_731_687_303_715_884_105_728 &
+              <=170_141_183_460_469_231_731_687_303_715_884_105_727
+uint128   >=0 & <=340_282_366_920_938_463_463_374_607_431_768_211_455
 ```
 
 <!-- CUE editor -->
diff --git a/doc/tutorial/basics/ranges.md b/doc/tutorial/basics/ranges.md
index da50c1c..548845b 100644
--- a/doc/tutorial/basics/ranges.md
+++ b/doc/tutorial/basics/ranges.md
@@ -2,23 +2,22 @@
 
 _Types ~~and~~ are Values_
 
-# Ranges
+# Bounds
 
-Ranges define an inclusive range of valid values.
-They work on numbers, strings, and bytes.
+Bounds define a lower bound, upper bound, or inequality for a certain value.
+They work on numbers, strings, bytes, and and null.
 
-The type of a range is the unification of the types of the start and end
-value.
-
-Unifying two ranges results in the overlapping range or an error if there
-is no overlap.
+The bound is defined for all values for which the corresponding comparison
+operation is define.
+For instance `>5.0` allows all floating point values greater than `5.0`,
+whereas `<0` allows all negative numbers (int or float).
 
 <!-- CUE editor -->
 ```
-rn: 3..5       // type int | float
-ri: 3..5 & int // type int
-rf: 3..5.0     // type float
-rs: "a".."mo"
+rn: >=3 & <8        // type int | float
+ri: >=3 & <8 & int  // type int
+rf: >=3 & <=8.0     // type float
+rs: >="a" & <"mo"
 
 {
     a: rn & 3.5
@@ -27,7 +26,7 @@
     d: rs & "ma"
     e: rs & "mu"
 
-    r1: 0..7 & 3..10
+    r1: rn & >=5 & <10
 }
 ```
 
@@ -38,5 +37,5 @@
 c:  3.0
 d:  "ma"
 e:  _|_
-r1: 3..7
+r1: >=5 & <8
 ```