sysmlpy 0.80.0__tar.gz → 0.82.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 (160) hide show
  1. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/__init__.py +2 -2
  4. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/__main__.py +34 -2
  5. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/boxes_view.py +76 -0
  6. sysmlpy-0.82.0/src/sysmlpy/diff.py +541 -0
  7. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/sim.py +191 -14
  8. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/usage.py +9 -0
  9. sysmlpy-0.80.0/src/sysmlpy/diff.py +0 -280
  10. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/LICENSE +0 -0
  11. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/README.md +0 -0
  12. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/README.md +0 -0
  13. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  14. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  15. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  16. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  17. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  18. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  19. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  20. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  21. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  22. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  23. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  24. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr_parser.py +0 -0
  25. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/antlr_visitor.py +0 -0
  26. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/definition.py +0 -0
  27. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/evaluator.py +0 -0
  28. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  29. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  30. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  31. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/formatting.py +0 -0
  32. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  33. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  34. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  35. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  36. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  37. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  38. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  39. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  40. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  41. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  42. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  43. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  44. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  45. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  46. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  47. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  48. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/grammar/classes.py +0 -0
  49. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/interchange.py +0 -0
  50. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/LICENSE +0 -0
  51. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/README.md +0 -0
  52. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/__init__.py +0 -0
  53. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  54. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  55. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  56. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  57. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  58. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  59. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  60. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  61. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  62. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  63. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  64. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  65. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  66. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  67. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  68. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  69. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  70. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  71. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  72. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  73. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  74. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  75. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  76. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  77. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  78. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  79. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  80. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  81. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  82. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  83. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  84. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  85. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  86. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  87. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  88. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  89. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  90. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  91. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  92. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  93. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  94. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  95. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  96. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  97. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  98. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  99. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  100. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  101. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  102. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  103. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  104. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  105. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  106. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  107. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  108. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  109. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  110. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  111. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  112. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  113. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  114. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  115. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  116. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  117. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  118. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  119. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  120. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  121. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  122. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  123. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  124. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  125. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  126. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  127. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  128. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  129. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  130. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  131. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  132. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  133. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  134. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  135. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  136. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  137. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  138. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  139. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  140. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  141. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  142. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  143. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  144. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  145. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  146. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  147. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/lsp/__init__.py +0 -0
  148. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/lsp/__main__.py +0 -0
  149. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/lsp/protocol.py +0 -0
  150. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/lsp/server.py +0 -0
  151. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/lsp/stdio.py +0 -0
  152. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/navigate.py +0 -0
  153. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/plantuml.py +0 -0
  154. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/project.py +0 -0
  155. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/semantic.py +0 -0
  156. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/spreadsheet.py +0 -0
  157. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/store.py +0 -0
  158. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/traceability.py +0 -0
  159. {sysmlpy-0.80.0 → sysmlpy-0.82.0}/src/sysmlpy/us_customary_units.txt +0 -0
  160. {sysmlpy-0.80.0 → sysmlpy-0.82.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.82.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.82.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.82.0"
38
38
 
39
39
  from sysmlpy.usage import (
40
40
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -449,7 +449,7 @@ def __getattr__(name):
449
449
  globals()[name] = fn
450
450
  return fn
451
451
  if name in ("ModelDiff", "ElementChange", "FieldChange",
452
- "diff_models", "diff_files"):
452
+ "diff_models", "diff_files", "diff_state_machines"):
453
453
  from sysmlpy import diff as _diff
454
454
  fn = getattr(_diff, name)
455
455
  globals()[name] = fn
@@ -117,15 +117,25 @@ def cmd_diff(args) -> int:
117
117
  print(f"Parse error: {e}", file=sys.stderr)
118
118
  return 2
119
119
 
120
+ threshold = getattr(args, "threshold", None)
121
+ if threshold is not None and not 0 <= threshold <= 1:
122
+ print(f"Error: --threshold expects a fraction in 0..1, "
123
+ f"got {threshold}", file=sys.stderr)
124
+ return 2
125
+
120
126
  if args.format == "json":
121
127
  import json as _json
122
128
  print(_json.dumps({
123
129
  "summary": d.summary(),
130
+ "elements_old": d.elements_old,
131
+ "elements_new": d.elements_new,
132
+ "change_rate": round(d.change_rate, 6),
124
133
  "changes": [
125
134
  {
126
135
  "change": c.change,
127
136
  "kind": c.kind,
128
137
  "qualified_name": c.qualified_name,
138
+ "old_qualified_name": c.old_qualified_name,
129
139
  "fields": [
130
140
  {"field": fc.field, "old": fc.old,
131
141
  "new": fc.new} for fc in c.fields
@@ -139,6 +149,14 @@ def cmd_diff(args) -> int:
139
149
  else:
140
150
  print(d.as_text(), end="")
141
151
 
152
+ if threshold is not None:
153
+ rate = d.change_rate
154
+ failed = rate > threshold
155
+ print(f"change gate: {len(d.changes)} changes / "
156
+ f"{d.elements_old} elements = {rate:.2%}; threshold "
157
+ f"{threshold:.2%} -> {'FAIL' if failed else 'OK'}")
158
+ return 1 if failed else 0
159
+
142
160
  # CI-friendly: differences are findings
143
161
  return 1 if not d.is_empty() else 0
144
162
 
@@ -567,10 +585,12 @@ def cmd_sim(args) -> int:
567
585
  name, _, raw = spec.partition("=")
568
586
  values[name.strip()] = _parse_eval_value(raw)
569
587
 
588
+ deep = bool(getattr(args, "deep_history", False))
570
589
  script = [t.strip() for t in (args.run or "").split(";") if t.strip()]
571
590
  try:
572
591
  from sysmlpy.sim import StateSimulator, SimulationError
573
- sim = StateSimulator(model, focus=args.focus, values=values)
592
+ sim = StateSimulator(model, focus=args.focus, values=values,
593
+ deep_history=deep)
574
594
  except (ImportError, SimulationError) as e:
575
595
  print(f"Simulation error: {e}", file=sys.stderr)
576
596
  return 2
@@ -582,7 +602,7 @@ def cmd_sim(args) -> int:
582
602
  print(f"{trigger}: {'fired' if fired else 'blocked'} "
583
603
  f"-> {sim.state!r}")
584
604
  return 0
585
- run_tui(model, focus=args.focus, values=values)
605
+ run_tui(model, focus=args.focus, values=values, deep_history=deep)
586
606
  return 0
587
607
 
588
608
 
@@ -760,6 +780,13 @@ def build_parser() -> argparse.ArgumentParser:
760
780
  "--format", choices=("text", "markdown", "json"), default="text",
761
781
  help="Output format: text (default), markdown or JSON",
762
782
  )
783
+ p_diff.add_argument(
784
+ "--threshold", type=float, default=None, metavar="FRAC",
785
+ help="CI gate: exit 1 only when the change rate (changes / old "
786
+ "elements) exceeds FRAC (0..1); exit 0 under the gate "
787
+ "even when the models differ. Without this flag any "
788
+ "difference exits 1.",
789
+ )
763
790
  p_diff.set_defaults(func=cmd_diff)
764
791
 
765
792
  # -- view ----------------------------------------------------------------
@@ -967,6 +994,11 @@ def build_parser() -> argparse.ArgumentParser:
967
994
  "-l", "--library",
968
995
  help="Path to SysML v2 library files to use for parsing",
969
996
  )
997
+ p_sim.add_argument(
998
+ "--deep-history", action="store_true",
999
+ help="History pseudostates restore the deepest visited state "
1000
+ "(default: one level, shallow)",
1001
+ )
970
1002
  p_sim.set_defaults(func=cmd_sim)
971
1003
 
972
1004
  # -- 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: