@@ -908,6 +908,7 @@ patterns for doing so, refer to K's
908
908
``` k
909
909
module LIST
910
910
imports private INT-SYNTAX
911
+ imports private MINT-SYNTAX
911
912
imports private BASIC-K
912
913
913
914
syntax List [hook(LIST.List)]
@@ -957,21 +958,25 @@ An element can be added to the front of a `List` using the `pushList` operator.
957
958
### List indexing
958
959
959
960
You can get an element of a list by its integer offset in O(log(N)) time, or
960
- effectively constant. Positive indices are 0-indexed from the beginning of the
961
+ effectively constant. Positive ` Int ` indices are 0-indexed from the beginning of the
961
962
list, and negative indices are -1-indexed from the end of the list. In other
962
- words, 0 is the first element and -1 is the last element.
963
+ words, 0 is the first element and -1 is the last element. The indice can also be
964
+ ` MInt ` , which is interprested as an unsigned integer, and therefore, don't support
965
+ negative indices feature. Currently, only 64-bit and 256-bit ` MInt ` types are supported.
963
966
964
967
``` k
965
968
syntax KItem ::= List "[" Int "]" [function, hook(LIST.get), symbol(List:get)]
969
+ syntax {Width} KItem ::= List "[" MInt{Width} "]" [function, hook(LIST.getMInt), symbol(List:getMInt)]
966
970
```
967
971
968
972
### List update
969
973
970
974
You can create a new ` List ` with a new value at a particular index in
971
- O(log(N)) time, or effectively constant.
975
+ O(log(N)) time, or effectively constant. The index can be either as an ` Int ` or as an ` MInt ` . Currently, only 64-bit ` MInt ` type is supported.
972
976
973
977
``` k
974
978
syntax List ::= List "[" index: Int "<-" value: KItem "]" [function, hook(LIST.update), symbol(List:set)]
979
+ syntax {Width} List ::= List "[" index: MInt{Width} "<-" value: KItem "]" [function, hook(LIST.updateMInt), symbol(List:setMInt)]
975
980
```
976
981
977
982
### List of identical elements
@@ -1023,10 +1028,16 @@ comparisons, it is much better to first convert to a set using `List2Set`.
1023
1028
1024
1029
### List size
1025
1030
1026
- You can get the number of elements of a list in O(1) time.
1031
+ You can get the number of elements of a list in O(1) time. The output
1032
+ size can be either as an ` Int ` or as an ` MInt ` . Currently, only 64-bit
1033
+ and 256-bit ` MInt ` types are supported. When using ` MInt ` , the size is
1034
+ interpreted as an unsigned integer, and the size of the list must match
1035
+ the bounds of this ` MInt ` type, that is the size can't be larger than
1036
+ ` 2^64 - 1 ` for ` MInt{64} ` and ` 2^256 - 1 ` for ` MInt{256} ` .
1027
1037
1028
1038
``` k
1029
1039
syntax Int ::= size(List) [function, total, hook(LIST.size), symbol(sizeList), smtlib(smt_seq_len)]
1040
+ syntax {Width} MInt{Width} ::= size(List) [function, hook(LIST.sizeMInt), symbol(sizeMInt)]
1030
1041
```
1031
1042
1032
1043
``` k
@@ -2010,6 +2021,7 @@ endmodule
2010
2021
module BYTES-HOOKED
2011
2022
imports STRING-SYNTAX
2012
2023
imports BYTES-SYNTAX
2024
+ imports MINT-SYNTAX
2013
2025
imports BYTES-STRING-ENCODE
2014
2026
```
2015
2027
@@ -2085,22 +2097,25 @@ mutations of the input or output value.
2085
2097
2086
2098
### Bytes update
2087
2099
2088
- You can set the value of a particular byte in a ` Bytes ` object in O(1) time.
2089
- The result is ` #False ` if ` value ` is not in the range [ 0..255] or if ` index `
2090
- is not a valid index (ie, less than zero or greater than or equal to the length
2091
- of the ` Bytes ` term).
2100
+ You can set the value of a particular byte in a ` Bytes ` object in O(1) time,
2101
+ either with index and value as ` Int ` or as an ` MInt ` . Currently, only 64-bit
2102
+ and 256-bit ` MInt ` types are supported. The result is ` #False ` if ` value ` is
2103
+ not in the range [ 0..255] or if ` index ` is not a valid index (ie, less than
2104
+ zero or greater than or equal to the length of the ` Bytes ` term).
2092
2105
2093
2106
``` k
2094
2107
syntax Bytes ::= Bytes "[" index: Int "<-" value: Int "]" [function, hook(BYTES.update)]
2108
+ syntax {Width} Bytes ::= Bytes "[" index: MInt{Width} "<-" value: MInt{Width} "]" [function, hook(BYTES.updateMInt)]
2095
2109
```
2096
2110
2097
2111
### Bytes lookup
2098
2112
2099
- You can get the value of a particular byte in a ` Bytes ` object in O(1) time.
2113
+ You can get the value of a particular byte in a ` Bytes ` object in O(1) time, either as an ` Int ` or as an ` MInt ` . Currently, only 64-bit and 256-bit ` MInt ` types are supported .
2100
2114
The result is ` #False ` if ` index ` is not a valid index (see above).
2101
2115
2102
2116
``` k
2103
2117
syntax Int ::= Bytes "[" Int "]" [function, hook(BYTES.get)]
2118
+ syntax {Width} MInt{Width} ::= Bytes "[" MInt{Width} "]" [function, hook(BYTES.getMInt)]
2104
2119
```
2105
2120
2106
2121
### Bytes substring
@@ -2109,9 +2124,12 @@ You can get a new `Bytes` object containing a range of bytes from the input
2109
2124
` Bytes ` in O(N) time (where N is the length of the substring). The range
2110
2125
of bytes included is ` [startIndex..endIndex) ` . The resulting ` Bytes ` is
2111
2126
a copy and mutations to it do not affect mutations to the original ` Bytes ` .
2127
+ Both ` startIndex ` and ` endIndex ` can be either ` Int ` or ` MInt ` values, but,
2128
+ currently, only 64-bit and 256-bit ` MInt ` types are supported.
2112
2129
2113
2130
``` k
2114
2131
syntax Bytes ::= substrBytes(Bytes, startIndex: Int, endIndex: Int) [function, hook(BYTES.substr)]
2132
+ syntax {Width} Bytes ::= substrBytes(Bytes, startIndex: MInt{Width}, endIndex: MInt{Width}) [function, hook(BYTES.substrMInt)]
2115
2133
```
2116
2134
2117
2135
The function is not total: ` substrBytes(B, startIndex, endIndex) ` is ` #Bottom ` if
@@ -2125,10 +2143,13 @@ You can modify a `Bytes` to return a `Bytes` which is equal to `dest` except the
2125
2143
` N ` elements starting at ` index ` are replaced with the contents of ` src ` in O(N)
2126
2144
time. If ` --llvm-mutable-bytes ` is active, this will not create a new ` Bytes `
2127
2145
object and will instead modify the original on concrete backends. The result is
2128
- ` #False ` if ` index ` + ` N ` is not a valid index.
2146
+ ` #False ` if ` index ` + ` N ` is not a valid index. This function accepts both
2147
+ ` Int ` and ` MInt ` values for ` index ` and ` N ` . Currently, only 64-bit and
2148
+ 256-bit ` MInt ` types are supported.
2129
2149
2130
2150
``` k
2131
2151
syntax Bytes ::= replaceAtBytes(dest: Bytes, index: Int, src: Bytes) [function, hook(BYTES.replaceAt)]
2152
+ syntax {Width} Bytes ::= replaceAtBytes(dest: Bytes, index: MInt{Width}, src: Bytes) [function, hook(BYTES.replaceAtMInt)]
2132
2153
```
2133
2154
2134
2155
### Multiple bytes update
@@ -2153,10 +2174,15 @@ left) with the specified `value`. If `--llvm-mutable-bytes` is active, this does
2153
2174
not create a new ` Bytes ` object if the input is already at least ` length ` bytes
2154
2175
long, and will instead return the input unchanged. The result is ` #False ` if
2155
2176
` value ` is not in the range ` [0..255] ` , or if the length is negative.
2177
+ We also provide a variant of this function which takes an ` MInt ` for the
2178
+ ` length ` and ` value ` . The current implementation only supports 64-bit and
2179
+ 256-bit ` MInt ` types.
2156
2180
2157
2181
``` k
2158
2182
syntax Bytes ::= padRightBytes(Bytes, length: Int, value: Int) [function, hook(BYTES.padRight)]
2159
2183
| padLeftBytes(Bytes, length: Int, value: Int) [function, hook(BYTES.padLeft)]
2184
+ syntax {Width} Bytes ::= padRightBytes(Bytes, length: MInt{Width}, value: MInt{Width}) [function, hook(BYTES.padRightMInt)]
2185
+ | padLeftBytes(Bytes, length: MInt{Width}, value: MInt{Width}) [function, hook(BYTES.padLeftMInt)]
2160
2186
```
2161
2187
2162
2188
### Bytes reverse
@@ -2171,10 +2197,12 @@ original.
2171
2197
2172
2198
### Bytes length
2173
2199
2174
- You can get the length of a ` Bytes ` term in O(1) time.
2200
+ You can get the length of a ` Bytes ` term in O(1) time. The lenghth can be either
2201
+ an ` Int ` or an ` MInt ` . Currently, only 64-bit and 256-bit ` MInt ` types are supported.
2175
2202
2176
2203
``` k
2177
2204
syntax Int ::= lengthBytes(Bytes) [function, total, hook(BYTES.length), smtlib(lengthBytes)]
2205
+ syntax {Width} MInt{Width} ::= lengthBytes(Bytes) [function, total, hook(BYTES.lengthMInt)]
2178
2206
```
2179
2207
2180
2208
@@ -2865,6 +2893,7 @@ endmodule
2865
2893
module MINT
2866
2894
imports MINT-SYNTAX
2867
2895
imports private INT
2896
+ imports private BYTES
2868
2897
imports private BOOL
2869
2898
```
2870
2899
@@ -2896,6 +2925,14 @@ has the correct bitwidth, as this will influence the width of the resulting
2896
2925
syntax {Width} MInt{Width} ::= Int2MInt(Int) [function, total, hook(MINT.integer), smt-hook(int2bv)]
2897
2926
```
2898
2927
2928
+ ### Mint and Bytes conversion
2929
+ You can convert from an ` MInt ` to a ` Bytes ` using the ` MInt2Bytes ` function.
2930
+ Currently we only support converting ` MInt ` s of width 256 to ` Bytes ` in a Big Endian format.
2931
+ ``` k
2932
+ syntax {Width} Bytes ::= MInt2Bytes(MInt{Width}) [function, total, hook(MINT.MInt2bytes)]
2933
+ syntax {Width} MInt{Width} ::= Bytes2MInt(Bytes) [function, total, hook(MINT.bytes2MInt)]
2934
+ ```
2935
+
2899
2936
### MInt min and max values
2900
2937
2901
2938
You can get the minimum and maximum values of a signed or unsigned ` MInt `
@@ -2938,6 +2975,8 @@ You can:
2938
2975
2939
2976
* Compute the bitwise complement ` ~MInt ` of an ` MInt ` .
2940
2977
* Compute the unary negation ` --MInt ` of an ` MInt ` .
2978
+ * Compute the power ` ^MInt ` of two ` MInt ` s interpreted as unsigned integers.
2979
+ Currently, only 64 and 256-bits is supported.
2941
2980
* Compute the product ` *MInt ` of two ` MInt ` s.
2942
2981
* Compute the quotient ` /sMInt ` of two ` MInt ` s interpreted as signed integers.
2943
2982
* Compute the modulus ` %sMInt ` of two ` MInt ` s interpreted as signed integers.
@@ -2960,7 +2999,8 @@ You can:
2960
2999
syntax {Width} MInt{Width} ::= "~MInt" MInt{Width} [function, total, hook(MINT.not), smt-hook(bvnot)]
2961
3000
| "--MInt" MInt{Width} [function, total, hook(MINT.neg), smt-hook(bvuminus)]
2962
3001
> left:
2963
- MInt{Width} "*MInt" MInt{Width} [function, total, hook(MINT.mul), smt-hook(bvmul)]
3002
+ MInt{Width} "^MInt" MInt{Width} [function, total, hook(MINT.pow)]
3003
+ | MInt{Width} "*MInt" MInt{Width} [function, total, hook(MINT.mul), smt-hook(bvmul)]
2964
3004
| MInt{Width} "/sMInt" MInt{Width} [function, hook(MINT.sdiv), smt-hook(bvsdiv)]
2965
3005
| MInt{Width} "%sMInt" MInt{Width} [function, hook(MINT.srem), smt-hook(bvsrem)]
2966
3006
| MInt{Width} "/uMInt" MInt{Width} [function, hook(MINT.udiv), smt-hook(bvudiv)]
0 commit comments