| 107 | | * `Integer` : the mathematical integers |
| 108 | | * `Int[lo,hi,wrap]` |
| 109 | | * `lo`, `hi` are concrete (?) integers, `wrap` is boolean |
| 110 | | * finite interval of integers `[lo,hi]`. If `wrap` is true then all operations "wrap", otherwise, any operation resulting in a value outside of the interval results in an exception being thrown. |
| 111 | | * **Do we want to allow `lo` and `hi` to be any values of type `Integer`, which means they are dynamic types, like complete array types?** |
| 112 | | * `HerbrandInt` : Herbrand integers. Values are unsimplified symbolic expressions. |
| 113 | | * `Real` : the mathematical real numbers |
| 114 | | * `Float[e,f]`, `e`, `f` are concrete integers, each at least 1. |
| 115 | | * IEEE754 floating point numbers. This type includes NaNs, negative 0s, infinities, etc. |
| 116 | | * `HerbrandReal` : Herbrand real numbers. Values are unsimplified symbolic expressions. |
| | 107 | * The **numeric types** |
| | 108 | * The **integral types** |
| | 109 | * `Integer` : the mathematical integers |
| | 110 | * `Int[lo,hi,wrap]` |
| | 111 | * `lo`, `hi` are concrete (?) integers, `wrap` is boolean |
| | 112 | * finite interval of integers `[lo,hi]`. If `wrap` is true then all operations "wrap", otherwise, any operation resulting in a value outside of the interval results in an exception being thrown. |
| | 113 | * **Do we want to allow `lo` and `hi` to be any values of type `Integer`, which means they are dynamic types, like complete array types?** |
| | 114 | * The **real types** |
| | 115 | * `Real` : the mathematical real numbers |
| | 116 | * `Float[e,f]`, `e`, `f` are concrete integers, each at least 1. |
| | 117 | * IEEE754 floating point numbers. This type includes NaNs, negative 0s, infinities, etc. |
| | 118 | * Herbrand[T], for a non-Herbrand numeric type `T` |
| | 119 | * the values of this type are (unsimplified) symbolic expressions. Each numeric operator is treated as an uninterpreted function. The leaf nodes in an expression are values of type `T`. Two values are equal iff the two symbolic expressions are identical (using equality in `T` on the leaf nodes). A value of Herbrand type may therefore be thought of as representing an expression in `T` but where all the numerical operations have been "delayed". |
| 202 | | * `herbrand(e)`: given a Real or Float value, returns the value as a `HerbrandReal`. Given an `Integer` or `Int` value, returns the value as a `HerbrandInt`. |
| 203 | | * `real(e)`: given any numerical value e, returns it as a real number |
| 204 | | * functions for converting floats to reals and back. |
| 205 | | * functions for converting between Ints and Integers -- or is there a subtype relation? If so, it must respect all operations. |
| | 205 | * `herbrand(e)`: given a numeric value of type `T`, returns the value as type `Herbrand[T]`, a trivial symbolic expression consisting of a single node. |
| | 206 | * `eval(e)` : given a value of type `Herbrand[T]`, returns the value of type `T` obtained by evaluating all the delayed operations |
| 263 | | * A cast can only take place when there is no change to the underlying value. It is only for changing the type. Example: one can cast from any integral type to another, but there might be an exception if the value is not in the range of the targeted type. One can cast any `Float` value to a `Real` value, but not the other way. (To convert from a `Real` to a `Float`, use, e.g., `round`.) If t1 is a subtype of t2, one can always cast from t1 to t2 (though this is rarely necessary, since an expression of type t1 can be used wherever one of type t2 is expected). |
| | 264 | * A cast can only take place when there is no change to the underlying value in the concrete semantics. It is only for changing the type. |
| | 265 | * One can cast from any integral type to another (as the values in all cases are integers), but there might be an exception if the value is not in the range of the targeted type. |
| | 266 | * One can cast any `Float` value to a `Real` value, but not the other way. (To convert from a `Real` to a `Float`, use, e.g., `round`.) One cannot cast from one `Float` type to another `Float` type (unless the float parameters are exactly the same). To do this, one could instead use `round`. |
| | 267 | * If t1 is a subtype of t2, one can always cast from t1 to t2 (though this is rarely necessary, since an expression of type t1 can be used wherever one of type t2 is expected). One can also cast from t2 to t1, but a runtime exception will be thrown if the value being cast does not already belong to t1. For example, one might cast from `Domain` to `Domain[n]`, or from `Array[Real]` to `Array[Real, n]`. |
| | 268 | * One cannot cast between a Herbrand type and any other type. Instead, use functions `eval` and `herbrand`. |