nimsets.nim 4.3 KB

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