sysmlpy 0.80.0__tar.gz → 0.81.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 (159) hide show
  1. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/__init__.py +1 -1
  4. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/__main__.py +9 -2
  5. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/boxes_view.py +76 -0
  6. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/sim.py +191 -14
  7. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/LICENSE +0 -0
  8. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/README.md +0 -0
  9. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/README.md +0 -0
  10. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  11. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  12. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  13. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  14. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  15. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  16. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  17. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  18. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  19. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  20. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  21. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr_parser.py +0 -0
  22. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/antlr_visitor.py +0 -0
  23. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/definition.py +0 -0
  24. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/diff.py +0 -0
  25. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/evaluator.py +0 -0
  26. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  27. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  28. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  29. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/formatting.py +0 -0
  30. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  31. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  32. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  33. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  34. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  35. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  36. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  37. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  38. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  39. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  40. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  41. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  42. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  43. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  44. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  45. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  46. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/grammar/classes.py +0 -0
  47. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/interchange.py +0 -0
  48. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/LICENSE +0 -0
  49. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/README.md +0 -0
  50. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/__init__.py +0 -0
  51. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  52. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  53. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  54. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  55. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  56. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  57. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  58. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  59. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  60. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  61. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  62. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  63. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  64. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  65. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  66. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  67. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  68. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  69. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  70. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  71. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  72. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  73. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  74. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  75. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  76. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  77. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  78. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  79. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  80. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  81. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  82. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  83. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  84. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  85. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  86. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  87. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  88. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  89. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  90. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  91. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  92. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  93. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  94. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  95. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  96. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  97. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  98. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  99. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  100. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  101. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  102. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  103. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  104. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  105. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  106. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  107. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  108. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  109. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  110. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  111. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  112. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  113. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  114. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  115. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  116. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  117. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  118. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  119. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  120. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  121. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  122. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  123. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  124. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  125. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  126. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  127. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  128. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  129. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  130. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  131. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  132. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  133. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  134. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  135. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  136. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  137. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  138. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  139. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  140. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  141. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  142. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  143. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  144. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  145. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/lsp/__init__.py +0 -0
  146. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/lsp/__main__.py +0 -0
  147. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/lsp/protocol.py +0 -0
  148. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/lsp/server.py +0 -0
  149. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/lsp/stdio.py +0 -0
  150. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/navigate.py +0 -0
  151. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/plantuml.py +0 -0
  152. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/project.py +0 -0
  153. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/semantic.py +0 -0
  154. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/spreadsheet.py +0 -0
  155. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/store.py +0 -0
  156. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/traceability.py +0 -0
  157. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/us_customary_units.txt +0 -0
  158. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/usage.py +0 -0
  159. {sysmlpy-0.80.0 → sysmlpy-0.81.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.80.0
3
+ Version: 0.81.0
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: Jon R. Fox (mycr0ft)
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [project]
8
8
  name = "sysmlpy"
9
- version = "0.80.0"
9
+ version = "0.81.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -34,7 +34,7 @@ __all__ = [
34
34
  "render_state_transition_view_svg", "boxes_view",
35
35
  ]
36
36
  __author__ = "Jon Fox"
37
- __version__ = "0.80.0"
37
+ __version__ = "0.81.0"
38
38
 
39
39
  from sysmlpy.usage import (
40
40
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -567,10 +567,12 @@ def cmd_sim(args) -> int:
567
567
  name, _, raw = spec.partition("=")
568
568
  values[name.strip()] = _parse_eval_value(raw)
569
569
 
570
+ deep = bool(getattr(args, "deep_history", False))
570
571
  script = [t.strip() for t in (args.run or "").split(";") if t.strip()]
571
572
  try:
572
573
  from sysmlpy.sim import StateSimulator, SimulationError
573
- sim = StateSimulator(model, focus=args.focus, values=values)
574
+ sim = StateSimulator(model, focus=args.focus, values=values,
575
+ deep_history=deep)
574
576
  except (ImportError, SimulationError) as e:
575
577
  print(f"Simulation error: {e}", file=sys.stderr)
576
578
  return 2
@@ -582,7 +584,7 @@ def cmd_sim(args) -> int:
582
584
  print(f"{trigger}: {'fired' if fired else 'blocked'} "
583
585
  f"-> {sim.state!r}")
584
586
  return 0
585
- run_tui(model, focus=args.focus, values=values)
587
+ run_tui(model, focus=args.focus, values=values, deep_history=deep)
586
588
  return 0
587
589
 
588
590
 
@@ -967,6 +969,11 @@ def build_parser() -> argparse.ArgumentParser:
967
969
  "-l", "--library",
968
970
  help="Path to SysML v2 library files to use for parsing",
969
971
  )
972
+ p_sim.add_argument(
973
+ "--deep-history", action="store_true",
974
+ help="History pseudostates restore the deepest visited state "
975
+ "(default: one level, shallow)",
976
+ )
970
977
  p_sim.set_defaults(func=cmd_sim)
971
978
 
972
979
  # -- xlsx (v0.66.0, Goal 7) -------------------------------------------------
@@ -380,6 +380,44 @@ def _top_member(item, target):
380
380
  return None
381
381
 
382
382
 
383
+ def _pseudostate_kind(usage: dict) -> Optional[str]:
384
+ """Classify a usage inside a state body as a pseudostate marker.
385
+
386
+ Recognizes history pseudostates: ``state h : HistoryUsage;`` /
387
+ ``h : HistoryUsage;`` (typed) and — for bare *reference* usages
388
+ only, as a name convention — ``h;``/``history;`` (untyped).
389
+ Returns ``"history"`` or ``None``.
390
+ """
391
+ if not isinstance(usage, dict):
392
+ return None
393
+ decl = usage.get("declaration") or {}
394
+ is_state = usage.get("name") == "StateUsage"
395
+
396
+ def _hunt(x):
397
+ if isinstance(x, dict):
398
+ if x.get("name") == "QualifiedName" and \
399
+ isinstance(x.get("names"), list) and x["names"]:
400
+ qns.append(x["names"])
401
+ for v in x.values():
402
+ _hunt(v)
403
+ elif isinstance(x, list):
404
+ for v in x:
405
+ _hunt(v)
406
+
407
+ qns: list = []
408
+ _hunt(decl)
409
+ typed_history = any(ns and ns[-1] == "HistoryUsage" for ns in qns)
410
+ if typed_history:
411
+ return "history"
412
+ if is_state:
413
+ return None # a real state named h is a state, not a marker
414
+ fd = decl.get("declaration") or {}
415
+ name = (fd.get("identification") or {}).get("declaredName")
416
+ if name in ("history", "h"):
417
+ return "history"
418
+ return None
419
+
420
+
383
421
  def _state_declared_name(state_usage: dict) -> Optional[str]:
384
422
  """Extract the declaredName from a StateUsage dict."""
385
423
  decl = state_usage.get("declaration", {})
@@ -405,6 +443,7 @@ def _collect_state_body(items: list, prefix: str = "",
405
443
  "initial": <state name:str>|None,
406
444
  "transitions": [ {name, source, target, trigger, guard}, ... ],
407
445
  "composites": [ {name, items, ...}, ... ],
446
+ "pseudostates": [ {name, kind}, ... ],
408
447
  "entry": <action label str|None>,
409
448
  "do": <action label str|None>,
410
449
  "exit": <action label str|None>,
@@ -416,6 +455,7 @@ def _collect_state_body(items: list, prefix: str = "",
416
455
  "initial": None,
417
456
  "transitions": [],
418
457
  "composites": [],
458
+ "pseudostates": [],
419
459
  "entry": None, "do": None, "exit": None,
420
460
  }
421
461
 
@@ -483,6 +523,12 @@ def _collect_state_body(items: list, prefix: str = "",
483
523
  if isinstance(orel, dict) and orel.get("name") == "BehaviorUsageElement":
484
524
  su = orel.get("ownedRelationship", {})
485
525
  if isinstance(su, dict) and su.get("name") == "StateUsage":
526
+ if _pseudostate_kind(su):
527
+ sname = _state_declared_name(su)
528
+ if sname:
529
+ result["pseudostates"].append(
530
+ {"name": sname, "kind": "history"})
531
+ continue
486
532
  sname = _state_declared_name(su)
487
533
  if sname:
488
534
  sub_body = su.get("body", {})
@@ -506,9 +552,39 @@ def _collect_state_body(items: list, prefix: str = "",
506
552
  "entry": None, "do": None, "exit": None,
507
553
  "states": [], "initial": None,
508
554
  "transitions": [], "composites": [],
555
+ "pseudostates": [],
509
556
  })
510
557
  continue
511
558
 
559
+ # History / pseudostate markers as bare references in a state
560
+ # body (``h;``, ``history;``, ``h : HistoryUsage;``). They are
561
+ # not states; sim treats transitions targeting them as history
562
+ # re-entries.
563
+ ps_name, ps_kind = None, None
564
+ for member_name in ("NonOccurrenceUsageMember",
565
+ "OccurrenceUsageMember"):
566
+ pm = _top_member(item, member_name)
567
+ if pm is None:
568
+ continue
569
+ orel = pm.get("ownedRelatedElement")
570
+ orel_list = orel if isinstance(orel, list) else (
571
+ [orel] if isinstance(orel, dict) else [])
572
+ for oe in orel_list:
573
+ usage = (oe.get("ownedRelatedElement")
574
+ if isinstance(oe, dict) else None)
575
+ if isinstance(usage, dict):
576
+ kind = _pseudostate_kind(usage)
577
+ if kind:
578
+ ps_name, ps_kind = usage, kind
579
+ if ps_name is not None:
580
+ fd = ((ps_name.get("declaration") or {}).get("declaration")
581
+ or {})
582
+ nm = (fd.get("identification") or {}).get("declaredName")
583
+ if nm:
584
+ result["pseudostates"].append(
585
+ {"name": nm, "kind": ps_kind})
586
+ continue
587
+
512
588
  # If this item was a pure entry/do/exit member, we already
513
589
  # handled it above and there's nothing else to register.
514
590
  if entry_do_exit_handled:
@@ -44,9 +44,16 @@ Scope of this MVP (deliberate cuts, tracked in TODO.md):
44
44
  still flattened implicitly
45
45
  - one machine per simulator (``focus`` picks which); parallel regions
46
46
  — top-level or inside a composite — raise :class:`SimulationError`
47
- - effects are logged, not executed; assignment effects surface as
48
- ``target := value`` text — executing them would flow through
49
- :meth:`StateSimulator.set_value` and is a follow-up
47
+ - assignment effects (``do x := 5``) execute against the simulator's
48
+ values (:meth:`StateSimulator.set_value`), so guards evaluated later
49
+ see the new value; other effects (``do <action>``, ``send``) are
50
+ logged only
51
+ - history pseudostates (``state h : HistoryUsage;``/``h :
52
+ HistoryUsage;``, or ``h;``/``history;`` by name convention) are
53
+ honored: a transition targeting one re-enters the region's last
54
+ active substate. Deep history restores the deepest visited state
55
+ when ``deep_history=True`` is passed to :class:`StateSimulator` —
56
+ the language has no deep-history form, so it is a simulator option
50
57
  - completion transitions (no ``accept`` trigger) fire automatically on
51
58
  entering a state (run-to-completion), and manually via
52
59
  :meth:`StateSimulator.step`
@@ -189,6 +196,15 @@ class TransitionSpec(NamedTuple):
189
196
  guard: Optional[str]
190
197
  #: Effect action name (``do <action>``), or None.
191
198
  effect: Optional[str]
199
+ #: For transitions targeting a history pseudostate: the flat name
200
+ #: of the region whose history the target remembers (``""`` =
201
+ #: machine root). None for ordinary transitions.
202
+ history_region: Optional[str] = None
203
+
204
+
205
+ #: Assignment-effect shape: ``name := expression`` (SysML assignment
206
+ #: operator; the effect text from the collector renders exactly this).
207
+ _ASSIGNMENT_RE = re.compile(r"^\s*([\w.]+)\s*:=\s*(.+?)\s*$", re.S)
192
208
 
193
209
 
194
210
  def _mangle(name: str) -> str:
@@ -209,6 +225,14 @@ class MachineDescriptor(NamedTuple):
209
225
  #: excluded from simulation but surfaced for diagnostics (the
210
226
  #: validator turns these into UNRESOLVED_TRANSITION_ENDPOINT).
211
227
  skipped: Tuple[TransitionSpec, ...] = ()
228
+ #: History pseudostate markers: flat marker name -> flat name of
229
+ #: the region whose last active substate it remembers (``""`` =
230
+ #: machine root).
231
+ history_markers: Dict[str, str] = {}
232
+ #: Region flat name -> default entry (initial substate leaf);
233
+ #: includes ``""`` -> machine initial. Fallback when no history
234
+ #: has been recorded yet.
235
+ region_defaults: Dict[str, str] = {}
212
236
 
213
237
 
214
238
  def build_state_machine(model, focus: Optional[str] = None,
@@ -261,6 +285,11 @@ def build_state_machine(model, focus: Optional[str] = None,
261
285
  # - a region declaring parallel raises (MVP cut).
262
286
  states: List[str] = []
263
287
  raw: List[dict] = []
288
+ # history pseudostate markers: flat marker name -> region flat name
289
+ markers_flat: Dict[str, str] = {}
290
+ # region flat name -> default entry (filled during expansion; the
291
+ # machine root is filled after the initial-state resolution below)
292
+ region_defaults_flat: Dict[str, str] = {}
264
293
 
265
294
  def _expand_region(level, prefix, all_names):
266
295
  local_flat: Dict[str, str] = {}
@@ -298,6 +327,7 @@ def build_state_machine(model, focus: Optional[str] = None,
298
327
  substates_of[nm] = [flat]
299
328
  continue
300
329
  entry_of[nm] = entry
330
+ region_defaults_flat[prefix + nm] = entry
301
331
  substates_of[nm] = (list(inner_flat.values()) +
302
332
  list(inner_entry.values()))
303
333
  else:
@@ -308,6 +338,20 @@ def build_state_machine(model, focus: Optional[str] = None,
308
338
  all_names.setdefault(nm, local_flat.get(nm)
309
339
  or entry_of.get(nm) or flat)
310
340
 
341
+ for ps in level.get("pseudostates", []) or []:
342
+ nm = ps.get("name") if isinstance(ps, dict) else ps
343
+ if not nm:
344
+ continue
345
+ flat = prefix + nm
346
+ region_flat = prefix[:-1] if prefix else ""
347
+ if nm in local_flat or nm in entry_of:
348
+ notes.append(
349
+ f"pseudostate {flat!r} shadows a state of the same "
350
+ "name; treating it as a state")
351
+ continue
352
+ markers_flat[flat] = region_flat
353
+ all_names.setdefault(nm, flat)
354
+
311
355
  for t in level.get("transitions", []):
312
356
  src, tgt = t.get("source"), t.get("target")
313
357
  if src in substates_of and src not in local_flat:
@@ -357,6 +401,28 @@ def build_state_machine(model, focus: Optional[str] = None,
357
401
  # substate) resolve to the qualified flat name
358
402
  source = all_names.get(source, source)
359
403
  target = all_names.get(target, target)
404
+ if target in markers_flat:
405
+ # history target: the transition re-enters the region's
406
+ # last active substate at fire time; the static dest is
407
+ # the region's default entry (used before any history)
408
+ region_flat = markers_flat[target]
409
+ dest = region_defaults_flat.get(region_flat)
410
+ if dest is None or dest not in states:
411
+ notes.append(
412
+ f"transition {t.get('name')!r} skipped: history "
413
+ f"region {region_flat or '(machine)'!r} has no "
414
+ "default entry to fall back to")
415
+ skipped.append(TransitionSpec(
416
+ name=t.get("name"), source=source, target=target,
417
+ trigger=t.get("trigger"), guard=t.get("guard"),
418
+ effect=t.get("effect"),
419
+ history_region=region_flat))
420
+ continue
421
+ transitions.append(TransitionSpec(
422
+ name=t.get("name"), source=source, target=dest,
423
+ trigger=t.get("trigger"), guard=t.get("guard"),
424
+ effect=t.get("effect"), history_region=region_flat))
425
+ continue
360
426
  if source not in states or target not in states:
361
427
  notes.append(
362
428
  f"transition {t.get('name')!r} skipped: endpoint(s) "
@@ -389,9 +455,12 @@ def build_state_machine(model, focus: Optional[str] = None,
389
455
  f"no entry transition in the model; starting in "
390
456
  f"{fallback!r} (the first declared state)")
391
457
  initial = fallback
458
+ region_defaults_flat[""] = initial
392
459
  return MachineDescriptor(name=sm.get("name"), states=states,
393
460
  initial=initial, transitions=transitions,
394
- notes=notes, skipped=tuple(skipped))
461
+ notes=notes, skipped=tuple(skipped),
462
+ history_markers=markers_flat,
463
+ region_defaults=region_defaults_flat)
395
464
 
396
465
 
397
466
  def load_model_grammar(model) -> dict:
@@ -422,7 +491,8 @@ class StepRecord:
422
491
  def __init__(self, from_state: str, trigger: Optional[str],
423
492
  guard: Optional[str], guard_ok: Optional[bool],
424
493
  to_state: Optional[str], effects: List[str],
425
- fired: bool, note: str = ""):
494
+ fired: bool, note: str = "",
495
+ assignments: Tuple[Tuple[str, Any], ...] = ()):
426
496
  self.from_state = from_state
427
497
  self.trigger = trigger
428
498
  self.guard = guard
@@ -431,13 +501,19 @@ class StepRecord:
431
501
  self.effects = effects
432
502
  self.fired = fired
433
503
  self.note = note
504
+ #: (name, value) pairs applied by ``do x := <expr>`` effects.
505
+ self.assignments = tuple(assignments)
434
506
  self.timestamp = time.time()
435
507
 
436
508
  def __repr__(self):
437
509
  arrow = "->" if self.fired else "-x"
438
510
  trig = self.trigger or "(completion)"
439
- return (f"<{arrow} {self.from_state!r} --{trig}"
440
- f"[{self.guard}]--> {self.to_state!r}>")
511
+ out = (f"<{arrow} {self.from_state!r} --{trig}"
512
+ f"[{self.guard}]--> {self.to_state!r}>")
513
+ if self.assignments:
514
+ assign = ", ".join(f"{n} := {v!r}" for n, v in self.assignments)
515
+ out += f" {assign}"
516
+ return out
441
517
 
442
518
 
443
519
  def _make_host(sim: "StateSimulator", n_guards: int, n_effects: int):
@@ -480,10 +556,14 @@ class StateSimulator:
480
556
  """
481
557
 
482
558
  def __init__(self, model, focus: Optional[str] = None,
483
- values: Optional[Dict[str, Any]] = None):
559
+ values: Optional[Dict[str, Any]] = None,
560
+ deep_history: bool = False):
484
561
  self.model = model
485
562
  self.descriptor = build_state_machine(model, focus=focus)
486
563
  self.notes = list(self.descriptor.notes)
564
+ #: When True, history pseudostates restore the deepest visited
565
+ #: state; by default (False) they restore one level (shallow).
566
+ self.deep_history = bool(deep_history)
487
567
  #: name -> value; guards evaluate against these (overrides on
488
568
  #: top of the model's collected attribute values).
489
569
  self.values: Dict[str, Any] = dict(values or {})
@@ -494,10 +574,66 @@ class StateSimulator:
494
574
  pass
495
575
  self.log: List[StepRecord] = []
496
576
  self._pending_effects: List[str] = []
577
+ self._pending_assignments: List[Tuple[str, Any]] = []
578
+ #: region flat name -> last active direct substate of that
579
+ #: region ("" = machine root)
580
+ self._history: Dict[str, str] = {}
497
581
  self._host = _make_host(
498
582
  self, len(self.descriptor.transitions),
499
583
  len(self.descriptor.transitions))
500
584
  self._build()
585
+ self._record_history(self.state)
586
+
587
+ # -- history ------------------------------------------------------------
588
+
589
+ def _record_history(self, state: str):
590
+ """Remember the active direct substate of every enclosing region.
591
+
592
+ For state ``C.Inner.Deep.S`` this records ``"" -> C``,
593
+ ``C -> C.Inner``, ``C.Inner -> C.Inner.Deep`` and
594
+ ``C.Inner.Deep -> C.Inner.Deep.S`` — i.e. each region maps to
595
+ its direct active child, which is what shallow history resumes;
596
+ deep history follows the chain down.
597
+ """
598
+ if not state:
599
+ return
600
+ parts = state.split(".")
601
+ for i in range(len(parts)):
602
+ self._history[".".join(parts[:i])] = ".".join(parts[:i + 1])
603
+
604
+ def _resolve_history(self, region_flat: str) -> Optional[str]:
605
+ """State to resume when re-entering *region_flat* via history."""
606
+ rd = self.descriptor.region_defaults
607
+ default = rd.get(region_flat) or self.descriptor.initial
608
+ s = self._history.get(region_flat)
609
+ if s is None:
610
+ return default
611
+ if not self.deep_history:
612
+ # shallow: the recorded direct child; if it is a composite,
613
+ # enter at its initial substate
614
+ if s in self.descriptor.states:
615
+ return s
616
+ return rd.get(s) or default
617
+ seen = set()
618
+ while (s is not None and s not in self.descriptor.states
619
+ and s not in seen):
620
+ seen.add(s)
621
+ s = self._history.get(s) or rd.get(s)
622
+ return s or default
623
+
624
+ def _apply_history(self, t: TransitionSpec) -> str:
625
+ """Post-fire state adjustment for history-targeting transitions.
626
+
627
+ pytransitions needs a concrete ``dest`` per transition, so
628
+ history transitions are defined to the region's default entry
629
+ and the actual (recorded) state is applied right after firing.
630
+ """
631
+ if t.history_region is None:
632
+ return t.target
633
+ resolved = self._resolve_history(t.history_region)
634
+ if resolved and resolved != self.state:
635
+ self._host.state = resolved
636
+ return resolved or t.target
501
637
 
502
638
  # -- construction -------------------------------------------------------
503
639
 
@@ -591,16 +727,27 @@ class StateSimulator:
591
727
  self, len(self.descriptor.transitions),
592
728
  len(self.descriptor.transitions))
593
729
  self._build()
730
+ self._history.clear()
731
+ self._record_history(self.state)
594
732
 
595
733
  def _fire(self, index: int) -> bool:
596
734
  t = self.descriptor.transitions[index]
597
735
  self._pending_effects.clear()
736
+ self._pending_assignments.clear()
598
737
  fired = bool(getattr(self._host, f"fire_{index}")())
599
738
  if fired:
739
+ to_state = self._apply_history(t)
740
+ self._record_history(self.state)
741
+ note = ""
742
+ if t.history_region is not None and to_state != t.target:
743
+ note = (f"history: resumed {to_state!r} in region "
744
+ f"{t.history_region or '(machine)'!r}")
600
745
  self.log.append(StepRecord(
601
- t.source, t.trigger, t.guard, True, t.target,
602
- list(self._pending_effects), True))
746
+ t.source, t.trigger, t.guard, True, to_state,
747
+ list(self._pending_effects), True, note,
748
+ assignments=tuple(self._pending_assignments)))
603
749
  self._pending_effects.clear()
750
+ self._pending_assignments.clear()
604
751
  self._run_completion()
605
752
  return True
606
753
  self.log.append(StepRecord(
@@ -617,11 +764,22 @@ class StateSimulator:
617
764
  if t.source == current and t.trigger is None:
618
765
  if self._eval_guard(i):
619
766
  self._pending_effects.clear()
767
+ self._pending_assignments.clear()
620
768
  getattr(self._host, f"fire_{i}")()
769
+ to_state = self._apply_history(t)
770
+ self._record_history(self.state)
771
+ note = ""
772
+ if t.history_region is not None \
773
+ and to_state != t.target:
774
+ note = (f"history: resumed {to_state!r} "
775
+ f"in region "
776
+ f"{t.history_region or '(machine)'!r}")
621
777
  self.log.append(StepRecord(
622
- t.source, None, t.guard, True, t.target,
623
- list(self._pending_effects), True))
778
+ t.source, None, t.guard, True, to_state,
779
+ list(self._pending_effects), True, note,
780
+ assignments=tuple(self._pending_assignments)))
624
781
  self._pending_effects.clear()
782
+ self._pending_assignments.clear()
625
783
  fired_any = True
626
784
  break
627
785
  if not fired_any:
@@ -672,8 +830,25 @@ class StateSimulator:
672
830
 
673
831
  def _do_effect(self, index: int):
674
832
  effect = self.descriptor.transitions[index].effect
675
- if effect:
833
+ if not effect:
834
+ return
835
+ m = _ASSIGNMENT_RE.match(effect)
836
+ if m:
837
+ # Assignment effect (``do x := <expr>``): evaluate and
838
+ # apply through set_value so later guards see the result.
839
+ name, expr = m.group(1), m.group(2)
840
+ try:
841
+ value = evaluate_expression(
842
+ expr, model=self.model, bindings=self.values)
843
+ except EvaluationError as e:
844
+ self._pending_effects.append(
845
+ f"{effect} (not evaluated: {e})")
846
+ return
847
+ self.set_value(name, value)
848
+ self._pending_assignments.append((name, value))
676
849
  self._pending_effects.append(effect)
850
+ return
851
+ self._pending_effects.append(effect)
677
852
 
678
853
 
679
854
  # ---------------------------------------------------------------------------
@@ -704,6 +879,7 @@ def _render(sim: StateSimulator) -> str:
704
879
 
705
880
  def run_tui(model, focus: Optional[str] = None,
706
881
  values: Optional[Dict[str, Any]] = None,
882
+ deep_history: bool = False,
707
883
  input_func=input, output=print) -> Optional[StateSimulator]:
708
884
  """Interactive simulate-test loop; returns the simulator on exit.
709
885
 
@@ -712,7 +888,8 @@ def run_tui(model, focus: Optional[str] = None,
712
888
  prints one snapshot and returns instead of looping.
713
889
  """
714
890
  try:
715
- sim = StateSimulator(model, focus=focus, values=values)
891
+ sim = StateSimulator(model, focus=focus, values=values,
892
+ deep_history=deep_history)
716
893
  except SimulationError as e:
717
894
  output(f"simulation: {e}")
718
895
  return None
File without changes
File without changes
File without changes
File without changes
File without changes