svf-lib 1.0.2319 → 1.0.2321

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/WorkList.h +0 -0
  2. package/SVF-linux-aarch64/Release-build/lib/cmake/SVF/Modules/FindZ3.cmake +93 -0
  3. package/SVF-linux-aarch64/Release-build/lib/cmake/SVF/SVFConfig.cmake +106 -0
  4. package/SVF-linux-aarch64/Release-build/lib/cmake/SVF/SVFConfigVersion.cmake +43 -0
  5. package/SVF-linux-aarch64/Release-build/lib/cmake/SVF/SVFTargets-release.cmake +101 -0
  6. package/SVF-linux-aarch64/Release-build/lib/cmake/SVF/SVFTargets.cmake +180 -0
  7. package/SVF-linux-aarch64/Release-build/lib/libSvfCore.so.3.1 +0 -0
  8. package/SVF-linux-aarch64/Release-build/lib/libSvfLLVM.so.3.1 +0 -0
  9. package/SVF-linux-aarch64/Release-build/lib/pkgconfig/SVF.pc +12 -0
  10. package/SVF-osx/Release-build/bin/ae +0 -0
  11. package/SVF-osx/Release-build/bin/cfl +0 -0
  12. package/SVF-osx/Release-build/bin/dvf +0 -0
  13. package/SVF-osx/Release-build/bin/llvm2svf +0 -0
  14. package/SVF-osx/Release-build/bin/mta +0 -0
  15. package/SVF-osx/Release-build/bin/saber +0 -0
  16. package/SVF-osx/Release-build/bin/svf-ex +0 -0
  17. package/SVF-osx/Release-build/bin/wpa +0 -0
  18. package/SVF-osx/Release-build/include/SVF/AE/Core/AbstractState.h +425 -0
  19. package/SVF-osx/Release-build/include/SVF/AE/Core/AbstractValue.h +157 -0
  20. package/SVF-osx/Release-build/include/SVF/AE/Core/AddressValue.h +225 -0
  21. package/SVF-osx/Release-build/include/SVF/AE/Core/ICFGWTO.h +135 -0
  22. package/SVF-osx/Release-build/include/SVF/AE/Core/IntervalValue.h +1055 -0
  23. package/SVF-osx/Release-build/include/SVF/AE/Core/NumericValue.h +1292 -0
  24. package/SVF-osx/Release-build/include/SVF/AE/Core/RelExeState.h +226 -0
  25. package/SVF-osx/Release-build/include/SVF/AE/Core/RelationSolver.h +91 -0
  26. package/SVF-osx/Release-build/include/SVF/AE/Svfexe/AEDetector.h +439 -0
  27. package/SVF-osx/Release-build/include/SVF/AE/Svfexe/AbsExtAPI.h +138 -0
  28. package/SVF-osx/Release-build/include/SVF/AE/Svfexe/AbstractInterpretation.h +384 -0
  29. package/SVF-osx/Release-build/include/SVF/CFL/CFGNormalizer.h +84 -0
  30. package/SVF-osx/Release-build/include/SVF/CFL/CFGrammar.h +468 -0
  31. package/SVF-osx/Release-build/include/SVF/CFL/CFLAlias.h +168 -0
  32. package/SVF-osx/Release-build/include/SVF/CFL/CFLBase.h +118 -0
  33. package/SVF-osx/Release-build/include/SVF/CFL/CFLGramGraphChecker.h +74 -0
  34. package/SVF-osx/Release-build/include/SVF/CFL/CFLGraphBuilder.h +168 -0
  35. package/SVF-osx/Release-build/include/SVF/CFL/CFLSVFGBuilder.h +58 -0
  36. package/SVF-osx/Release-build/include/SVF/CFL/CFLSolver.h +374 -0
  37. package/SVF-osx/Release-build/include/SVF/CFL/CFLStat.h +67 -0
  38. package/SVF-osx/Release-build/include/SVF/CFL/CFLVF.h +68 -0
  39. package/SVF-osx/Release-build/include/SVF/CFL/GrammarBuilder.h +100 -0
  40. package/SVF-osx/Release-build/include/SVF/DDA/ContextDDA.h +230 -0
  41. package/SVF-osx/Release-build/include/SVF/DDA/DDAClient.h +163 -0
  42. package/SVF-osx/Release-build/include/SVF/DDA/DDAPass.h +102 -0
  43. package/SVF-osx/Release-build/include/SVF/DDA/DDAStat.h +121 -0
  44. package/SVF-osx/Release-build/include/SVF/DDA/DDAVFSolver.h +794 -0
  45. package/SVF-osx/Release-build/include/SVF/DDA/FlowDDA.h +178 -0
  46. package/SVF-osx/Release-build/include/SVF/FastCluster/fastcluster.h +80 -0
  47. package/SVF-osx/Release-build/include/SVF/Graphs/BasicBlockG.h +318 -0
  48. package/SVF-osx/Release-build/include/SVF/Graphs/CDG.h +482 -0
  49. package/SVF-osx/Release-build/include/SVF/Graphs/CFLGraph.h +232 -0
  50. package/SVF-osx/Release-build/include/SVF/Graphs/CHG.h +368 -0
  51. package/SVF-osx/Release-build/include/SVF/Graphs/CallGraph.h +497 -0
  52. package/SVF-osx/Release-build/include/SVF/Graphs/ConsG.h +402 -0
  53. package/SVF-osx/Release-build/include/SVF/Graphs/ConsGEdge.h +355 -0
  54. package/SVF-osx/Release-build/include/SVF/Graphs/ConsGNode.h +418 -0
  55. package/SVF-osx/Release-build/include/SVF/Graphs/DOTGraphTraits.h +188 -0
  56. package/SVF-osx/Release-build/include/SVF/Graphs/GenericGraph.h +628 -0
  57. package/SVF-osx/Release-build/include/SVF/Graphs/GraphPrinter.h +111 -0
  58. package/SVF-osx/Release-build/include/SVF/Graphs/GraphTraits.h +150 -0
  59. package/SVF-osx/Release-build/include/SVF/Graphs/GraphWriter.h +380 -0
  60. package/SVF-osx/Release-build/include/SVF/Graphs/ICFG.h +331 -0
  61. package/SVF-osx/Release-build/include/SVF/Graphs/ICFGEdge.h +281 -0
  62. package/SVF-osx/Release-build/include/SVF/Graphs/ICFGNode.h +669 -0
  63. package/SVF-osx/Release-build/include/SVF/Graphs/ICFGStat.h +164 -0
  64. package/SVF-osx/Release-build/include/SVF/Graphs/IRGraph.h +398 -0
  65. package/SVF-osx/Release-build/include/SVF/Graphs/SCC.h +375 -0
  66. package/SVF-osx/Release-build/include/SVF/Graphs/SVFG.h +491 -0
  67. package/SVF-osx/Release-build/include/SVF/Graphs/SVFGEdge.h +237 -0
  68. package/SVF-osx/Release-build/include/SVF/Graphs/SVFGNode.h +501 -0
  69. package/SVF-osx/Release-build/include/SVF/Graphs/SVFGOPT.h +372 -0
  70. package/SVF-osx/Release-build/include/SVF/Graphs/SVFGStat.h +273 -0
  71. package/SVF-osx/Release-build/include/SVF/Graphs/ThreadCallGraph.h +399 -0
  72. package/SVF-osx/Release-build/include/SVF/Graphs/VFG.h +726 -0
  73. package/SVF-osx/Release-build/include/SVF/Graphs/VFGEdge.h +295 -0
  74. package/SVF-osx/Release-build/include/SVF/Graphs/VFGNode.h +1266 -0
  75. package/SVF-osx/Release-build/include/SVF/Graphs/WTO.h +872 -0
  76. package/SVF-osx/Release-build/include/SVF/MSSA/MSSAMuChi.h +722 -0
  77. package/SVF-osx/Release-build/include/SVF/MSSA/MemPartition.h +169 -0
  78. package/SVF-osx/Release-build/include/SVF/MSSA/MemRegion.h +489 -0
  79. package/SVF-osx/Release-build/include/SVF/MSSA/MemSSA.h +452 -0
  80. package/SVF-osx/Release-build/include/SVF/MSSA/SVFGBuilder.h +104 -0
  81. package/SVF-osx/Release-build/include/SVF/MTA/LockAnalysis.h +533 -0
  82. package/SVF-osx/Release-build/include/SVF/MTA/MHP.h +546 -0
  83. package/SVF-osx/Release-build/include/SVF/MTA/MTA.h +97 -0
  84. package/SVF-osx/Release-build/include/SVF/MTA/MTAStat.h +73 -0
  85. package/SVF-osx/Release-build/include/SVF/MTA/TCT.h +620 -0
  86. package/SVF-osx/Release-build/include/SVF/MemoryModel/AbstractPointsToDS.h +316 -0
  87. package/SVF-osx/Release-build/include/SVF/MemoryModel/AccessPath.h +194 -0
  88. package/SVF-osx/Release-build/include/SVF/MemoryModel/ConditionalPT.h +878 -0
  89. package/SVF-osx/Release-build/include/SVF/MemoryModel/MutablePointsToDS.h +1025 -0
  90. package/SVF-osx/Release-build/include/SVF/MemoryModel/PersistentPointsToCache.h +463 -0
  91. package/SVF-osx/Release-build/include/SVF/MemoryModel/PersistentPointsToDS.h +955 -0
  92. package/SVF-osx/Release-build/include/SVF/MemoryModel/PointerAnalysis.h +428 -0
  93. package/SVF-osx/Release-build/include/SVF/MemoryModel/PointerAnalysisImpl.h +602 -0
  94. package/SVF-osx/Release-build/include/SVF/MemoryModel/PointsTo.h +255 -0
  95. package/SVF-osx/Release-build/include/SVF/MemoryModel/SVFLoop.h +167 -0
  96. package/SVF-osx/Release-build/include/SVF/SABER/DoubleFreeChecker.h +76 -0
  97. package/SVF-osx/Release-build/include/SVF/SABER/FileChecker.h +80 -0
  98. package/SVF-osx/Release-build/include/SVF/SABER/LeakChecker.h +122 -0
  99. package/SVF-osx/Release-build/include/SVF/SABER/ProgSlice.h +327 -0
  100. package/SVF-osx/Release-build/include/SVF/SABER/SaberCheckerAPI.h +151 -0
  101. package/SVF-osx/Release-build/include/SVF/SABER/SaberCondAllocator.h +317 -0
  102. package/SVF-osx/Release-build/include/SVF/SABER/SaberSVFGBuilder.h +114 -0
  103. package/SVF-osx/Release-build/include/SVF/SABER/SrcSnkDDA.h +327 -0
  104. package/SVF-osx/Release-build/include/SVF/SABER/SrcSnkSolver.h +186 -0
  105. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/BasicTypes.h +280 -0
  106. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/BreakConstantExpr.h +93 -0
  107. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/CHGBuilder.h +78 -0
  108. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/CppUtil.h +184 -0
  109. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/DCHG.h +474 -0
  110. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/GEPTypeBridgeIterator.h +183 -0
  111. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/ICFGBuilder.h +160 -0
  112. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/LLVMLoopAnalysis.h +60 -0
  113. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/LLVMModule.h +527 -0
  114. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/LLVMUtil.h +433 -0
  115. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/ObjTypeInference.h +129 -0
  116. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/SVFIRBuilder.h +523 -0
  117. package/SVF-osx/Release-build/include/SVF/SVF-LLVM/SymbolTableBuilder.h +132 -0
  118. package/SVF-osx/Release-build/include/SVF/SVFIR/ObjTypeInfo.h +224 -0
  119. package/SVF-osx/Release-build/include/SVF/SVFIR/PAGBuilderFromFile.h +80 -0
  120. package/SVF-osx/Release-build/include/SVF/SVFIR/SVFIR.h +856 -0
  121. package/SVF-osx/Release-build/include/SVF/SVFIR/SVFStatements.h +1330 -0
  122. package/SVF-osx/Release-build/include/SVF/SVFIR/SVFType.h +606 -0
  123. package/SVF-osx/Release-build/include/SVF/SVFIR/SVFValue.h +338 -0
  124. package/SVF-osx/Release-build/include/SVF/SVFIR/SVFVariables.h +2212 -0
  125. package/SVF-osx/Release-build/include/SVF/Util/Annotator.h +180 -0
  126. package/SVF-osx/Release-build/include/SVF/Util/BitVector.h +55 -0
  127. package/SVF-osx/Release-build/include/SVF/Util/CDGBuilder.h +107 -0
  128. package/SVF-osx/Release-build/include/SVF/Util/CallGraphBuilder.h +61 -0
  129. package/SVF-osx/Release-build/include/SVF/Util/Casting.h +426 -0
  130. package/SVF-osx/Release-build/include/SVF/Util/CommandLine.h +530 -0
  131. package/SVF-osx/Release-build/include/SVF/Util/CoreBitVector.h +214 -0
  132. package/SVF-osx/Release-build/include/SVF/Util/CxtStmt.h +502 -0
  133. package/SVF-osx/Release-build/include/SVF/Util/DPItem.h +618 -0
  134. package/SVF-osx/Release-build/include/SVF/Util/ExtAPI.h +117 -0
  135. package/SVF-osx/Release-build/include/SVF/Util/GeneralType.h +127 -0
  136. package/SVF-osx/Release-build/include/SVF/Util/GraphReachSolver.h +186 -0
  137. package/SVF-osx/Release-build/include/SVF/Util/NodeIDAllocator.h +203 -0
  138. package/SVF-osx/Release-build/include/SVF/Util/Options.h +273 -0
  139. package/SVF-osx/Release-build/include/SVF/Util/PTAStat.h +83 -0
  140. package/SVF-osx/Release-build/include/SVF/Util/SVFBugReport.h +427 -0
  141. package/SVF-osx/Release-build/include/SVF/Util/SVFLoopAndDomInfo.h +169 -0
  142. package/SVF-osx/Release-build/include/SVF/Util/SVFStat.h +103 -0
  143. package/SVF-osx/Release-build/include/SVF/Util/SVFUtil.h +478 -0
  144. package/SVF-osx/Release-build/include/SVF/Util/SparseBitVector.h +1252 -0
  145. package/SVF-osx/Release-build/include/SVF/Util/ThreadAPI.h +188 -0
  146. package/SVF-osx/Release-build/include/SVF/Util/WorkList.h +317 -0
  147. package/SVF-osx/Release-build/include/SVF/Util/Z3Expr.h +325 -0
  148. package/SVF-osx/Release-build/include/SVF/Util/cJSON.h +300 -0
  149. package/SVF-osx/Release-build/include/SVF/Util/config.h +46 -0
  150. package/SVF-osx/Release-build/include/SVF/Util/iterator.h +407 -0
  151. package/SVF-osx/Release-build/include/SVF/Util/iterator_range.h +76 -0
  152. package/SVF-osx/Release-build/include/SVF/WPA/Andersen.h +434 -0
  153. package/SVF-osx/Release-build/include/SVF/WPA/AndersenPWC.h +160 -0
  154. package/SVF-osx/Release-build/include/SVF/WPA/CSC.h +95 -0
  155. package/SVF-osx/Release-build/include/SVF/WPA/FlowSensitive.h +322 -0
  156. package/SVF-osx/Release-build/include/SVF/WPA/Steensgaard.h +131 -0
  157. package/SVF-osx/Release-build/include/SVF/WPA/TypeAnalysis.h +90 -0
  158. package/SVF-osx/Release-build/include/SVF/WPA/VersionedFlowSensitive.h +295 -0
  159. package/SVF-osx/Release-build/include/SVF/WPA/WPAFSSolver.h +246 -0
  160. package/SVF-osx/Release-build/include/SVF/WPA/WPAPass.h +115 -0
  161. package/SVF-osx/Release-build/include/SVF/WPA/WPASolver.h +205 -0
  162. package/SVF-osx/Release-build/include/SVF/WPA/WPAStat.h +222 -0
  163. package/SVF-osx/Release-build/include/SVF/extapi.bc +2384 -0
  164. package/SVF-osx/Release-build/lib/cmake/SVF/Modules/FindZ3.cmake +93 -0
  165. package/SVF-osx/Release-build/lib/cmake/SVF/SVFConfig.cmake +106 -0
  166. package/SVF-osx/Release-build/lib/cmake/SVF/SVFConfigVersion.cmake +43 -0
  167. package/SVF-osx/Release-build/lib/cmake/SVF/SVFTargets-release.cmake +101 -0
  168. package/SVF-osx/Release-build/lib/cmake/SVF/SVFTargets.cmake +180 -0
  169. package/SVF-osx/Release-build/lib/libSvfCore.3.1.dylib +0 -0
  170. package/SVF-osx/Release-build/lib/libSvfLLVM.3.1.dylib +0 -0
  171. package/SVF-osx/Release-build/lib/pkgconfig/SVF.pc +12 -0
  172. package/package.json +1 -1
  173. package/SVF-linux-aarch64/Release-build/include/CFL/grammar/PAGGrammar.txt +0 -15
  174. package/SVF-linux-aarch64/Release-build/include/CFL/grammar/PEGGrammar.txt +0 -11
  175. package/SVF-linux-aarch64/Release-build/include/CFL/grammar/VFGGrammar.txt +0 -7
  176. package/SVF-linux-aarch64/Release-build/include/FastCluster/LICENSE.TXT +0 -13
  177. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/AbstractState.h +0 -0
  178. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/AbstractValue.h +0 -0
  179. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/AddressValue.h +0 -0
  180. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/ICFGWTO.h +0 -0
  181. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/IntervalValue.h +0 -0
  182. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/NumericValue.h +0 -0
  183. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/RelExeState.h +0 -0
  184. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Core/RelationSolver.h +0 -0
  185. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Svfexe/AEDetector.h +0 -0
  186. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Svfexe/AbsExtAPI.h +0 -0
  187. /package/SVF-linux-aarch64/Release-build/include/{AE → SVF/AE}/Svfexe/AbstractInterpretation.h +0 -0
  188. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFGNormalizer.h +0 -0
  189. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFGrammar.h +0 -0
  190. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLAlias.h +0 -0
  191. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLBase.h +0 -0
  192. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLGramGraphChecker.h +0 -0
  193. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLGraphBuilder.h +0 -0
  194. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLSVFGBuilder.h +0 -0
  195. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLSolver.h +0 -0
  196. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLStat.h +0 -0
  197. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/CFLVF.h +0 -0
  198. /package/SVF-linux-aarch64/Release-build/include/{CFL → SVF/CFL}/GrammarBuilder.h +0 -0
  199. /package/SVF-linux-aarch64/Release-build/include/{DDA → SVF/DDA}/ContextDDA.h +0 -0
  200. /package/SVF-linux-aarch64/Release-build/include/{DDA → SVF/DDA}/DDAClient.h +0 -0
  201. /package/SVF-linux-aarch64/Release-build/include/{DDA → SVF/DDA}/DDAPass.h +0 -0
  202. /package/SVF-linux-aarch64/Release-build/include/{DDA → SVF/DDA}/DDAStat.h +0 -0
  203. /package/SVF-linux-aarch64/Release-build/include/{DDA → SVF/DDA}/DDAVFSolver.h +0 -0
  204. /package/SVF-linux-aarch64/Release-build/include/{DDA → SVF/DDA}/FlowDDA.h +0 -0
  205. /package/SVF-linux-aarch64/Release-build/include/{FastCluster → SVF/FastCluster}/fastcluster.h +0 -0
  206. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/BasicBlockG.h +0 -0
  207. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/CDG.h +0 -0
  208. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/CFLGraph.h +0 -0
  209. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/CHG.h +0 -0
  210. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/CallGraph.h +0 -0
  211. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ConsG.h +0 -0
  212. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ConsGEdge.h +0 -0
  213. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ConsGNode.h +0 -0
  214. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/DOTGraphTraits.h +0 -0
  215. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/GenericGraph.h +0 -0
  216. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/GraphPrinter.h +0 -0
  217. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/GraphTraits.h +0 -0
  218. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/GraphWriter.h +0 -0
  219. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ICFG.h +0 -0
  220. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ICFGEdge.h +0 -0
  221. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ICFGNode.h +0 -0
  222. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ICFGStat.h +0 -0
  223. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/IRGraph.h +0 -0
  224. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/SCC.h +0 -0
  225. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/SVFG.h +0 -0
  226. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/SVFGEdge.h +0 -0
  227. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/SVFGNode.h +0 -0
  228. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/SVFGOPT.h +0 -0
  229. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/SVFGStat.h +0 -0
  230. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/ThreadCallGraph.h +0 -0
  231. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/VFG.h +0 -0
  232. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/VFGEdge.h +0 -0
  233. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/VFGNode.h +0 -0
  234. /package/SVF-linux-aarch64/Release-build/include/{Graphs → SVF/Graphs}/WTO.h +0 -0
  235. /package/SVF-linux-aarch64/Release-build/include/{MSSA → SVF/MSSA}/MSSAMuChi.h +0 -0
  236. /package/SVF-linux-aarch64/Release-build/include/{MSSA → SVF/MSSA}/MemPartition.h +0 -0
  237. /package/SVF-linux-aarch64/Release-build/include/{MSSA → SVF/MSSA}/MemRegion.h +0 -0
  238. /package/SVF-linux-aarch64/Release-build/include/{MSSA → SVF/MSSA}/MemSSA.h +0 -0
  239. /package/SVF-linux-aarch64/Release-build/include/{MSSA → SVF/MSSA}/SVFGBuilder.h +0 -0
  240. /package/SVF-linux-aarch64/Release-build/include/{MTA → SVF/MTA}/LockAnalysis.h +0 -0
  241. /package/SVF-linux-aarch64/Release-build/include/{MTA → SVF/MTA}/MHP.h +0 -0
  242. /package/SVF-linux-aarch64/Release-build/include/{MTA → SVF/MTA}/MTA.h +0 -0
  243. /package/SVF-linux-aarch64/Release-build/include/{MTA → SVF/MTA}/MTAStat.h +0 -0
  244. /package/SVF-linux-aarch64/Release-build/include/{MTA → SVF/MTA}/TCT.h +0 -0
  245. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/AbstractPointsToDS.h +0 -0
  246. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/AccessPath.h +0 -0
  247. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/ConditionalPT.h +0 -0
  248. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/MutablePointsToDS.h +0 -0
  249. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/PersistentPointsToCache.h +0 -0
  250. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/PersistentPointsToDS.h +0 -0
  251. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/PointerAnalysis.h +0 -0
  252. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/PointerAnalysisImpl.h +0 -0
  253. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/PointsTo.h +0 -0
  254. /package/SVF-linux-aarch64/Release-build/include/{MemoryModel → SVF/MemoryModel}/SVFLoop.h +0 -0
  255. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/DoubleFreeChecker.h +0 -0
  256. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/FileChecker.h +0 -0
  257. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/LeakChecker.h +0 -0
  258. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/ProgSlice.h +0 -0
  259. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/SaberCheckerAPI.h +0 -0
  260. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/SaberCondAllocator.h +0 -0
  261. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/SaberSVFGBuilder.h +0 -0
  262. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/SrcSnkDDA.h +0 -0
  263. /package/SVF-linux-aarch64/Release-build/include/{SABER → SVF/SABER}/SrcSnkSolver.h +0 -0
  264. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/BasicTypes.h +0 -0
  265. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/BreakConstantExpr.h +0 -0
  266. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/CHGBuilder.h +0 -0
  267. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/CppUtil.h +0 -0
  268. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/DCHG.h +0 -0
  269. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/GEPTypeBridgeIterator.h +0 -0
  270. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/ICFGBuilder.h +0 -0
  271. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/LLVMLoopAnalysis.h +0 -0
  272. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/LLVMModule.h +0 -0
  273. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/LLVMUtil.h +0 -0
  274. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/ObjTypeInference.h +0 -0
  275. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/SVFIRBuilder.h +0 -0
  276. /package/SVF-linux-aarch64/Release-build/include/{SVF-LLVM → SVF/SVF-LLVM}/SymbolTableBuilder.h +0 -0
  277. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/ObjTypeInfo.h +0 -0
  278. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/PAGBuilderFromFile.h +0 -0
  279. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/SVFIR.h +0 -0
  280. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/SVFStatements.h +0 -0
  281. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/SVFType.h +0 -0
  282. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/SVFValue.h +0 -0
  283. /package/SVF-linux-aarch64/Release-build/include/{SVFIR → SVF/SVFIR}/SVFVariables.h +0 -0
  284. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/Annotator.h +0 -0
  285. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/BitVector.h +0 -0
  286. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/CDGBuilder.h +0 -0
  287. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/CallGraphBuilder.h +0 -0
  288. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/Casting.h +0 -0
  289. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/CommandLine.h +0 -0
  290. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/CoreBitVector.h +0 -0
  291. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/CxtStmt.h +0 -0
  292. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/DPItem.h +0 -0
  293. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/ExtAPI.h +0 -0
  294. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/GeneralType.h +0 -0
  295. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/GraphReachSolver.h +0 -0
  296. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/NodeIDAllocator.h +0 -0
  297. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/Options.h +0 -0
  298. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/PTAStat.h +0 -0
  299. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/SVFBugReport.h +0 -0
  300. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/SVFLoopAndDomInfo.h +0 -0
  301. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/SVFStat.h +0 -0
  302. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/SVFUtil.h +0 -0
  303. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/SparseBitVector.h +0 -0
  304. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/ThreadAPI.h +0 -0
  305. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/Z3Expr.h +0 -0
  306. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/cJSON.h +0 -0
  307. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/iterator.h +0 -0
  308. /package/SVF-linux-aarch64/Release-build/include/{Util → SVF/Util}/iterator_range.h +0 -0
  309. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/Andersen.h +0 -0
  310. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/AndersenPWC.h +0 -0
  311. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/CSC.h +0 -0
  312. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/FlowSensitive.h +0 -0
  313. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/Steensgaard.h +0 -0
  314. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/TypeAnalysis.h +0 -0
  315. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/VersionedFlowSensitive.h +0 -0
  316. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/WPAFSSolver.h +0 -0
  317. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/WPAPass.h +0 -0
  318. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/WPASolver.h +0 -0
  319. /package/SVF-linux-aarch64/Release-build/include/{WPA → SVF/WPA}/WPAStat.h +0 -0
  320. /package/SVF-linux-aarch64/Release-build/{lib → include/SVF}/extapi.bc +0 -0
@@ -0,0 +1,1292 @@
1
+ //===- NumericValue.h ----Numeric Value-------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-2022> <Yulei Sui>
6
+ //
7
+
8
+ // This program is free software: you can redistribute it and/or modify
9
+ // it under the terms of the GNU Affero General Public License as published by
10
+ // the Free Software Foundation, either version 3 of the License, or
11
+ // (at your option) any later version.
12
+
13
+ // This program is distributed in the hope that it will be useful,
14
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ // GNU Affero General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU Affero General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+ /*
23
+ * Numeri Value.h
24
+ *
25
+ * Created on: May 11, 2024
26
+ * Author: Xiao Cheng, Jiawei Ren
27
+ *
28
+ */
29
+ // The implementation is based on
30
+ // Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction.
31
+ // 46th International Conference on Software Engineering. (ICSE24)
32
+
33
+ #ifndef SVF_NUMERICVALUE_H
34
+ #define SVF_NUMERICVALUE_H
35
+
36
+ #include "SVFIR/SVFType.h"
37
+ #include <cfloat> // For DBL_MAX
38
+ #include <cmath>
39
+ #include <utility>
40
+
41
+ #define epsilon std::numeric_limits<double>::epsilon();
42
+ namespace SVF
43
+ {
44
+
45
+ /**
46
+ * @brief A class representing a bounded 64-bit integer.
47
+ *
48
+ * BoundedInt is a class that represents a 64-bit integer that can also
49
+ * represent positive and negative infinity. It includes a 64-bit integer
50
+ * value and a boolean flag indicating whether the value is infinite.
51
+ * If the value is infinite, the integer value is used to represent the sign
52
+ * of infinity (1 for positive infinity and 0 for negative infinity).
53
+ */
54
+ class BoundedInt
55
+ {
56
+ protected:
57
+ s64_t _iVal; // The 64-bit integer value.
58
+ bool _isInf; // True if the value is infinite. If true, _iVal == 1
59
+ // represents positive infinity and _iVal == 0 represents
60
+ // negative infinity.
61
+
62
+ // Default constructor is protected to prevent creating an object without
63
+ // initializing _iVal and _isInf.
64
+ BoundedInt() = default;
65
+
66
+ public:
67
+ // Constructs a BoundedInt with the given 64-bit integer value. The value is
68
+ // not infinite.
69
+ BoundedInt(s64_t fVal) : _iVal(fVal), _isInf(false) {}
70
+
71
+ // Constructs a BoundedInt with the given 64-bit integer value and infinity
72
+ // flag.
73
+ BoundedInt(s64_t fVal, bool isInf) : _iVal(fVal), _isInf(isInf) {}
74
+
75
+ // Copy constructor.
76
+ BoundedInt(const BoundedInt& rhs) : _iVal(rhs._iVal), _isInf(rhs._isInf) {}
77
+
78
+ // Copy assignment operator.
79
+ BoundedInt& operator=(const BoundedInt& rhs)
80
+ {
81
+ _iVal = rhs._iVal;
82
+ _isInf = rhs._isInf;
83
+ return *this;
84
+ }
85
+
86
+ // Move constructor.
87
+ BoundedInt(BoundedInt&& rhs) : _iVal(rhs._iVal), _isInf(rhs._isInf) {}
88
+
89
+ // Move assignment operator.
90
+ BoundedInt& operator=(BoundedInt&& rhs)
91
+ {
92
+ _iVal = rhs._iVal;
93
+ _isInf = rhs._isInf;
94
+ return *this;
95
+ }
96
+
97
+ // Virtual destructor.
98
+ virtual ~BoundedInt() {}
99
+
100
+ // Checks if the BoundedInt represents positive infinity.
101
+ bool is_plus_infinity() const
102
+ {
103
+ return _isInf && _iVal == 1;
104
+ }
105
+
106
+ // Checks if the BoundedInt represents negative infinity.
107
+ bool is_minus_infinity() const
108
+ {
109
+ return _isInf && _iVal == -1;
110
+ }
111
+
112
+ // Checks if the BoundedInt represents either positive or negative infinity.
113
+ bool is_infinity() const
114
+ {
115
+ return is_plus_infinity() || is_minus_infinity();
116
+ }
117
+
118
+ // Sets the BoundedInt to represent positive infinity.
119
+ void set_plus_infinity()
120
+ {
121
+ *this = plus_infinity();
122
+ }
123
+
124
+ // Sets the BoundedInt to represent negative infinity.
125
+ void set_minus_infinity()
126
+ {
127
+ *this = minus_infinity();
128
+ }
129
+
130
+ // Returns a BoundedInt representing positive infinity.
131
+ static BoundedInt plus_infinity()
132
+ {
133
+ return {1, true};
134
+ }
135
+
136
+ // Returns a BoundedInt representing negative infinity.
137
+ static BoundedInt minus_infinity()
138
+ {
139
+ return {-1, true};
140
+ }
141
+
142
+ // Checks if the BoundedInt represents zero.
143
+ bool is_zero() const
144
+ {
145
+ return _iVal == 0;
146
+ }
147
+
148
+ // Checks if the given BoundedInt represents zero.
149
+ static bool isZero(const BoundedInt& expr)
150
+ {
151
+ return expr._iVal == 0;
152
+ }
153
+
154
+ // Checks if the BoundedInt is equal to another BoundedInt.
155
+ bool equal(const BoundedInt& rhs) const
156
+ {
157
+ return _iVal == rhs._iVal && _isInf == rhs._isInf;
158
+ }
159
+
160
+ // Checks if the BoundedInt is less than or equal to another BoundedInt.
161
+ bool leq(const BoundedInt& rhs) const
162
+ {
163
+ // If only one of the two BoundedInts is infinite.
164
+ if (is_infinity() ^ rhs.is_infinity())
165
+ {
166
+ if (is_infinity())
167
+ {
168
+ return is_minus_infinity();
169
+ }
170
+ else
171
+ {
172
+ return rhs.is_plus_infinity();
173
+ }
174
+ }
175
+ // If both BoundedInts are infinite.
176
+ if (is_infinity() && rhs.is_infinity())
177
+ {
178
+ if (is_minus_infinity())
179
+ return true;
180
+ else
181
+ return rhs.is_plus_infinity();
182
+ }
183
+ // If neither BoundedInt is infinite.
184
+ else
185
+ return _iVal <= rhs._iVal;
186
+ }
187
+
188
+ // Checks if the BoundedInt is greater than or equal to another BoundedInt.
189
+ bool geq(const BoundedInt& rhs) const
190
+ {
191
+ // If only one of the two BoundedInts is infinite.
192
+ if (is_infinity() ^ rhs.is_infinity())
193
+ {
194
+ if (is_infinity())
195
+ {
196
+ return is_plus_infinity();
197
+ }
198
+ else
199
+ {
200
+ return rhs.is_minus_infinity();
201
+ }
202
+ }
203
+ // If both BoundedInts are infinite.
204
+ if (is_infinity() && rhs.is_infinity())
205
+ {
206
+ if (is_plus_infinity())
207
+ return true;
208
+ else
209
+ return rhs.is_minus_infinity();
210
+ }
211
+ // If neither BoundedInt is infinite.
212
+ else
213
+ return _iVal >= rhs._iVal;
214
+ }
215
+
216
+ /// Reload operator
217
+ //{%
218
+ // Overloads the equality operator to compare two BoundedInt objects.
219
+ friend BoundedInt operator==(const BoundedInt& lhs, const BoundedInt& rhs)
220
+ {
221
+ return lhs.equal(rhs);
222
+ }
223
+
224
+ // Overloads the inequality operator to compare two BoundedInt objects.
225
+ friend BoundedInt operator!=(const BoundedInt& lhs, const BoundedInt& rhs)
226
+ {
227
+ return !lhs.equal(rhs);
228
+ }
229
+
230
+ // Overloads the greater than operator to compare two BoundedInt objects.
231
+ friend BoundedInt operator>(const BoundedInt& lhs, const BoundedInt& rhs)
232
+ {
233
+ return !lhs.leq(rhs);
234
+ }
235
+
236
+ // Overloads the less than operator to compare two BoundedInt objects.
237
+ friend BoundedInt operator<(const BoundedInt& lhs, const BoundedInt& rhs)
238
+ {
239
+ return !lhs.geq(rhs);
240
+ }
241
+
242
+ // Overloads the less than or equal to operator to compare two BoundedInt
243
+ // objects.
244
+ friend BoundedInt operator<=(const BoundedInt& lhs, const BoundedInt& rhs)
245
+ {
246
+ return lhs.leq(rhs);
247
+ }
248
+
249
+ // Overloads the greater than or equal to operator to compare two BoundedInt
250
+ // objects.
251
+ friend BoundedInt operator>=(const BoundedInt& lhs, const BoundedInt& rhs)
252
+ {
253
+ return lhs.geq(rhs);
254
+ }
255
+
256
+ /**
257
+ * Safely adds two BoundedInt objects.
258
+ *
259
+ * This function adds two BoundedInt objects in a way that respects the
260
+ * bounds of the underlying s64_t type. It checks for conditions that would
261
+ * result in overflow or underflow and returns a representation of positive
262
+ * or negative infinity in those cases. If addition of the two numbers would
263
+ * result in a value that is within the representable range of s64_t, it
264
+ * performs the addition and returns the result. If the addition is not
265
+ * defined (e.g., positive infinity plus negative infinity), it asserts
266
+ * false to indicate an error.
267
+ *
268
+ * @param lhs The first BoundedInt to add. This can be any valid BoundedInt,
269
+ * including positive and negative infinity.
270
+ * @param rhs The second BoundedInt to add. This can be any valid
271
+ * BoundedInt, including positive and negative infinity.
272
+ * @return A BoundedInt that represents the result of the addition. If the
273
+ * addition would result in overflow, the function returns a BoundedInt
274
+ * representing positive infinity. If the addition would result in
275
+ * underflow, the function returns a BoundedInt representing negative
276
+ * infinity. If the addition is not defined (e.g., positive infinity plus
277
+ * negative infinity), the function asserts false and does not return a
278
+ * value.
279
+ */
280
+ static BoundedInt safeAdd(const BoundedInt& lhs, const BoundedInt& rhs)
281
+ {
282
+ // If one number is positive infinity and the other is negative
283
+ // infinity, this is an invalid operation, so we assert false.
284
+ if ((lhs.is_plus_infinity() && rhs.is_minus_infinity()) ||
285
+ (lhs.is_minus_infinity() && rhs.is_plus_infinity()))
286
+ {
287
+ assert(false && "invalid add");
288
+ }
289
+
290
+ // If either number is positive infinity, the result is positive
291
+ // infinity.
292
+ if (lhs.is_plus_infinity() || rhs.is_plus_infinity())
293
+ {
294
+ return plus_infinity();
295
+ }
296
+
297
+ // If either number is negative infinity, the result is negative
298
+ // infinity.
299
+ if (lhs.is_minus_infinity() || rhs.is_minus_infinity())
300
+ {
301
+ return minus_infinity();
302
+ }
303
+
304
+ // If both numbers are positive and their sum would exceed the maximum
305
+ // representable number, the result is positive infinity.
306
+ if (lhs._iVal > 0 && rhs._iVal > 0 &&
307
+ (std::numeric_limits<s64_t>::max() - lhs._iVal) < rhs._iVal)
308
+ {
309
+ return plus_infinity();
310
+ }
311
+
312
+ // If both numbers are negative and their sum would be less than the
313
+ // most negative representable number, the result is negative infinity.
314
+ if (lhs._iVal < 0 && rhs._iVal < 0 &&
315
+ (-std::numeric_limits<s64_t>::max() - lhs._iVal) > rhs._iVal)
316
+ {
317
+ return minus_infinity();
318
+ }
319
+
320
+ // If none of the above conditions are met, the numbers can be safely
321
+ // added.
322
+ return lhs._iVal + rhs._iVal;
323
+ }
324
+
325
+ // Overloads the addition operator to safely add two BoundedInt objects.
326
+ // Utilizes the safeAdd method to handle potential overflow and underflow.
327
+ friend BoundedInt operator+(const BoundedInt& lhs, const BoundedInt& rhs)
328
+ {
329
+ return safeAdd(lhs, rhs);
330
+ }
331
+
332
+ // Overloads the unary minus operator to negate a BoundedInt object.
333
+ // The operation simply negates the internal integer value.
334
+ friend BoundedInt operator-(const BoundedInt& lhs)
335
+ {
336
+ return {-lhs._iVal, lhs._isInf};
337
+ }
338
+
339
+ // Overloads the subtraction operator to safely subtract one BoundedInt
340
+ // object from another. This is implemented as the addition of the lhs and
341
+ // the negation of the rhs, using the safeAdd method for safety.
342
+ friend BoundedInt operator-(const BoundedInt& lhs, const BoundedInt& rhs)
343
+ {
344
+ return safeAdd(lhs, -rhs);
345
+ }
346
+
347
+ /**
348
+ * @brief Performs safe multiplication of two BoundedInt objects.
349
+ *
350
+ * This function ensures that the multiplication of two BoundedInt objects
351
+ * doesn't result in overflow or underflow. It returns the multiplication
352
+ * result if it can be represented within the range of a 64-bit integer. If
353
+ * the result would be larger than the maximum representable positive
354
+ * number, it returns positive infinity. If the result would be less than
355
+ * the minimum representable negative number, it returns negative infinity.
356
+ * If either of the inputs is zero, the result is zero. If either of the
357
+ * inputs is infinity, the result is determined by the signs of the inputs.
358
+ *
359
+ * @param lhs The first BoundedInt to multiply.
360
+ * @param rhs The second BoundedInt to multiply.
361
+ * @return The result of the multiplication, or positive/negative infinity
362
+ * if the result would be outside the range of a 64-bit integer.
363
+ */
364
+ static BoundedInt safeMul(const BoundedInt& lhs, const BoundedInt& rhs)
365
+ {
366
+ // If either number is zero, the result is zero.
367
+ if (lhs._iVal == 0 || rhs._iVal == 0)
368
+ return 0;
369
+
370
+ // If either number is infinity, the result depends on the signs of the
371
+ // numbers.
372
+ if (lhs.is_infinity() || rhs.is_infinity())
373
+ {
374
+ // If the signs of the numbers are the same, the result is positive
375
+ // infinity. If the signs of the numbers are different, the result
376
+ // is negative infinity.
377
+ if (lhs._iVal * rhs._iVal > 0)
378
+ {
379
+ return plus_infinity();
380
+ }
381
+ else
382
+ {
383
+ return minus_infinity();
384
+ }
385
+ }
386
+
387
+ // If both numbers are positive and their product would exceed the
388
+ // maximum representable number, the result is positive infinity.
389
+ if (lhs._iVal > 0 && rhs._iVal > 0 &&
390
+ (std::numeric_limits<s64_t>::max() / lhs._iVal) < rhs._iVal)
391
+ {
392
+ return plus_infinity();
393
+ }
394
+
395
+ // If both numbers are negative and their product would exceed the
396
+ // maximum representable number, the result is positive infinity.
397
+ if (lhs._iVal < 0 && rhs._iVal < 0 &&
398
+ (std::numeric_limits<s64_t>::max() / lhs._iVal) > rhs._iVal)
399
+ {
400
+ return plus_infinity();
401
+ }
402
+
403
+ // If one number is positive and the other is negative and their product
404
+ // would be less than the most negative representable number, the result
405
+ // is negative infinity.
406
+ if ((lhs._iVal > 0 && rhs._iVal < 0 &&
407
+ (-std::numeric_limits<s64_t>::max() / lhs._iVal) > rhs._iVal) ||
408
+ (lhs._iVal < 0 && rhs._iVal > 0 &&
409
+ (-std::numeric_limits<s64_t>::max() / rhs._iVal) > lhs._iVal))
410
+ {
411
+ return minus_infinity();
412
+ }
413
+
414
+ // If none of the above conditions are met, the numbers can be safely
415
+ // multiplied.
416
+ return lhs._iVal * rhs._iVal;
417
+ }
418
+
419
+
420
+ friend BoundedInt operator%(const BoundedInt& lhs, const BoundedInt& rhs)
421
+ {
422
+ if (rhs.is_zero())
423
+ assert(false && "divide by zero");
424
+ else if (!lhs.is_infinity() && !rhs.is_infinity())
425
+ return lhs._iVal % rhs._iVal;
426
+ else if (!lhs.is_infinity() && rhs.is_infinity())
427
+ return 0;
428
+ // TODO: not sure
429
+ else if (lhs.is_infinity() && !rhs.is_infinity())
430
+ return ite(rhs._iVal > 0, lhs, -lhs);
431
+ else
432
+ // TODO: +oo/-oo L'Hôpital's rule?
433
+ return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
434
+ abort();
435
+ }
436
+ // Overloads the multiplication operator to safely multiply two BoundedInt
437
+ // objects. Utilizes the safeMul method to handle potential overflow.
438
+ friend BoundedInt operator*(const BoundedInt& lhs, const BoundedInt& rhs)
439
+ {
440
+ return safeMul(lhs, rhs);
441
+ }
442
+
443
+ // Overloads the division operator to safely divide a BoundedInt object by
444
+ // another. Utilizes the safeDiv method to handle potential division by zero
445
+ // and overflow.
446
+ friend BoundedInt operator/(const BoundedInt& lhs, const BoundedInt& rhs)
447
+ {
448
+ if (rhs.is_zero())
449
+ assert(false && "divide by zero");
450
+ else if (!lhs.is_infinity() && !rhs.is_infinity())
451
+ return lhs._iVal / rhs._iVal;
452
+ else if (!lhs.is_infinity() && rhs.is_infinity())
453
+ return 0;
454
+ else if (lhs.is_infinity() && !rhs.is_infinity())
455
+ return ite(rhs._iVal >= 0, lhs, -lhs);
456
+ else
457
+ return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
458
+ }
459
+
460
+ // Overload bitwise operators for BoundedInt objects. These operators
461
+ // directly apply the corresponding bitwise operators to the internal
462
+ // integer values of the BoundedInt objects.
463
+
464
+ // Overloads the bitwise XOR operator for BoundedInt objects.
465
+ friend BoundedInt operator^(const BoundedInt& lhs, const BoundedInt& rhs)
466
+ {
467
+ return lhs._iVal ^ rhs._iVal;
468
+ }
469
+
470
+ // Overloads the bitwise AND operator for BoundedInt objects.
471
+ friend BoundedInt operator&(const BoundedInt& lhs, const BoundedInt& rhs)
472
+ {
473
+ return lhs._iVal & rhs._iVal;
474
+ }
475
+
476
+ // Overloads the bitwise OR operator for BoundedInt objects.
477
+ friend BoundedInt operator|(const BoundedInt& lhs, const BoundedInt& rhs)
478
+ {
479
+ return lhs._iVal | rhs._iVal;
480
+ }
481
+
482
+ // Overload logical operators for BoundedInt objects. These operators
483
+ // directly apply the corresponding logical operators to the internal
484
+ // integer values of the BoundedInt objects.
485
+
486
+ // Overloads the logical AND operator for BoundedInt objects.
487
+ friend BoundedInt operator&&(const BoundedInt& lhs, const BoundedInt& rhs)
488
+ {
489
+ return lhs._iVal && rhs._iVal;
490
+ }
491
+
492
+ // Overloads the logical OR operator for BoundedInt objects.
493
+ friend BoundedInt operator||(const BoundedInt& lhs, const BoundedInt& rhs)
494
+ {
495
+ return lhs._iVal || rhs._iVal;
496
+ }
497
+
498
+ // Overloads the logical NOT operator for BoundedInt objects.
499
+ friend BoundedInt operator!(const BoundedInt& lhs)
500
+ {
501
+ return !lhs._iVal;
502
+ }
503
+
504
+ // Overloads the right shift operator for BoundedInt objects.
505
+ // This operation is safe as long as the right-hand side is non-negative.
506
+ // If the left-hand side is zero or infinity, the result is the same as the
507
+ // left-hand side. If the right-hand side is infinity, the result depends on
508
+ // the sign of the left-hand side.
509
+ friend BoundedInt operator>>(const BoundedInt& lhs, const BoundedInt& rhs)
510
+ {
511
+ assert(rhs.geq(0) && "rhs should be greater or equal than 0");
512
+ if (lhs.is_zero())
513
+ return lhs;
514
+ else if (lhs.is_infinity())
515
+ return lhs;
516
+ else if (rhs.is_infinity())
517
+ return lhs.geq(0) ? 0 : -1;
518
+ else
519
+ return lhs._iVal >> rhs._iVal;
520
+ }
521
+
522
+ // Overloads the left shift operator for BoundedInt objects.
523
+ // This operation is safe as long as the right-hand side is non-negative.
524
+ // If the left-hand side is zero or infinity, the result is the same as the
525
+ // left-hand side. If the right-hand side is infinity, the result depends on
526
+ // the sign of the left-hand side.
527
+ friend BoundedInt operator<<(const BoundedInt& lhs, const BoundedInt& rhs)
528
+ {
529
+ assert(rhs.geq(0) && "rhs should be greater or equal than 0");
530
+ if (lhs.is_zero())
531
+ return lhs;
532
+ else if (lhs.is_infinity())
533
+ return lhs;
534
+ else if (rhs.is_infinity())
535
+ return lhs.geq(0) ? plus_infinity() : minus_infinity();
536
+ else
537
+ return lhs._iVal << rhs._iVal;
538
+ }
539
+
540
+ // Overloads the ternary if-then-else operator for BoundedInt objects.
541
+ // The condition is evaluated as a boolean, and the result is either the
542
+ // second or third argument depending on the condition.
543
+ friend BoundedInt ite(const BoundedInt& cond, const BoundedInt& lhs,
544
+ const BoundedInt& rhs)
545
+ {
546
+ return cond._iVal != 0 ? lhs : rhs;
547
+ }
548
+
549
+ // Overloads the stream insertion operator for BoundedInt objects.
550
+ // This allows BoundedInt objects to be printed directly using std::cout or
551
+ // other output streams.
552
+ friend std::ostream& operator<<(std::ostream& out, const BoundedInt& expr)
553
+ {
554
+ out << expr._iVal;
555
+ return out;
556
+ }
557
+
558
+ // Defines a function to compare two BoundedInt objects for equality.
559
+ // This function directly compares the internal integer values of the
560
+ // BoundedInt objects.
561
+ friend bool eq(const BoundedInt& lhs, const BoundedInt& rhs)
562
+ {
563
+ return lhs._iVal == rhs._iVal && lhs._isInf == rhs._isInf;
564
+ }
565
+
566
+ // Defines a function to find the minimum of two BoundedInt objects.
567
+ // This function directly compares the internal integer values of the BoundedInt objects,
568
+ // and also checks if either of them represents infinity.
569
+ friend BoundedInt min(const BoundedInt& lhs, const BoundedInt& rhs)
570
+ {
571
+ if (lhs.is_minus_infinity() || rhs.is_minus_infinity())
572
+ return minus_infinity();
573
+ else if(lhs.is_plus_infinity())
574
+ return rhs;
575
+ else if(rhs.is_plus_infinity())
576
+ return lhs;
577
+ else
578
+ return BoundedInt(std::min(lhs._iVal, rhs._iVal));
579
+ }
580
+
581
+
582
+ // Defines a function to find the maximum of two BoundedInt objects.
583
+ // This function directly compares the internal integer values of the BoundedInt objects,
584
+ // and also checks if either of them represents infinity.
585
+ friend BoundedInt max(const BoundedInt& lhs, const BoundedInt& rhs)
586
+ {
587
+ if (lhs.is_plus_infinity() || rhs.is_plus_infinity())
588
+ return plus_infinity();
589
+ else if(lhs.is_minus_infinity())
590
+ return rhs;
591
+ else if(rhs.is_minus_infinity())
592
+ return lhs;
593
+ else
594
+ return BoundedInt(std::max(lhs._iVal, rhs._iVal));
595
+ }
596
+
597
+
598
+ // Defines a function to find the minimum of a vector of BoundedInt objects.
599
+ // This function iterates over the vector and returns the smallest
600
+ // BoundedInt object.
601
+ static BoundedInt min(std::vector<BoundedInt>& _l)
602
+ {
603
+ BoundedInt ret(plus_infinity());
604
+ for (const auto& it : _l)
605
+ {
606
+ if (it.is_minus_infinity())
607
+ return minus_infinity();
608
+ else if (!it.geq(ret))
609
+ {
610
+ ret = it;
611
+ }
612
+ }
613
+ return ret;
614
+ }
615
+
616
+ // Defines a function to find the maximum of a vector of BoundedInt objects.
617
+ // This function iterates over the vector and returns the largest BoundedInt
618
+ // object.
619
+ static BoundedInt max(std::vector<BoundedInt>& _l)
620
+ {
621
+ BoundedInt ret(minus_infinity());
622
+ for (const auto& it : _l)
623
+ {
624
+ if (it.is_plus_infinity())
625
+ return plus_infinity();
626
+ else if (!it.leq(ret))
627
+ {
628
+ ret = it;
629
+ }
630
+ }
631
+ return ret;
632
+ }
633
+
634
+ // Defines a function to find the absolute value of a BoundedInt object.
635
+ // This function directly applies the unary minus operator if the BoundedInt
636
+ // object is negative.
637
+ friend BoundedInt abs(const BoundedInt& lhs)
638
+ {
639
+ return lhs.leq(0) ? -lhs : lhs;
640
+ }
641
+
642
+ // Defines a method to check if a BoundedInt object is true.
643
+ // A BoundedInt object is considered true if its internal integer value is
644
+ // non-zero.
645
+ inline bool is_true() const
646
+ {
647
+ return _iVal != 0;
648
+ }
649
+
650
+ /**
651
+ * @brief Retrieves the numeral value of the BoundedInt object.
652
+ *
653
+ * This method returns the numeral representation of the BoundedInt object.
654
+ * If the object represents negative infinity, it returns the minimum
655
+ * representable 64-bit integer. If the object represents positive infinity,
656
+ * it returns the maximum representable 64-bit integer. Otherwise, it
657
+ * returns the actual 64-bit integer value of the object.
658
+ *
659
+ * @return The numeral value of the BoundedInt object.
660
+ */
661
+ inline s64_t getNumeral() const
662
+ {
663
+ // If the object represents negative infinity, return the minimum
664
+ // representable 64-bit integer.
665
+ if (is_minus_infinity())
666
+ {
667
+ return std::numeric_limits<s64_t>::min();
668
+ }
669
+ // If the object represents positive infinity, return the maximum
670
+ // representable 64-bit integer.
671
+ else if (is_plus_infinity())
672
+ {
673
+ return std::numeric_limits<s64_t>::max();
674
+ }
675
+ // Otherwise, return the actual 64-bit integer value of the object.
676
+ else
677
+ {
678
+ return _iVal;
679
+ }
680
+ }
681
+
682
+ inline virtual const std::string to_string() const
683
+ {
684
+ if (is_minus_infinity())
685
+ {
686
+ return "-oo";
687
+ }
688
+ if (is_plus_infinity())
689
+ {
690
+ return "+oo";
691
+ }
692
+ else
693
+ return std::to_string(_iVal);
694
+ }
695
+
696
+ //%}
697
+
698
+ bool is_real() const
699
+ {
700
+ return false;
701
+ }
702
+
703
+ inline s64_t getIntNumeral() const
704
+ {
705
+ return getNumeral();
706
+ }
707
+
708
+ inline double getRealNumeral() const
709
+ {
710
+ assert(false && "cannot get real number for integer!");
711
+ abort();
712
+ }
713
+
714
+ const double getFVal() const
715
+ {
716
+ assert(false && "cannot get real number for integer!");
717
+ abort();
718
+ }
719
+ };
720
+ /*!
721
+ * Bounded double numeric value
722
+ */
723
+ class BoundedDouble
724
+ {
725
+ protected:
726
+ double _fVal;
727
+
728
+ BoundedDouble() = default;
729
+
730
+ public:
731
+ BoundedDouble(double fVal) : _fVal(fVal) {}
732
+
733
+ BoundedDouble(const BoundedDouble& rhs) : _fVal(rhs._fVal) {}
734
+
735
+ BoundedDouble& operator=(const BoundedDouble& rhs)
736
+ {
737
+ _fVal = rhs._fVal;
738
+ return *this;
739
+ }
740
+
741
+ BoundedDouble(BoundedDouble&& rhs) : _fVal(std::move(rhs._fVal)) {}
742
+
743
+ BoundedDouble& operator=(BoundedDouble&& rhs)
744
+ {
745
+ _fVal = std::move(rhs._fVal);
746
+ return *this;
747
+ }
748
+
749
+ virtual ~BoundedDouble() {}
750
+
751
+ static bool doubleEqual(double a, double b)
752
+ {
753
+ if (std::isinf(a) && std::isinf(b))
754
+ return a == b;
755
+ return std::fabs(a - b) < epsilon;
756
+ }
757
+
758
+ const double getFVal() const
759
+ {
760
+ return _fVal;
761
+ }
762
+
763
+ bool is_plus_infinity() const
764
+ {
765
+ return _fVal == std::numeric_limits<double>::infinity();
766
+ }
767
+
768
+ bool is_minus_infinity() const
769
+ {
770
+ return _fVal == -std::numeric_limits<double>::infinity();
771
+ }
772
+
773
+ bool is_infinity() const
774
+ {
775
+ return is_plus_infinity() || is_minus_infinity();
776
+ }
777
+
778
+ void set_plus_infinity()
779
+ {
780
+ *this = plus_infinity();
781
+ }
782
+
783
+ void set_minus_infinity()
784
+ {
785
+ *this = minus_infinity();
786
+ }
787
+
788
+ static BoundedDouble plus_infinity()
789
+ {
790
+ return std::numeric_limits<double>::infinity();
791
+ }
792
+
793
+ static BoundedDouble minus_infinity()
794
+ {
795
+ return -std::numeric_limits<double>::infinity();
796
+ }
797
+
798
+ bool is_zero() const
799
+ {
800
+ return doubleEqual(_fVal, 0.0f);
801
+ }
802
+
803
+ static bool isZero(const BoundedDouble& expr)
804
+ {
805
+ return doubleEqual(expr.getFVal(), 0.0f);
806
+ }
807
+
808
+ bool equal(const BoundedDouble& rhs) const
809
+ {
810
+ return doubleEqual(_fVal, rhs._fVal);
811
+ }
812
+
813
+ bool leq(const BoundedDouble& rhs) const
814
+ {
815
+ if (is_infinity() ^ rhs.is_infinity())
816
+ {
817
+ if (is_infinity())
818
+ {
819
+ return is_minus_infinity();
820
+ }
821
+ else
822
+ {
823
+ return rhs.is_plus_infinity();
824
+ }
825
+ }
826
+ if (is_infinity() && rhs.is_infinity())
827
+ {
828
+ if (is_minus_infinity())
829
+ return true;
830
+ else
831
+ return rhs.is_plus_infinity();
832
+ }
833
+ else
834
+ return _fVal <= rhs._fVal;
835
+ }
836
+
837
+ bool geq(const BoundedDouble& rhs) const
838
+ {
839
+ if (is_infinity() ^ rhs.is_infinity())
840
+ {
841
+ if (is_infinity())
842
+ {
843
+ return is_plus_infinity();
844
+ }
845
+ else
846
+ {
847
+ return rhs.is_minus_infinity();
848
+ }
849
+ }
850
+ if (is_infinity() && rhs.is_infinity())
851
+ {
852
+ if (is_plus_infinity())
853
+ return true;
854
+ else
855
+ return rhs.is_minus_infinity();
856
+ }
857
+ else
858
+ return _fVal >= rhs._fVal;
859
+ }
860
+
861
+ /// Reload operator
862
+ //{%
863
+ friend BoundedDouble operator==(const BoundedDouble& lhs,
864
+ const BoundedDouble& rhs)
865
+ {
866
+ return lhs.equal(rhs);
867
+ }
868
+
869
+ friend BoundedDouble operator!=(const BoundedDouble& lhs,
870
+ const BoundedDouble& rhs)
871
+ {
872
+ return !lhs.equal(rhs);
873
+ }
874
+
875
+ friend BoundedDouble operator>(const BoundedDouble& lhs,
876
+ const BoundedDouble& rhs)
877
+ {
878
+ return !lhs.leq(rhs);
879
+ }
880
+
881
+ friend BoundedDouble operator<(const BoundedDouble& lhs,
882
+ const BoundedDouble& rhs)
883
+ {
884
+ return !lhs.geq(rhs);
885
+ }
886
+
887
+ friend BoundedDouble operator<=(const BoundedDouble& lhs,
888
+ const BoundedDouble& rhs)
889
+ {
890
+ return lhs.leq(rhs);
891
+ }
892
+
893
+ friend BoundedDouble operator>=(const BoundedDouble& lhs,
894
+ const BoundedDouble& rhs)
895
+ {
896
+ return lhs.geq(rhs);
897
+ }
898
+
899
+ /**
900
+ * Adds two floating-point numbers safely, checking for overflow and
901
+ * underflow conditions.
902
+ *
903
+ * @param lhs Left-hand side operand of the addition.
904
+ * @param rhs Right-hand side operand of the addition.
905
+ * @return The sum of lhs and rhs. If overflow or underflow occurs, returns
906
+ * positive or negative infinity.
907
+ */
908
+ static double safeAdd(double lhs, double rhs)
909
+ {
910
+ if ((lhs == std::numeric_limits<double>::infinity() &&
911
+ rhs == -std::numeric_limits<double>::infinity()) ||
912
+ (lhs == -std::numeric_limits<double>::infinity() &&
913
+ rhs == std::numeric_limits<double>::infinity()))
914
+ {
915
+ assert(false && "invalid add");
916
+ }
917
+ double res =
918
+ lhs + rhs; // Perform the addition and store the result in 'res'
919
+
920
+ // Check if the result is positive infinity due to overflow
921
+ if (res == std::numeric_limits<double>::infinity())
922
+ {
923
+ return res; // Positive overflow has occurred, return positive
924
+ // infinity
925
+ }
926
+
927
+ // Check if the result is negative infinity, which can indicate a large
928
+ // negative overflow
929
+ if (res == -std::numeric_limits<double>::infinity())
930
+ {
931
+ return res; // Negative "overflow", effectively an underflow to
932
+ // negative infinity
933
+ }
934
+
935
+ // Check for positive overflow: verify if both operands are positive and
936
+ // their sum exceeds the maximum double value
937
+ if (lhs > 0 && rhs > 0 &&
938
+ (std::numeric_limits<double>::max() - lhs) < rhs)
939
+ {
940
+ res = std::numeric_limits<double>::infinity(); // Set result to
941
+ // positive infinity to
942
+ // indicate overflow
943
+ return res;
944
+ }
945
+
946
+ // Check for an underflow scenario: both numbers are negative and their
947
+ // sum is more negative than what double can represent
948
+ if (lhs < 0 && rhs < 0 &&
949
+ (-std::numeric_limits<double>::max() - lhs) > rhs)
950
+ {
951
+ res = -std::numeric_limits<
952
+ double>::infinity(); // Set result to negative infinity to
953
+ // clarify extreme negative sum
954
+ return res;
955
+ }
956
+
957
+ // If none of the above conditions are met, return the result of the
958
+ // addition
959
+ return res;
960
+ }
961
+
962
+ friend BoundedDouble operator+(const BoundedDouble& lhs,
963
+ const BoundedDouble& rhs)
964
+ {
965
+ return safeAdd(lhs._fVal, rhs._fVal);
966
+ }
967
+
968
+ friend BoundedDouble operator-(const BoundedDouble& lhs)
969
+ {
970
+ return -lhs._fVal;
971
+ }
972
+
973
+ friend BoundedDouble operator-(const BoundedDouble& lhs,
974
+ const BoundedDouble& rhs)
975
+ {
976
+ return safeAdd(lhs._fVal, -rhs._fVal);
977
+ }
978
+
979
+ /**
980
+ * Safely multiplies two floating-point numbers, checking for overflow and
981
+ * underflow.
982
+ *
983
+ * @param lhs Left-hand side operand of the multiplication.
984
+ * @param rhs Right-hand side operand of the multiplication.
985
+ * @return The product of lhs and rhs. If overflow or underflow occurs,
986
+ * returns positive or negative infinity accordingly.
987
+ */
988
+ static double safeMul(double lhs, double rhs)
989
+ {
990
+ if (doubleEqual(lhs, 0.0f) || doubleEqual(rhs, 0.0f))
991
+ return 0.0f;
992
+ double res = lhs * rhs;
993
+ // Check if the result is positive infinity due to overflow
994
+ if (res == std::numeric_limits<double>::infinity())
995
+ {
996
+ return res; // Positive overflow has occurred, return positive
997
+ // infinity
998
+ }
999
+
1000
+ // Check if the result is negative infinity, which can indicate a large
1001
+ // negative overflow
1002
+ if (res == -std::numeric_limits<double>::infinity())
1003
+ {
1004
+ return res; // Negative "overflow", effectively an underflow to
1005
+ // negative infinity
1006
+ }
1007
+ // Check for overflow scenarios
1008
+ if (lhs > 0 && rhs > 0 &&
1009
+ lhs > std::numeric_limits<double>::max() / rhs)
1010
+ {
1011
+ return std::numeric_limits<double>::infinity();
1012
+ }
1013
+ if (lhs < 0 && rhs < 0 &&
1014
+ lhs < std::numeric_limits<double>::max() / rhs)
1015
+ {
1016
+ return std::numeric_limits<double>::infinity();
1017
+ }
1018
+
1019
+ // Check for "underflow" scenarios (negative overflow)
1020
+ if (lhs > 0 && rhs < 0 &&
1021
+ rhs < std::numeric_limits<double>::lowest() / lhs)
1022
+ {
1023
+ return -std::numeric_limits<double>::infinity();
1024
+ }
1025
+ if (lhs < 0 && rhs > 0 &&
1026
+ lhs < std::numeric_limits<double>::lowest() / rhs)
1027
+ {
1028
+ return -std::numeric_limits<double>::infinity();
1029
+ }
1030
+
1031
+ return res; // If no overflow or underflow, return the product
1032
+ }
1033
+
1034
+ friend BoundedDouble operator*(const BoundedDouble& lhs,
1035
+ const BoundedDouble& rhs)
1036
+ {
1037
+ return safeMul(lhs._fVal, rhs._fVal);
1038
+ }
1039
+
1040
+ /**
1041
+ * Safely divides one floating-point number by another, checking for
1042
+ * division by zero and overflow.
1043
+ *
1044
+ * @param lhs Left-hand side operand (numerator).
1045
+ * @param rhs Right-hand side operand (denominator).
1046
+ * @return The quotient of lhs and rhs. Returns positive or negative
1047
+ * infinity for division by zero, or when overflow occurs.
1048
+ */
1049
+ static double safeDiv(double lhs, double rhs)
1050
+ {
1051
+ // Check for division by zero
1052
+ if (doubleEqual(rhs, 0.0f))
1053
+ {
1054
+ return (lhs >= 0.0f) ? std::numeric_limits<double>::infinity()
1055
+ : -std::numeric_limits<double>::infinity();
1056
+ }
1057
+ double res = lhs / rhs;
1058
+ // Check if the result is positive infinity due to overflow
1059
+ if (res == std::numeric_limits<double>::infinity())
1060
+ {
1061
+ return res; // Positive overflow has occurred, return positive
1062
+ // infinity
1063
+ }
1064
+
1065
+ // Check if the result is negative infinity, which can indicate a large
1066
+ // negative overflow
1067
+ if (res == -std::numeric_limits<double>::infinity())
1068
+ {
1069
+ return res; // Negative "overflow", effectively an underflow to
1070
+ // negative infinity
1071
+ }
1072
+
1073
+ // Check for overflow when dividing small numbers
1074
+ if (rhs > 0 && rhs < std::numeric_limits<double>::min() &&
1075
+ lhs > std::numeric_limits<double>::max() * rhs)
1076
+ {
1077
+ return std::numeric_limits<double>::infinity();
1078
+ }
1079
+ if (rhs < 0 && rhs > -std::numeric_limits<double>::min() &&
1080
+ lhs > std::numeric_limits<double>::max() * rhs)
1081
+ {
1082
+ return -std::numeric_limits<double>::infinity();
1083
+ }
1084
+
1085
+ return res; // If no special cases, return the quotient
1086
+ }
1087
+
1088
+ friend BoundedDouble operator/(const BoundedDouble& lhs,
1089
+ const BoundedDouble& rhs)
1090
+ {
1091
+ return safeDiv(lhs._fVal, rhs._fVal);
1092
+ }
1093
+
1094
+ friend BoundedDouble operator%(const BoundedDouble& lhs,
1095
+ const BoundedDouble& rhs)
1096
+ {
1097
+ if (rhs.is_zero())
1098
+ assert(false && "divide by zero");
1099
+ else if (!lhs.is_infinity() && !rhs.is_infinity())
1100
+ return std::fmod(lhs._fVal, rhs._fVal);
1101
+ else if (!lhs.is_infinity() && rhs.is_infinity())
1102
+ return 0.0f;
1103
+ // TODO: not sure
1104
+ else if (lhs.is_infinity() && !rhs.is_infinity())
1105
+ return ite(rhs._fVal > 0.0f, lhs, -lhs);
1106
+ else
1107
+ // TODO: +oo/-oo L'Hôpital's rule?
1108
+ return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
1109
+ abort();
1110
+ }
1111
+
1112
+ inline bool is_int() const
1113
+ {
1114
+ return _fVal == std::round(_fVal);
1115
+ }
1116
+ inline bool is_real() const
1117
+ {
1118
+ return !is_int();
1119
+ }
1120
+
1121
+ friend BoundedDouble operator^(const BoundedDouble& lhs,
1122
+ const BoundedDouble& rhs)
1123
+ {
1124
+ int lInt = std::round(lhs._fVal), rInt = std::round(rhs._fVal);
1125
+ return lInt ^ rInt;
1126
+ }
1127
+
1128
+ friend BoundedDouble operator&(const BoundedDouble& lhs,
1129
+ const BoundedDouble& rhs)
1130
+ {
1131
+ int lInt = std::round(lhs._fVal), rInt = std::round(rhs._fVal);
1132
+ return lInt & rInt;
1133
+ }
1134
+
1135
+ friend BoundedDouble operator|(const BoundedDouble& lhs,
1136
+ const BoundedDouble& rhs)
1137
+ {
1138
+ int lInt = std::round(lhs._fVal), rInt = std::round(rhs._fVal);
1139
+ return lInt | rInt;
1140
+ }
1141
+
1142
+ friend BoundedDouble operator&&(const BoundedDouble& lhs,
1143
+ const BoundedDouble& rhs)
1144
+ {
1145
+ return lhs._fVal && rhs._fVal;
1146
+ }
1147
+
1148
+ friend BoundedDouble operator||(const BoundedDouble& lhs,
1149
+ const BoundedDouble& rhs)
1150
+ {
1151
+ return lhs._fVal || rhs._fVal;
1152
+ }
1153
+
1154
+ friend BoundedDouble operator!(const BoundedDouble& lhs)
1155
+ {
1156
+ return !lhs._fVal;
1157
+ }
1158
+
1159
+ friend BoundedDouble operator>>(const BoundedDouble& lhs,
1160
+ const BoundedDouble& rhs)
1161
+ {
1162
+ assert(rhs.geq(0) && "rhs should be greater or equal than 0");
1163
+ if (lhs.is_zero())
1164
+ return lhs;
1165
+ else if (lhs.is_infinity())
1166
+ return lhs;
1167
+ else if (rhs.is_infinity())
1168
+ return lhs.geq(0) ? 0 : -1;
1169
+ else
1170
+ return (s32_t)lhs.getNumeral() >> (s32_t)rhs.getNumeral();
1171
+ }
1172
+
1173
+ friend BoundedDouble operator<<(const BoundedDouble& lhs,
1174
+ const BoundedDouble& rhs)
1175
+ {
1176
+ assert(rhs.geq(0) && "rhs should be greater or equal than 0");
1177
+ if (lhs.is_zero())
1178
+ return lhs;
1179
+ else if (lhs.is_infinity())
1180
+ return lhs;
1181
+ else if (rhs.is_infinity())
1182
+ return lhs.geq(0) ? plus_infinity() : minus_infinity();
1183
+ else
1184
+ return (s32_t)lhs.getNumeral() << (s32_t)rhs.getNumeral();
1185
+ }
1186
+
1187
+ friend BoundedDouble ite(const BoundedDouble& cond,
1188
+ const BoundedDouble& lhs, const BoundedDouble& rhs)
1189
+ {
1190
+ return cond._fVal != 0.0f ? lhs._fVal : rhs._fVal;
1191
+ }
1192
+
1193
+ friend std::ostream& operator<<(std::ostream& out,
1194
+ const BoundedDouble& expr)
1195
+ {
1196
+ out << expr._fVal;
1197
+ return out;
1198
+ }
1199
+
1200
+ friend bool eq(const BoundedDouble& lhs, const BoundedDouble& rhs)
1201
+ {
1202
+ return doubleEqual(lhs._fVal, rhs._fVal);
1203
+ }
1204
+
1205
+ friend BoundedDouble min(const BoundedDouble& lhs, const BoundedDouble& rhs)
1206
+ {
1207
+ return std::min(lhs._fVal, rhs._fVal);
1208
+ }
1209
+
1210
+ friend BoundedDouble max(const BoundedDouble& lhs, const BoundedDouble& rhs)
1211
+ {
1212
+ return std::max(lhs._fVal, rhs._fVal);
1213
+ }
1214
+
1215
+ static BoundedDouble min(std::vector<BoundedDouble>& _l)
1216
+ {
1217
+ BoundedDouble ret(plus_infinity());
1218
+ for (const auto& it : _l)
1219
+ {
1220
+ if (it.is_minus_infinity())
1221
+ return minus_infinity();
1222
+ else if (!it.geq(ret))
1223
+ {
1224
+ ret = it;
1225
+ }
1226
+ }
1227
+ return ret;
1228
+ }
1229
+
1230
+ static BoundedDouble max(std::vector<BoundedDouble>& _l)
1231
+ {
1232
+ BoundedDouble ret(minus_infinity());
1233
+ for (const auto& it : _l)
1234
+ {
1235
+ if (it.is_plus_infinity())
1236
+ return plus_infinity();
1237
+ else if (!it.leq(ret))
1238
+ {
1239
+ ret = it;
1240
+ }
1241
+ }
1242
+ return ret;
1243
+ }
1244
+
1245
+ friend BoundedDouble abs(const BoundedDouble& lhs)
1246
+ {
1247
+ return lhs.leq(0) ? -lhs : lhs;
1248
+ }
1249
+
1250
+ inline bool is_true() const
1251
+ {
1252
+ return _fVal != 0.0f;
1253
+ }
1254
+
1255
+ /// Return Numeral
1256
+ inline s64_t getNumeral() const
1257
+ {
1258
+ if (is_minus_infinity())
1259
+ {
1260
+ return INT64_MIN;
1261
+ }
1262
+ else if (is_plus_infinity())
1263
+ {
1264
+ return INT64_MAX;
1265
+ }
1266
+ else
1267
+ {
1268
+ return std::round(_fVal);
1269
+ }
1270
+ }
1271
+
1272
+ inline s64_t getIntNumeral() const
1273
+ {
1274
+ return getNumeral();
1275
+ }
1276
+
1277
+ inline double getRealNumeral() const
1278
+ {
1279
+ return _fVal;
1280
+ }
1281
+
1282
+ inline virtual const std::string to_string() const
1283
+ {
1284
+ return std::to_string(_fVal);
1285
+ }
1286
+
1287
+ //%}
1288
+ }; // end class BoundedDouble
1289
+
1290
+ } // end namespace SVF
1291
+
1292
+ #endif // SVF_NUMERICVALUE_H