nimsets.nim 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # this unit handles Nim sets; it implements symbolic sets
  10. import
  11. ast, astalgo, lineinfos, bitsets, types, options
  12. proc inSet*(s: PNode, elem: PNode): bool =
  13. assert s.kind == nkCurly
  14. if s.kind != nkCurly:
  15. #internalError(s.info, "inSet")
  16. return false
  17. for i in 0 ..< len(s):
  18. if s.sons[i].kind == nkRange:
  19. if leValue(s.sons[i].sons[0], elem) and
  20. leValue(elem, s.sons[i].sons[1]):
  21. return true
  22. else:
  23. if sameValue(s.sons[i], elem):
  24. return true
  25. result = false
  26. proc overlap*(a, b: PNode): bool =
  27. if a.kind == nkRange:
  28. if b.kind == nkRange:
  29. # X..Y and C..D overlap iff (X <= D and C <= Y)
  30. result = leValue(a.sons[0], b.sons[1]) and
  31. leValue(b.sons[0], a.sons[1])
  32. else:
  33. result = leValue(a.sons[0], b) and leValue(b, a.sons[1])
  34. else:
  35. if b.kind == nkRange:
  36. result = leValue(b.sons[0], a) and leValue(a, b.sons[1])
  37. else:
  38. result = sameValue(a, b)
  39. proc someInSet*(s: PNode, a, b: PNode): bool =
  40. # checks if some element of a..b is in the set s
  41. assert s.kind == nkCurly
  42. if s.kind != nkCurly:
  43. #internalError(s.info, "SomeInSet")
  44. return false
  45. for i in 0 ..< len(s):
  46. if s.sons[i].kind == nkRange:
  47. if leValue(s.sons[i].sons[0], b) and leValue(b, s.sons[i].sons[1]) or
  48. leValue(s.sons[i].sons[0], a) and leValue(a, s.sons[i].sons[1]):
  49. return true
  50. else:
  51. # a <= elem <= b
  52. if leValue(a, s.sons[i]) and leValue(s.sons[i], b):
  53. return true
  54. result = false
  55. proc toBitSet*(conf: ConfigRef; s: PNode, b: var TBitSet) =
  56. var first, j: Int128
  57. first = firstOrd(conf, s.typ.sons[0])
  58. bitSetInit(b, int(getSize(conf, s.typ)))
  59. for i in 0 ..< len(s):
  60. if s.sons[i].kind == nkRange:
  61. j = getOrdValue(s.sons[i].sons[0], first)
  62. while j <= getOrdValue(s.sons[i].sons[1], first):
  63. bitSetIncl(b, toInt64(j - first))
  64. inc(j)
  65. else:
  66. bitSetIncl(b, toInt64(getOrdValue(s.sons[i]) - first))
  67. proc toTreeSet*(conf: ConfigRef; s: TBitSet, settype: PType, info: TLineInfo): PNode =
  68. var
  69. a, b, e, first: BiggestInt # a, b are interval borders
  70. elemType: PType
  71. n: PNode
  72. elemType = settype.sons[0]
  73. first = firstOrd(conf, elemType).toInt64
  74. result = newNodeI(nkCurly, info)
  75. result.typ = settype
  76. result.info = info
  77. e = 0
  78. while e < len(s) * ElemSize:
  79. if bitSetIn(s, e):
  80. a = e
  81. b = e
  82. while true:
  83. inc(b)
  84. if (b >= len(s) * ElemSize) or not bitSetIn(s, b): break
  85. dec(b)
  86. let aa = newIntTypeNode(a + first, elemType)
  87. aa.info = info
  88. if a == b:
  89. addSon(result, aa)
  90. else:
  91. n = newNodeI(nkRange, info)
  92. n.typ = elemType
  93. addSon(n, aa)
  94. let bb = newIntTypeNode(b + first, elemType)
  95. bb.info = info
  96. addSon(n, bb)
  97. addSon(result, n)
  98. e = b
  99. inc(e)
  100. template nodeSetOp(a, b: PNode, op: untyped) {.dirty.} =
  101. var x, y: TBitSet
  102. toBitSet(conf, a, x)
  103. toBitSet(conf, b, y)
  104. op(x, y)
  105. result = toTreeSet(conf, x, a.typ, a.info)
  106. proc unionSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetUnion)
  107. proc diffSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff)
  108. proc intersectSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect)
  109. proc symdiffSets*(conf: ConfigRef; a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff)
  110. proc containsSets*(conf: ConfigRef; a, b: PNode): bool =
  111. var x, y: TBitSet
  112. toBitSet(conf, a, x)
  113. toBitSet(conf, b, y)
  114. result = bitSetContains(x, y)
  115. proc equalSets*(conf: ConfigRef; a, b: PNode): bool =
  116. var x, y: TBitSet
  117. toBitSet(conf, a, x)
  118. toBitSet(conf, b, y)
  119. result = bitSetEquals(x, y)
  120. proc complement*(conf: ConfigRef; a: PNode): PNode =
  121. var x: TBitSet
  122. toBitSet(conf, a, x)
  123. for i in 0 .. high(x): x[i] = not x[i]
  124. result = toTreeSet(conf, x, a.typ, a.info)
  125. proc deduplicate*(conf: ConfigRef; a: PNode): PNode =
  126. var x: TBitSet
  127. toBitSet(conf, a, x)
  128. result = toTreeSet(conf, x, a.typ, a.info)
  129. proc cardSet*(conf: ConfigRef; a: PNode): BiggestInt =
  130. var x: TBitSet
  131. toBitSet(conf, a, x)
  132. result = bitSetCard(x)
  133. proc setHasRange*(s: PNode): bool =
  134. assert s.kind == nkCurly
  135. if s.kind != nkCurly:
  136. return false
  137. for i in 0 ..< len(s):
  138. if s.sons[i].kind == nkRange:
  139. return true
  140. result = false
  141. proc emptyRange*(a, b: PNode): bool =
  142. result = not leValue(a, b) # a > b iff not (a <= b)