@@ -7,6 +7,7 @@ endmodule
7
7
module COMPAT-SYNTAX
8
8
imports COMPAT-SORTS
9
9
imports COMMON-SYNTAX
10
+ imports LIST
10
11
11
12
syntax String ::= firstChar(String) [function]
12
13
syntax String ::= lastChar(String) [function]
@@ -78,6 +79,23 @@ module COMPAT-SYNTAX
78
79
// implements List[Idx <- Val]
79
80
syntax List ::= myListUpdate(List, Int, KItem) [function]
80
81
82
+
83
+ // Range map. It is recommended to use .rangeMap and rangeMapAppendSorted
84
+ // to construct it.
85
+ syntax RangeMap
86
+ // A range item contains all integers between start and end, including both
87
+ // ends.
88
+ syntax RangeMapItem ::= rangeMapItem(start:Int, end:Int)
89
+ syntax MaybeRangeMapItem ::= RangeMapItem | "noRangeMapItem"
90
+
91
+ syntax RangeMap ::= ".RangeMap" [function]
92
+ syntax RangeMap ::= rangeMapAppendSorted(RangeMap, RangeMapItem) [function]
93
+ // Each pair of ranges from the two maps be either identical, or disjoint.
94
+ syntax RangeMap ::= mergeRangeMaps(RangeMap, RangeMap) [function]
95
+
96
+ syntax Bool ::= rangeMapContains(RangeMap, value:Int) [function]
97
+ syntax MaybeRangeMapItem ::= rangeMapFind(RangeMap, value:Int) [function]
98
+
81
99
endmodule
82
100
83
101
module COMPAT-KAST [kast]
@@ -102,6 +120,7 @@ module COMPAT
102
120
imports C-CONFIGURATION
103
121
imports K-REFLECTION
104
122
imports BOOL
123
+ imports LIST
105
124
imports MAP
106
125
imports STRING
107
126
@@ -294,4 +313,123 @@ module COMPAT
294
313
)
295
314
requires N >Int 0
296
315
316
+
317
+ // The list must be sorted, must contain only RangeMapItem, and the ranges
318
+ // must be disjoint.
319
+ syntax RangeMap ::= rangeMap(List)
320
+
321
+ syntax RangeMap ::= #mergeRangeMaps(first:RangeMap, second:RangeMap, merged:RangeMap) [function]
322
+
323
+ // (the address at 'start' is <= 'addr') or (start == 0)
324
+ // (the address at 'end' is >= 'addr') or (end == last-element).
325
+ // If only one of them is equal to 'addr', we change the other one.
326
+ syntax MaybeRangeMapItem ::= #rangeMapFind(RangeMap, value:Int, start:Int, end:Int) [function]
327
+ syntax MaybeRangeMapItem ::= #rangeMapFindChoice(RangeMap, addr:Int, start:Int, middle:Int, middleItem:RangeMapItem, end:Int) [function]
328
+
329
+ syntax MaybeRangeMapItem ::= #checkInRangeMapItem(value:Int, RangeMapItem) [function]
330
+ syntax MaybeRangeMapItem ::= #firstRangeMapItem(MaybeRangeMapItem, MaybeRangeMapItem) [function]
331
+
332
+ syntax Bool ::= isInRangeMapItem(addr:Int, RangeMapItem) [function]
333
+ syntax RangeMapItem ::= asRangeMapItem(KItem) [function]
334
+
335
+ rule rangeMapContains(M:RangeMap, Value:Int)
336
+ => isRangeMapItem(rangeMapFind(M, Value))
337
+
338
+ rule rangeMapFind(rangeMap(.List), _:Int) => noRangeMapItem
339
+ rule rangeMapFind(rangeMap(L:List) #as M:RangeMap, Value:Int)
340
+ => #rangeMapFind(M, Value, 0, size(L) -Int 1)
341
+ [owise]
342
+
343
+ rule #rangeMapFind(rangeMap(L:List), Value:Int, Start:Int, Start)
344
+ => #checkInRangeMapItem(Value, asRangeMapItem(L[Start]))
345
+ rule #rangeMapFind(rangeMap(L:List), Value:Int, Start:Int, End:Int)
346
+ => #firstRangeMapItem(
347
+ #checkInRangeMapItem(Value, asRangeMapItem(L[Start])),
348
+ #checkInRangeMapItem(Value, asRangeMapItem(L[End]))
349
+ )
350
+ requires Start ==Int End -Int 1
351
+ rule #rangeMapFind(rangeMap(L:List) #as M:RangeMap, Value:Int, Start:Int, End:Int)
352
+ => #rangeMapFindChoice(
353
+ M, Value, Start,
354
+ (Start +Int End) /Int 2,
355
+ asRangeMapItem(L[(Start +Int End) /Int 2]),
356
+ End
357
+ )
358
+ requires Start <Int End -Int 1
359
+
360
+ rule #rangeMapFindChoice(M:RangeMap, Value:Int, Start:Int, Middle:Int, rangeMapItem(MiddleStart:Int, _:Int), _End:Int)
361
+ => #rangeMapFind(M, Value, Start, Middle)
362
+ requires Value <Int MiddleStart
363
+ rule #rangeMapFindChoice(M:RangeMap, Value:Int, _Start:Int, Middle:Int, rangeMapItem(MiddleStart:Int, _:Int), End:Int)
364
+ => #rangeMapFind(M, Value, Middle, End)
365
+ requires Value >=Int MiddleStart
366
+
367
+ rule isInRangeMapItem(Value:Int, rangeMapItem(Start:Int, End:Int))
368
+ => Start <=Int Value andBool Value <=Int End
369
+
370
+ rule #checkInRangeMapItem(Value:Int, Item:RangeMapItem) => Item
371
+ requires isInRangeMapItem(Value, Item)
372
+ rule #checkInRangeMapItem(_:Int, _:RangeMapItem) => noRangeMapItem [owise]
373
+
374
+ rule #firstRangeMapItem(noRangeMapItem, Item:MaybeRangeMapItem) => Item
375
+ rule #firstRangeMapItem(Item:RangeMapItem, _) => Item
376
+
377
+ rule asRangeMapItem(Item:RangeMapItem) => Item
378
+
379
+ rule .RangeMap => rangeMap(.List)
380
+ rule rangeMapAppendSorted(
381
+ rangeMap(.List),
382
+ rangeMapItem(Start:Int, End:Int) #as Item:RangeMapItem
383
+ )
384
+ => rangeMap(ListItem(Item))
385
+ rule rangeMapAppendSorted(
386
+ rangeMap(
387
+ (_::List ListItem(rangeMapItem(_:Int, LastEnd:Int))) #as L::List),
388
+ rangeMapItem(Start:Int, End:Int) #as Item:RangeMapItem
389
+ )
390
+ => rangeMap(L ListItem(Item))
391
+ requires LastEnd <Int Start andBool Start <=Int End
392
+
393
+ rule mergeRangeMaps(First:RangeMap, Second:RangeMap)
394
+ => #mergeRangeMaps(First, Second, .RangeMap)
395
+
396
+ rule #mergeRangeMaps(rangeMap(.List), rangeMap(.List), Merged:RangeMap)
397
+ => Merged
398
+ rule #mergeRangeMaps(rangeMap(.List), rangeMap(L::List), rangeMap(Merged::List))
399
+ => rangeMap(Merged L)
400
+ requires size(L) >Int 0
401
+ rule #mergeRangeMaps(rangeMap(L::List), rangeMap(.List), rangeMap(Merged::List))
402
+ => rangeMap(Merged L)
403
+ requires size(L) >Int 0
404
+ rule #mergeRangeMaps(
405
+ rangeMap(ListItem(rangeMapItem(Start:Int, End:Int) #as FirstItem) FirstRemainder:List),
406
+ rangeMap(ListItem(rangeMapItem(Start:Int, End:Int)) SecondRemainder:List),
407
+ Merged:RangeMap
408
+ )
409
+ => #mergeRangeMaps(
410
+ rangeMap(FirstRemainder),
411
+ rangeMap(SecondRemainder),
412
+ rangeMapAppendSorted(Merged, FirstItem)
413
+ )
414
+ rule #mergeRangeMaps(
415
+ rangeMap(ListItem(rangeMapItem(FirstStart:Int, _:Int) #as FirstItem) FirstRemainder:List),
416
+ rangeMap(ListItem(rangeMapItem(SecondStart:Int, _:Int)) _:List) #as Second:RangeMap,
417
+ Merged:RangeMap
418
+ )
419
+ => #mergeRangeMaps(
420
+ rangeMap(FirstRemainder), Second,
421
+ rangeMapAppendSorted(Merged, FirstItem)
422
+ )
423
+ requires FirstStart <Int SecondStart
424
+ rule #mergeRangeMaps(
425
+ rangeMap(ListItem(rangeMapItem(FirstStart:Int, _:Int)) _:List) #as First:RangeMap,
426
+ rangeMap(ListItem(rangeMapItem(SecondStart:Int, _:Int) #as SecondItem) SecondRemainder:List),
427
+ Merged:RangeMap
428
+ )
429
+ => #mergeRangeMaps(
430
+ First, rangeMap(SecondRemainder),
431
+ rangeMapAppendSorted(Merged, SecondItem)
432
+ )
433
+ requires FirstStart >Int SecondStart
434
+
297
435
endmodule
0 commit comments