sysmlpy 0.91.0__tar.gz → 0.95.0__tar.gz

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 (163) hide show
  1. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/PKG-INFO +87 -1
  2. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/README.md +84 -0
  3. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/pyproject.toml +3 -1
  4. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/__init__.py +5 -1
  5. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/__main__.py +124 -1
  6. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr_visitor.py +101 -0
  7. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/evaluator.py +27 -0
  8. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/classes.py +8 -1
  9. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/plantuml.py +260 -2
  10. sysmlpy-0.95.0/src/sysmlpy/repl.py +638 -0
  11. sysmlpy-0.95.0/src/sysmlpy/reqif_io.py +411 -0
  12. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/usage.py +56 -0
  13. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/LICENSE +0 -0
  14. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/README.md +0 -0
  15. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  16. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  17. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  18. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  19. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  20. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  21. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  22. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  23. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  24. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  25. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  26. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/antlr_parser.py +0 -0
  27. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/boxes_view.py +0 -0
  28. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/definition.py +0 -0
  29. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/dfa_cache.py +0 -0
  30. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/diff.py +0 -0
  31. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  32. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  33. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  34. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/formatting.py +0 -0
  35. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  36. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  37. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  38. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  39. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  40. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  41. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  42. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  43. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  44. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  45. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  46. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  47. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  48. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  49. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  50. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  51. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/interchange.py +0 -0
  52. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/ipython_magic.py +0 -0
  53. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/LICENSE +0 -0
  54. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/README.md +0 -0
  55. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/__init__.py +0 -0
  56. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  57. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  58. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  59. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  60. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  61. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  62. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  63. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  64. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  65. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  66. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  67. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  68. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  69. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  70. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  71. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  72. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  73. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  74. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  75. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  76. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  77. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  78. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  79. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  80. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  81. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  82. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  83. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  84. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  85. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  86. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  87. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  88. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  89. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  90. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  91. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  92. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  93. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  94. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  95. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  96. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  97. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  98. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  99. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  100. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  101. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  102. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  103. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  104. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  105. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  106. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  107. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  108. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  109. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  110. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  111. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  112. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  113. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  114. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  115. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  116. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  117. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  118. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  119. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  120. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  121. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  122. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  123. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  124. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  125. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  126. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  127. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  128. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  129. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  130. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  131. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  132. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  133. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  134. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  135. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  136. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  137. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  138. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  139. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  140. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  141. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  142. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  143. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  144. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  145. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  146. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  147. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  148. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  149. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  150. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/lsp/__init__.py +0 -0
  151. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/lsp/__main__.py +0 -0
  152. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/lsp/protocol.py +0 -0
  153. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/lsp/server.py +0 -0
  154. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/lsp/stdio.py +0 -0
  155. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/navigate.py +0 -0
  156. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/project.py +0 -0
  157. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/semantic.py +0 -0
  158. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/sim.py +0 -0
  159. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/spreadsheet.py +0 -0
  160. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/store.py +0 -0
  161. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/traceability.py +0 -0
  162. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/us_customary_units.txt +0 -0
  163. {sysmlpy-0.91.0 → sysmlpy-0.95.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.91.0
3
+ Version: 0.95.0
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: Jon R. Fox (mycr0ft)
@@ -17,6 +17,7 @@ Provides-Extra: cayley
17
17
  Provides-Extra: graph
18
18
  Provides-Extra: jupyter
19
19
  Provides-Extra: kuzu
20
+ Provides-Extra: reqif
20
21
  Provides-Extra: sim
21
22
  Provides-Extra: xlsx
22
23
  Requires-Dist: antlr4-python3-runtime (>=4.13)
@@ -27,6 +28,7 @@ Requires-Dist: networkx (>=3.0) ; extra == "graph"
27
28
  Requires-Dist: openpyxl (>=3.1) ; extra == "xlsx"
28
29
  Requires-Dist: pint (>=0.24)
29
30
  Requires-Dist: pyyaml (>=6.0)
31
+ Requires-Dist: reqif (>=0.1) ; extra == "reqif"
30
32
  Requires-Dist: requests (>=2.31) ; extra == "cayley"
31
33
  Requires-Dist: transitions (>=0.9,<0.10) ; extra == "sim"
32
34
  Description-Content-Type: text/markdown
@@ -73,6 +75,7 @@ sysmlpy requires the following Python packages:
73
75
  - [networkx](https://networkx.org/) — graph analysis backend (install with `pip install sysmlpy[graph]`)
74
76
  - [kuzu](https://kuzudb.com/) — embedded graph database with disk persistence and Cypher queries (install with `pip install sysmlpy[kuzu]`)
75
77
  - [cayley](https://cayley.io/) — graph database via HTTP API, supports BoltDB/LevelDB backends (install with `pip install sysmlpy[cayley]`)
78
+ - [reqif](https://github.com/strictdoc-project/reqif) — ReqIF 1.0 requirements interchange, import/export with any ReqIF-capable tool (install with `pip install sysmlpy[reqif]`; see [ReqIF Interchange](#reqif-interchange-requirements-interchange-format))
76
79
  - [PlantUML](https://plantuml.com/) **v1.2020.0+** — diagram rendering (requires Java + PlantUML JAR or [PlantUML server](https://www.plantuml.com/plantuml)). The generator uses `<style>` blocks and `skinparam` stereotype selectors introduced in v1.2020.
77
80
  - [IPython](https://ipython.org/) **v8.0+** — the `%%sysml` Jupyter cell magic (install with `pip install sysmlpy[jupyter]`; see [Jupyter integration](#jupyter-integration))
78
81
 
@@ -150,9 +153,12 @@ threshold or operational error, `2` = parse/load failure — so
150
153
  | `sysmlpy trace <file>` | Requirement traceability & verification coverage |
151
154
  | `sysmlpy export <file>` | Export to the JSON interchange format |
152
155
  | `sysmlpy import <file>` | Import a JSON interchange document as SysML text |
156
+ | `sysmlpy reqif-import <file>` | Import a ReqIF file as SysML v2 requirements |
157
+ | `sysmlpy reqif-export <file>` | Export model requirements as ReqIF 1.0 XML |
153
158
  | `sysmlpy eval <file>` | Evaluate expressions, attribute values, constraints |
154
159
  | `sysmlpy sim <file>` | Simulate a state machine (guards evaluated for real) |
155
160
  | `sysmlpy xlsx <file>` | Export tabular views to an Excel workbook |
161
+ | `sysmlpy repl <file...>` | Interactive REPL: declarations accumulate into a session model; `%eval`, `%sim`, `%view`, `%check`, ... inspect it |
156
162
  | `sysmlpy-lsp` | Language server (stdio) for SysML v2 editors |
157
163
 
158
164
  Examples:
@@ -171,6 +177,15 @@ sysmlpy view model.sysml --view sv > model.puml
171
177
  # Drive a state machine interactively
172
178
  sysmlpy sim traffic_light.sysml
173
179
 
180
+ # Or work in an accumulating session: declare, query, evaluate, simulate
181
+ sysmlpy repl
182
+ sysml> package Demo { part def Wheel { attribute diameter : Real = 16.0; } }
183
+ ✓ Demo
184
+ sysml> %eval Demo::Wheel::diameter
185
+ = 16.0
186
+ sysml> %view Demo pkg
187
+ sysml> %quit
188
+
174
189
  # Excel workbook of the tabular views
175
190
  sysmlpy xlsx bill_of_materials.sysml -o bom.xlsx
176
191
  ```
@@ -864,6 +879,77 @@ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for all rendered exampl
864
879
  | 15 | Relationship Matrix (GridView) | Relationship Matrix |
865
880
  | 16 | Tabular View — Color | Tabular View (color) |
866
881
 
882
+ ## ReqIF Interchange (Requirements Interchange Format)
883
+
884
+ sysmlpy imports and exports **ReqIF 1.0** — the OMG requirements interchange
885
+ standard used by DOORS, Polarion, ReqIF Studio, Capella, Enterprise Architect,
886
+ and most requirements-management tools. This makes sysmlpy a viable
887
+ *single source of truth* for requirements: author them as SysML v2
888
+ `requirement` elements, then exchange them with any ReqIF-capable toolchain.
889
+
890
+ Install the optional dependency once:
891
+
892
+ ```bash
893
+ pip install sysmlpy[reqif]
894
+ ```
895
+
896
+ ### Import — ReqIF → SysML requirements
897
+
898
+ ```python
899
+ from sysmlpy import reqif_import, loads
900
+
901
+ text = reqif_import("requirements.reqif") # ReqIF XML → SysML v2 text
902
+ model = loads(text) # → live requirement tree
903
+ ```
904
+
905
+ Each ReqIF SpecObject becomes a `requirement` element; the ReqIF
906
+ specification hierarchy becomes requirement ownership nesting;
907
+ `ReqIF.Text` (XHTML) becomes the requirement's `doc` comment with tags
908
+ stripped; other attributes (e.g. `ReqIF.ForeignID`) are folded into the
909
+ doc so no data is lost.
910
+
911
+ ### Export — SysML requirements → ReqIF
912
+
913
+ ```python
914
+ from sysmlpy import loads, reqif_export
915
+
916
+ model = loads("model.sysml")
917
+ reqif_export(model, "requirements.reqif")
918
+ ```
919
+
920
+ Requirement ownership becomes the ReqIF hierarchy; `doc` comments become
921
+ `ReqIF.Text` XHTML values.
922
+
923
+ ### CLI
924
+
925
+ ```bash
926
+ sysmlpy reqif-import requirements.reqif -o requirements.sysml
927
+ sysmlpy reqif-export model.sysml -o requirements.reqif
928
+ ```
929
+
930
+ The import direction was validated against real-world anonymized ReqIF
931
+ files from multiple vendor flavors (ReqIF Studio, DOORS, Polarion,
932
+ Eclipse RMF, Enterprise Architect — see the
933
+ [reqif project's corpus](https://github.com/strictdoc-project/reqif/tree/main/tests/integration/reqif_software)),
934
+ including a 137-requirement model with a 3-level hierarchy and 14
935
+ relations, round-tripped through sysmlpy with exact structural fidelity.
936
+
937
+ > **Note:** ReqIF "flavors" differ across tools (attribute naming,
938
+ > datatypes, relation semantics). The importer handles the common
939
+ > `ReqIF.Text` / `ReqIF.ChapterName` / `ReqIF.ForeignID` attributes
940
+ > found in every flavor; exotic vendor extensions are skipped
941
+ > gracefully. If a file fails to import, it is genuinely malformed.
942
+
943
+ ### Relationship to other tools
944
+
945
+ - **Cameo / MagicDraw** — export ReqIF from them, import with sysmlpy;
946
+ no license needed on the sysmlpy side.
947
+ - **Doorstop** — the [Doorstop](https://doorstop.readthedocs.io) text-file
948
+ requirements tool can serve as a git-native review/publishing front-end;
949
+ exchange via ReqIF or the XLSX bridge.
950
+ - **[strictdoc/reqif](https://github.com/strictdoc-project/reqif)** — the
951
+ parser library sysmlpy uses for the ReqIF wire format (Apache-2.0).
952
+
867
953
  ## Conformance
868
954
 
869
955
  **100% of 123 OMG XPect conformance tests pass** (123/123).
@@ -40,6 +40,7 @@ sysmlpy requires the following Python packages:
40
40
  - [networkx](https://networkx.org/) — graph analysis backend (install with `pip install sysmlpy[graph]`)
41
41
  - [kuzu](https://kuzudb.com/) — embedded graph database with disk persistence and Cypher queries (install with `pip install sysmlpy[kuzu]`)
42
42
  - [cayley](https://cayley.io/) — graph database via HTTP API, supports BoltDB/LevelDB backends (install with `pip install sysmlpy[cayley]`)
43
+ - [reqif](https://github.com/strictdoc-project/reqif) — ReqIF 1.0 requirements interchange, import/export with any ReqIF-capable tool (install with `pip install sysmlpy[reqif]`; see [ReqIF Interchange](#reqif-interchange-requirements-interchange-format))
43
44
  - [PlantUML](https://plantuml.com/) **v1.2020.0+** — diagram rendering (requires Java + PlantUML JAR or [PlantUML server](https://www.plantuml.com/plantuml)). The generator uses `<style>` blocks and `skinparam` stereotype selectors introduced in v1.2020.
44
45
  - [IPython](https://ipython.org/) **v8.0+** — the `%%sysml` Jupyter cell magic (install with `pip install sysmlpy[jupyter]`; see [Jupyter integration](#jupyter-integration))
45
46
 
@@ -117,9 +118,12 @@ threshold or operational error, `2` = parse/load failure — so
117
118
  | `sysmlpy trace <file>` | Requirement traceability & verification coverage |
118
119
  | `sysmlpy export <file>` | Export to the JSON interchange format |
119
120
  | `sysmlpy import <file>` | Import a JSON interchange document as SysML text |
121
+ | `sysmlpy reqif-import <file>` | Import a ReqIF file as SysML v2 requirements |
122
+ | `sysmlpy reqif-export <file>` | Export model requirements as ReqIF 1.0 XML |
120
123
  | `sysmlpy eval <file>` | Evaluate expressions, attribute values, constraints |
121
124
  | `sysmlpy sim <file>` | Simulate a state machine (guards evaluated for real) |
122
125
  | `sysmlpy xlsx <file>` | Export tabular views to an Excel workbook |
126
+ | `sysmlpy repl <file...>` | Interactive REPL: declarations accumulate into a session model; `%eval`, `%sim`, `%view`, `%check`, ... inspect it |
123
127
  | `sysmlpy-lsp` | Language server (stdio) for SysML v2 editors |
124
128
 
125
129
  Examples:
@@ -138,6 +142,15 @@ sysmlpy view model.sysml --view sv > model.puml
138
142
  # Drive a state machine interactively
139
143
  sysmlpy sim traffic_light.sysml
140
144
 
145
+ # Or work in an accumulating session: declare, query, evaluate, simulate
146
+ sysmlpy repl
147
+ sysml> package Demo { part def Wheel { attribute diameter : Real = 16.0; } }
148
+ ✓ Demo
149
+ sysml> %eval Demo::Wheel::diameter
150
+ = 16.0
151
+ sysml> %view Demo pkg
152
+ sysml> %quit
153
+
141
154
  # Excel workbook of the tabular views
142
155
  sysmlpy xlsx bill_of_materials.sysml -o bom.xlsx
143
156
  ```
@@ -831,6 +844,77 @@ See [`docs/plantuml-examples/`](docs/plantuml-examples/) for all rendered exampl
831
844
  | 15 | Relationship Matrix (GridView) | Relationship Matrix |
832
845
  | 16 | Tabular View — Color | Tabular View (color) |
833
846
 
847
+ ## ReqIF Interchange (Requirements Interchange Format)
848
+
849
+ sysmlpy imports and exports **ReqIF 1.0** — the OMG requirements interchange
850
+ standard used by DOORS, Polarion, ReqIF Studio, Capella, Enterprise Architect,
851
+ and most requirements-management tools. This makes sysmlpy a viable
852
+ *single source of truth* for requirements: author them as SysML v2
853
+ `requirement` elements, then exchange them with any ReqIF-capable toolchain.
854
+
855
+ Install the optional dependency once:
856
+
857
+ ```bash
858
+ pip install sysmlpy[reqif]
859
+ ```
860
+
861
+ ### Import — ReqIF → SysML requirements
862
+
863
+ ```python
864
+ from sysmlpy import reqif_import, loads
865
+
866
+ text = reqif_import("requirements.reqif") # ReqIF XML → SysML v2 text
867
+ model = loads(text) # → live requirement tree
868
+ ```
869
+
870
+ Each ReqIF SpecObject becomes a `requirement` element; the ReqIF
871
+ specification hierarchy becomes requirement ownership nesting;
872
+ `ReqIF.Text` (XHTML) becomes the requirement's `doc` comment with tags
873
+ stripped; other attributes (e.g. `ReqIF.ForeignID`) are folded into the
874
+ doc so no data is lost.
875
+
876
+ ### Export — SysML requirements → ReqIF
877
+
878
+ ```python
879
+ from sysmlpy import loads, reqif_export
880
+
881
+ model = loads("model.sysml")
882
+ reqif_export(model, "requirements.reqif")
883
+ ```
884
+
885
+ Requirement ownership becomes the ReqIF hierarchy; `doc` comments become
886
+ `ReqIF.Text` XHTML values.
887
+
888
+ ### CLI
889
+
890
+ ```bash
891
+ sysmlpy reqif-import requirements.reqif -o requirements.sysml
892
+ sysmlpy reqif-export model.sysml -o requirements.reqif
893
+ ```
894
+
895
+ The import direction was validated against real-world anonymized ReqIF
896
+ files from multiple vendor flavors (ReqIF Studio, DOORS, Polarion,
897
+ Eclipse RMF, Enterprise Architect — see the
898
+ [reqif project's corpus](https://github.com/strictdoc-project/reqif/tree/main/tests/integration/reqif_software)),
899
+ including a 137-requirement model with a 3-level hierarchy and 14
900
+ relations, round-tripped through sysmlpy with exact structural fidelity.
901
+
902
+ > **Note:** ReqIF "flavors" differ across tools (attribute naming,
903
+ > datatypes, relation semantics). The importer handles the common
904
+ > `ReqIF.Text` / `ReqIF.ChapterName` / `ReqIF.ForeignID` attributes
905
+ > found in every flavor; exotic vendor extensions are skipped
906
+ > gracefully. If a file fails to import, it is genuinely malformed.
907
+
908
+ ### Relationship to other tools
909
+
910
+ - **Cameo / MagicDraw** — export ReqIF from them, import with sysmlpy;
911
+ no license needed on the sysmlpy side.
912
+ - **Doorstop** — the [Doorstop](https://doorstop.readthedocs.io) text-file
913
+ requirements tool can serve as a git-native review/publishing front-end;
914
+ exchange via ReqIF or the XLSX bridge.
915
+ - **[strictdoc/reqif](https://github.com/strictdoc-project/reqif)** — the
916
+ parser library sysmlpy uses for the ReqIF wire format (Apache-2.0).
917
+
834
918
  ## Conformance
835
919
 
836
920
  **100% of 123 OMG XPect conformance tests pass** (123/123).
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [project]
8
8
  name = "sysmlpy"
9
- version = "0.91.0"
9
+ version = "0.95.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -20,6 +20,7 @@ antlr4-python3-runtime = ">=4.13"
20
20
  networkx = { version = ">=3.0", optional = true }
21
21
  kuzu = { version = ">=0.7,<0.12", optional = true }
22
22
  openpyxl = { version = ">=3.1", optional = true }
23
+ reqif = { version = ">=0.1", optional = true }
23
24
  arrow = "^1.4.0"
24
25
  transitions = {version = "^0.9", optional = true}
25
26
  requests = { version = ">=2.31", optional = true }
@@ -30,6 +31,7 @@ graph = ["networkx"]
30
31
  kuzu = ["kuzu"]
31
32
  xlsx = ["openpyxl"]
32
33
  sim = ["transitions"]
34
+ reqif = ["reqif"]
33
35
  cayley = ["requests"]
34
36
  jupyter = ["ipython"]
35
37
 
@@ -20,6 +20,7 @@ __all__ = [
20
20
  "as_sequence_view", "as_case_view", "as_browser_view",
21
21
  "extract_traceability", "TraceabilityReport", "RequirementTrace",
22
22
  "to_interchange", "from_interchange", "interchange_to_json_text",
23
+ "reqif_import", "reqif_import_model", "reqif_export",
23
24
  "evaluate_expression", "evaluate_calculation", "collect_values",
24
25
  "check_constraints", "ConstraintReport", "ConstraintResult",
25
26
  "tabular_view_to_csv", "data_value_tabular_to_csv",
@@ -34,7 +35,7 @@ __all__ = [
34
35
  "render_state_transition_view_svg", "boxes_view",
35
36
  ]
36
37
  __author__ = "Jon Fox"
37
- __version__ = "0.91.0"
38
+ __version__ = "0.95.0"
38
39
 
39
40
  from sysmlpy.usage import (
40
41
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -57,6 +58,9 @@ from sysmlpy.traceability import (
57
58
  from sysmlpy.interchange import (
58
59
  to_interchange, from_interchange, interchange_to_json_text,
59
60
  )
61
+ from sysmlpy.reqif_io import (
62
+ reqif_import, reqif_import_model, reqif_export,
63
+ )
60
64
  from sysmlpy.evaluator import (
61
65
  evaluate_expression, evaluate_calculation, collect_values,
62
66
  check_constraints, ConstraintReport, ConstraintResult,
@@ -33,7 +33,8 @@ from sysmlpy import loads
33
33
 
34
34
  # Subcommand table, also used to detect the legacy flat invocation form.
35
35
  SUBCOMMANDS = ("parse", "analyze", "view", "trace", "export", "import",
36
- "eval", "xlsx", "sim", "diff", "format", "fmt")
36
+ "reqif-import", "reqif-export",
37
+ "eval", "xlsx", "sim", "diff", "format", "fmt", "repl")
37
38
 
38
39
 
39
40
  # ---------------------------------------------------------------------------
@@ -442,6 +443,60 @@ def cmd_import(args) -> int:
442
443
  return 0
443
444
 
444
445
 
446
+ def cmd_reqif_import(args) -> int:
447
+ """ReqIF file → SysML v2 requirements text."""
448
+ from sysmlpy.reqif_io import ReqIFImportError, reqif_import
449
+
450
+ path = Path(args.file)
451
+ if not path.exists():
452
+ print(f"Error: File '{path}' not found.", file=sys.stderr)
453
+ return 2
454
+
455
+ try:
456
+ output = reqif_import(str(path))
457
+ except ReqIFImportError as e:
458
+ print(f"Error: {e}", file=sys.stderr)
459
+ return 2
460
+ except Exception as e: # noqa: BLE001 - surface parser failures cleanly
461
+ print(f"Error: ReqIF import failed: {e}", file=sys.stderr)
462
+ return 2
463
+
464
+ if args.output:
465
+ Path(args.output).write_text(output, encoding="utf-8")
466
+ print(f"Wrote {args.output}")
467
+ else:
468
+ print(output)
469
+ return 0
470
+
471
+
472
+ def cmd_reqif_export(args) -> int:
473
+ """SysML requirements → ReqIF 1.0 XML."""
474
+ from sysmlpy.reqif_io import ReqIFExportError, reqif_export
475
+
476
+ paths = [Path(f) for f in args.files]
477
+ for p in _missing_files(paths):
478
+ print(f"Error: File '{p}' not found.", file=sys.stderr)
479
+ return 2
480
+
481
+ try:
482
+ model = sysmlpy.load_files(paths, library=args.library)
483
+ except Exception as e:
484
+ print(f"Parse error: {e}", file=sys.stderr)
485
+ return 2
486
+
487
+ try:
488
+ reqif_export(model, args.output)
489
+ except ReqIFExportError as e:
490
+ print(f"Error: {e}", file=sys.stderr)
491
+ return 1
492
+ except Exception as e: # noqa: BLE001 - surface unparser failures cleanly
493
+ print(f"Error: ReqIF export failed: {e}", file=sys.stderr)
494
+ return 1
495
+
496
+ print(f"Wrote {args.output}")
497
+ return 0
498
+
499
+
445
500
  def _parse_eval_value(text):
446
501
  """Parse a --set NAME=VALUE literal (number / bool / string / unit)."""
447
502
  from sysmlpy.usage import ureg
@@ -606,6 +661,16 @@ def cmd_sim(args) -> int:
606
661
  return 0
607
662
 
608
663
 
664
+ def cmd_repl(args) -> int:
665
+ """Interactive REPL (declarations accumulate; %commands inspect)."""
666
+ from sysmlpy.repl import main as repl_main
667
+
668
+ return repl_main(
669
+ [*(args.files or []), *(["--no-banner"] if args.no_banner else [])]
670
+ + (["-l", args.library] if getattr(args, "library", None) else []),
671
+ )
672
+
673
+
609
674
  def cmd_xlsx(args) -> int:
610
675
  """Export tabular views to an Excel workbook (v0.66.0, Goal 7)."""
611
676
  from sysmlpy.spreadsheet import write_xlsx
@@ -922,6 +987,43 @@ def build_parser() -> argparse.ArgumentParser:
922
987
  )
923
988
  p_import.set_defaults(func=cmd_import)
924
989
 
990
+ # -- reqif-import / reqif-export ------------------------------------------
991
+ p_reqif_import = sub.add_parser(
992
+ "reqif-import",
993
+ help="Import a ReqIF file as SysML v2 requirements",
994
+ description="Convert a ReqIF 1.0 XML file (ReqIF Studio, DOORS, "
995
+ "Polarion, Eclipse RMF, ...) into SysML v2 requirement "
996
+ "usages, nested by the ReqIF specification hierarchy. "
997
+ "Exit 2 on invalid input. Requires the optional 'reqif' "
998
+ "package.",
999
+ )
1000
+ p_reqif_import.add_argument("file", help="ReqIF XML file")
1001
+ p_reqif_import.add_argument(
1002
+ "-o", "--output",
1003
+ help="Write the SysML text to a file instead of stdout",
1004
+ )
1005
+ p_reqif_import.set_defaults(func=cmd_reqif_import)
1006
+
1007
+ p_reqif_export = sub.add_parser(
1008
+ "reqif-export",
1009
+ help="Export model requirements as a ReqIF 1.0 file",
1010
+ description="Export the requirements of the merged model as ReqIF "
1011
+ "1.0 XML (one spec object per requirement, hierarchy "
1012
+ "from ownership, doc comments as ReqIF.Text). Exit 1 "
1013
+ "when the model has no requirements. Requires the "
1014
+ "optional 'reqif' package.",
1015
+ )
1016
+ p_reqif_export.add_argument("files", nargs="+", help="SysML v2 file(s)")
1017
+ p_reqif_export.add_argument(
1018
+ "-o", "--output", required=True,
1019
+ help="Destination ReqIF XML file",
1020
+ )
1021
+ p_reqif_export.add_argument(
1022
+ "-l", "--library",
1023
+ help="Path to SysML v2 library files to use for parsing",
1024
+ )
1025
+ p_reqif_export.set_defaults(func=cmd_reqif_export)
1026
+
925
1027
  p_eval = sub.add_parser(
926
1028
  "eval",
927
1029
  help="Evaluate expressions, attribute values and constraints",
@@ -1030,6 +1132,27 @@ def build_parser() -> argparse.ArgumentParser:
1030
1132
  )
1031
1133
  p_xlsx.set_defaults(func=cmd_xlsx)
1032
1134
 
1135
+ # -- repl ----------------------------------------------------------------
1136
+ p_repl = sub.add_parser(
1137
+ "repl",
1138
+ help="Interactive SysML v2 REPL",
1139
+ description="Declarations accumulate into a session model; "
1140
+ "%commands inspect it (%eval, %sim, %view, ...). "
1141
+ "See %help inside the REPL for the command list.",
1142
+ )
1143
+ p_repl.add_argument("files", nargs="*", metavar="FILE",
1144
+ help="model file(s) to load into the session first")
1145
+ p_repl.add_argument(
1146
+ "-l", "--library",
1147
+ help="Path to SysML v2 library files (accepted for parity; "
1148
+ "submissions parse without it)",
1149
+ )
1150
+ p_repl.add_argument(
1151
+ "--no-banner", action="store_true",
1152
+ help="suppress the startup banner",
1153
+ )
1154
+ p_repl.set_defaults(func=cmd_repl)
1155
+
1033
1156
  return parser
1034
1157
 
1035
1158
 
@@ -6389,6 +6389,92 @@ def _make_state_usage_dict(ctx, prefix=None):
6389
6389
  }
6390
6390
 
6391
6391
 
6392
+ def _make_exhibit_state_usage_dict(ctx, prefix=None):
6393
+ """Create a StateUsage dictionary for an ``exhibit state`` usage.
6394
+
6395
+ Grammar:
6396
+ exhibitStateUsage
6397
+ : occurrenceUsagePrefix EXHIBIT
6398
+ ( ownedReferenceSubsetting featureSpecializationPart?
6399
+ | STATE usageDeclaration? ) valuePart? stateUsageBody
6400
+ ;
6401
+
6402
+ Both spellings met in practice carry a usageDeclaration:
6403
+ exhibit state phases : MissionPhases; (typed reference)
6404
+ exhibit state modes { ... } (inline body)
6405
+ The dict is a StateUsage with ``exhibit: True`` so the grammar class
6406
+ dumps the ``exhibit`` keyword and every downstream consumer (public
6407
+ tree, boxes collector, sim) sees a plain StateUsage node. Previously
6408
+ ``exhibit state`` was silently dropped by the visitor, which made
6409
+ part-embedded state machines invisible to sim and lossy on dump.
6410
+ """
6411
+ if ctx is None:
6412
+ return None
6413
+
6414
+ occ_prefix = _get_occurrence_usage_prefix(ctx)
6415
+ if prefix is not None:
6416
+ occ_prefix = prefix
6417
+
6418
+ # Declaration: name/shortname from the usageDeclaration, typing from
6419
+ # its featureSpecializationPart (``: MissionPhases``).
6420
+ name, shortname = _get_usage_identification(ctx)
6421
+ specialization = _build_full_specialization_from_ctx(ctx)
6422
+
6423
+ decl_dict = None
6424
+ if hasattr(ctx, 'usageDeclaration') and ctx.usageDeclaration():
6425
+ ud = ctx.usageDeclaration()
6426
+ if isinstance(ud, list):
6427
+ ud = ud[0] if ud else None
6428
+ if ud is not None:
6429
+ decl_dict = {
6430
+ "name": "ActionUsageDeclaration",
6431
+ "declaration": {
6432
+ "name": "UsageDeclaration",
6433
+ "declaration": {
6434
+ "name": "FeatureDeclaration",
6435
+ "identification": {
6436
+ "name": "Identification",
6437
+ "declaredShortName": shortname,
6438
+ "declaredName": name
6439
+ },
6440
+ "specialization": specialization
6441
+ }
6442
+ },
6443
+ "valuepart": None
6444
+ }
6445
+
6446
+ # Body: a stateUsageBody, exactly like a plain stateUsage.
6447
+ body_dict = {"name": "StateUsageBody", "body": {"name": "StateDefBody", "part": None, "isParallel": None}}
6448
+ if hasattr(ctx, 'stateUsageBody') and ctx.stateUsageBody():
6449
+ sub = ctx.stateUsageBody()
6450
+ if isinstance(sub, list):
6451
+ sub = sub[0]
6452
+ if sub:
6453
+ body_dict = _visit_state_usage_body(sub)
6454
+
6455
+ return {
6456
+ "name": "PackageMember",
6457
+ "prefix": None,
6458
+ "ownedRelatedElement": {
6459
+ "name": "UsageElement",
6460
+ "ownedRelatedElement": {
6461
+ "name": "OccurrenceUsageElement",
6462
+ "ownedRelatedElement": {
6463
+ "name": "BehaviorUsageElement",
6464
+ "ownedRelationship": {
6465
+ "name": "StateUsage",
6466
+ "prefix": occ_prefix,
6467
+ "exhibit": True,
6468
+ "keyword": "state",
6469
+ "declaration": decl_dict,
6470
+ "body": body_dict
6471
+ }
6472
+ }
6473
+ }
6474
+ }
6475
+ }
6476
+
6477
+
6392
6478
  def _make_calculation_usage_dict(ctx, prefix=None):
6393
6479
  """Create a CalculationUsage dictionary.
6394
6480
 
@@ -10650,6 +10736,16 @@ def _visit_nested_occurrence_usage(occ_elem):
10650
10736
  inner = result.get("ownedRelatedElement", {})
10651
10737
  return inner
10652
10738
  return result
10739
+ elif hasattr(behav_elem, 'exhibitStateUsage') and behav_elem.exhibitStateUsage():
10740
+ # ``exhibit state`` usages share the BehaviorUsageElement
10741
+ # wrapper; previously silently dropped (part-embedded state
10742
+ # machines vanished from the tree, dump, boxes and sim).
10743
+ ctx = behav_elem.exhibitStateUsage()
10744
+ result = _make_exhibit_state_usage_dict(ctx, None)
10745
+ if result and result.get("name") == "PackageMember":
10746
+ inner = result.get("ownedRelatedElement", {})
10747
+ return inner
10748
+ return result
10653
10749
  elif hasattr(behav_elem, 'allocationUsage') and behav_elem.allocationUsage():
10654
10750
  # Phase 0: allocation usages inside a definition body.
10655
10751
  ctx = behav_elem.allocationUsage()
@@ -13136,6 +13232,11 @@ def _visit_usage_element_dict(usage_elem_ctx, prefix=None):
13136
13232
  if hasattr(behav_elem, 'stateUsage') and behav_elem.stateUsage():
13137
13233
  ctx = behav_elem.stateUsage()
13138
13234
  return _make_state_usage_dict(ctx, prefix)
13235
+ elif hasattr(behav_elem, 'exhibitStateUsage') and behav_elem.exhibitStateUsage():
13236
+ # ``exhibit state`` — same wrapper, StateUsage with
13237
+ # exhibit=True (previously dropped).
13238
+ ctx = behav_elem.exhibitStateUsage()
13239
+ return _make_exhibit_state_usage_dict(ctx, prefix)
13139
13240
  elif hasattr(behav_elem, 'performActionUsage') and behav_elem.performActionUsage():
13140
13241
  ctx = behav_elem.performActionUsage()
13141
13242
  return _make_nested_perform_action_usage_dict(ctx, None)
@@ -96,6 +96,28 @@ def _sqrt(x):
96
96
  return math.sqrt(x)
97
97
 
98
98
 
99
+ def _exp(x):
100
+ if isinstance(x, ureg.Quantity):
101
+ return math.exp(x.magnitude) * ureg.dimensionless
102
+ return math.exp(x)
103
+
104
+
105
+ def _ln(x):
106
+ if isinstance(x, ureg.Quantity):
107
+ return math.log(x.magnitude) * ureg.dimensionless
108
+ return math.log(x)
109
+
110
+
111
+ def _log(x, base=None):
112
+ if isinstance(x, ureg.Quantity):
113
+ x = x.magnitude
114
+ if base is None:
115
+ return math.log10(x) * ureg.dimensionless
116
+ if isinstance(base, ureg.Quantity):
117
+ base = base.magnitude
118
+ return math.log(x, base) * ureg.dimensionless
119
+
120
+
99
121
  def _floor(x):
100
122
  if isinstance(x, ureg.Quantity):
101
123
  return math.floor(x.magnitude) * x.units
@@ -110,6 +132,11 @@ def _ceil(x):
110
132
 
111
133
  _FUNCTIONS = {
112
134
  "sqrt": _sqrt,
135
+ "exp": _exp,
136
+ "ln": _ln,
137
+ "log": _log,
138
+ "log2": lambda x: _log(x, 2.0),
139
+ "log10": lambda x: _log(x, 10.0),
113
140
  "abs": abs,
114
141
  "min": min,
115
142
  "max": max,
@@ -1055,11 +1055,16 @@ class StateBodyItem:
1055
1055
  class StateUsage:
1056
1056
  # prefix=OccurrenceUsagePrefix StateUsageKeyword
1057
1057
  # declaration=ActionUsageDeclaration body=StateUsageBody
1058
+ # An ``exhibit state`` usage is the same node with exhibit=True; the
1059
+ # visitor emits exhibit on the StateUsage dict (v0.93.x — previously
1060
+ # ``exhibit state`` was dropped by the visitor entirely).
1058
1061
  def __init__(self, definition=None):
1059
1062
  self.prefix = None
1060
1063
  self.keyword = "state"
1064
+ self.exhibit = None
1061
1065
  if definition is not None:
1062
1066
  if valid_definition(definition, self.__class__.__name__):
1067
+ self.exhibit = definition.get("exhibit")
1063
1068
  if definition["prefix"] is not None:
1064
1069
  self.prefix = OccurrenceUsagePrefix(definition["prefix"])
1065
1070
  self.declaration = ActionUsageDeclaration(definition["declaration"])
@@ -1072,13 +1077,15 @@ class StateUsage:
1072
1077
  output = []
1073
1078
  if self.prefix is not None:
1074
1079
  output.append(self.prefix.dump())
1080
+ if self.exhibit:
1081
+ output.append("exhibit")
1075
1082
  output.append(self.keyword)
1076
1083
  output.append(self.declaration.dump())
1077
1084
  output.append(self.body.dump())
1078
1085
  return " ".join(output)
1079
1086
 
1080
1087
  def get_definition(self):
1081
- output = {"name": self.__class__.__name__, "prefix": None}
1088
+ output = {"name": self.__class__.__name__, "prefix": None, "exhibit": self.exhibit}
1082
1089
  if self.prefix is not None:
1083
1090
  output["prefix"] = self.prefix.get_definition()
1084
1091
  output["declaration"] = self.declaration.get_definition()