Fix compile time set cardinality (#7558)
This commit is contained in:
parent
992300b300
commit
427490a845
3 changed files with 34 additions and 11 deletions
|
|
@ -28,6 +28,7 @@ proc bitSetExcl*(x: var TBitSet, elem: BiggestInt)
|
||||||
proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
|
proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
|
||||||
proc bitSetEquals*(x, y: TBitSet): bool
|
proc bitSetEquals*(x, y: TBitSet): bool
|
||||||
proc bitSetContains*(x, y: TBitSet): bool
|
proc bitSetContains*(x, y: TBitSet): bool
|
||||||
|
proc bitSetCard*(x: TBitSet): BiggestInt
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
|
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
|
||||||
|
|
@ -69,3 +70,27 @@ proc bitSetContains(x, y: TBitSet): bool =
|
||||||
if (x[i] and not y[i]) != int8(0):
|
if (x[i] and not y[i]) != int8(0):
|
||||||
return false
|
return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
# Number of set bits for all values of int8
|
||||||
|
const populationCount: array[low(int8)..high(int8), int8] = [
|
||||||
|
1.int8, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||||
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||||
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||||
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||||
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||||
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||||
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
||||||
|
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
||||||
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||||
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||||
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||||
|
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||||
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||||
|
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
||||||
|
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7
|
||||||
|
]
|
||||||
|
|
||||||
|
proc bitSetCard(x: TBitSet): BiggestInt =
|
||||||
|
for it in x:
|
||||||
|
result.inc populationCount[it]
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ proc intersectSets*(a, b: PNode): PNode
|
||||||
proc symdiffSets*(a, b: PNode): PNode
|
proc symdiffSets*(a, b: PNode): PNode
|
||||||
proc containsSets*(a, b: PNode): bool
|
proc containsSets*(a, b: PNode): bool
|
||||||
proc equalSets*(a, b: PNode): bool
|
proc equalSets*(a, b: PNode): bool
|
||||||
proc cardSet*(s: PNode): BiggestInt
|
proc cardSet*(a: PNode): BiggestInt
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
proc inSet(s: PNode, elem: PNode): bool =
|
proc inSet(s: PNode, elem: PNode): bool =
|
||||||
|
|
@ -156,16 +156,10 @@ proc deduplicate*(a: PNode): PNode =
|
||||||
toBitSet(a, x)
|
toBitSet(a, x)
|
||||||
result = toTreeSet(x, a.typ, a.info)
|
result = toTreeSet(x, a.typ, a.info)
|
||||||
|
|
||||||
proc cardSet(s: PNode): BiggestInt =
|
proc cardSet(a: PNode): BiggestInt =
|
||||||
# here we can do better than converting it into a compact set
|
var x: TBitSet
|
||||||
# we just count the elements directly
|
toBitSet(a, x)
|
||||||
result = 0
|
result = bitSetCard(x)
|
||||||
for i in countup(0, sonsLen(s) - 1):
|
|
||||||
if s.sons[i].kind == nkRange:
|
|
||||||
result = result + getOrdValue(s.sons[i].sons[1]) -
|
|
||||||
getOrdValue(s.sons[i].sons[0]) + 1
|
|
||||||
else:
|
|
||||||
inc(result)
|
|
||||||
|
|
||||||
proc setHasRange(s: PNode): bool =
|
proc setHasRange(s: PNode): bool =
|
||||||
if s.kind != nkCurly:
|
if s.kind != nkCurly:
|
||||||
|
|
|
||||||
|
|
@ -202,3 +202,7 @@ var
|
||||||
#import compiler.msgs
|
#import compiler.msgs
|
||||||
|
|
||||||
echo warnUninit in gNotes
|
echo warnUninit in gNotes
|
||||||
|
|
||||||
|
# 7555
|
||||||
|
doAssert {-1.int8, -2, -2}.card == 2
|
||||||
|
doAssert {1, 2, 2, 3..5, 4..6}.card == 6
|
||||||
Loading…
Add table
Add a link
Reference in a new issue