sysmlpy 0.78.0__tar.gz → 0.79.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.78.0 → sysmlpy-0.79.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/__init__.py +1 -1
  4. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/definition.py +126 -0
  5. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/store.py +205 -0
  6. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/usage.py +50 -4
  7. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/LICENSE +0 -0
  8. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/README.md +0 -0
  9. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/__main__.py +0 -0
  10. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/README.md +0 -0
  11. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  12. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  13. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  14. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  15. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  16. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  17. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  18. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  19. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  20. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  21. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  22. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr_parser.py +0 -0
  23. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/antlr_visitor.py +0 -0
  24. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/boxes_view.py +0 -0
  25. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/diff.py +0 -0
  26. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/evaluator.py +0 -0
  27. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  28. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  29. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  30. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/formatting.py +0 -0
  31. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  32. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  33. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  34. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  35. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  36. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  37. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  38. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  39. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  40. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  41. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  42. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  43. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  44. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  45. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  46. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  47. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/grammar/classes.py +0 -0
  48. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/interchange.py +0 -0
  49. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/LICENSE +0 -0
  50. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/README.md +0 -0
  51. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/__init__.py +0 -0
  52. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  53. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  54. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  55. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  56. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  57. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  58. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  59. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  60. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  61. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  62. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  63. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  64. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  65. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  66. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  67. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  68. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  69. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  70. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  71. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  72. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  73. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  74. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  75. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  76. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  77. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  78. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  79. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  80. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  81. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  82. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  83. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  84. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  85. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  86. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  87. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  88. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  89. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  90. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  91. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  92. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  93. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  94. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  95. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  96. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  97. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  98. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  99. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  100. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  101. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  102. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  103. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  104. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  105. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  106. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  107. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  108. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  109. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  110. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  111. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  112. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  113. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  114. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  115. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  116. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  117. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  118. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  119. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  120. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  121. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  122. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  123. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  124. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  125. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  126. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  127. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  128. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  129. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  130. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  131. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  132. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  133. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  134. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  135. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  136. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  137. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  138. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  139. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  140. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  141. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  142. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  143. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  144. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  145. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  146. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/lsp/__init__.py +0 -0
  147. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/lsp/__main__.py +0 -0
  148. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/lsp/protocol.py +0 -0
  149. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/lsp/server.py +0 -0
  150. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/lsp/stdio.py +0 -0
  151. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/navigate.py +0 -0
  152. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/plantuml.py +0 -0
  153. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/project.py +0 -0
  154. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/semantic.py +0 -0
  155. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/sim.py +0 -0
  156. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/spreadsheet.py +0 -0
  157. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/traceability.py +0 -0
  158. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/us_customary_units.txt +0 -0
  159. {sysmlpy-0.78.0 → sysmlpy-0.79.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.78.0
3
+ Version: 0.79.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.78.0"
9
+ version = "0.79.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.78.0"
37
+ __version__ = "0.79.0"
38
38
 
39
39
  from sysmlpy.usage import (
40
40
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -117,6 +117,7 @@ class Model(Searchable):
117
117
  p = Package().load_from_grammar(
118
118
  PackageGrammar(de["ownedRelatedElement"])
119
119
  )
120
+ p.parent = self
120
121
  self.children.append(p)
121
122
  member_grammar.append(p._get_definition(child="PackageBody"))
122
123
  elif found_package:
@@ -164,6 +165,7 @@ class Model(Searchable):
164
165
  p = Package().load_from_grammar(
165
166
  PackageGrammar(synthetic_definition)
166
167
  )
168
+ p.parent = self
167
169
  self.children.append(p)
168
170
  member_grammar.append(p._get_definition(child="PackageBody"))
169
171
  else:
@@ -429,6 +431,130 @@ class Model(Searchable):
429
431
  return path
430
432
  return None
431
433
 
434
+ def resolve_types(self) -> int:
435
+ """Resolve every usage's declared type name to its definition object.
436
+
437
+ ``loads()`` preserves the *declared type name* on usages
438
+ (``usage.typed_by_name``), but the resolved definition *object*
439
+ (``usage.typedby``) is only set when the model is wired
440
+ programmatically via ``set_type()`` / ``set_typed_by()``. This
441
+ pass closes that gap: it indexes every definition in the model
442
+ (by simple name and by ``::``-qualified namespace path) and
443
+ links each usage's typing to the matching definition object.
444
+
445
+ Returns
446
+ -------
447
+ int
448
+ The number of usages resolved by this call.
449
+
450
+ Notes
451
+ -----
452
+ - Library typings (e.g. ``ScalarValues::Real``) match no
453
+ definition in the model and are left untouched —
454
+ :func:`~sysmlpy.analyze` already reports those as unresolved.
455
+ - Names that resolve to no definition are left untouched.
456
+ - An ambiguous simple name (same definition name in several
457
+ packages) resolves to the definition in the usage's own
458
+ package when one exists, otherwise to the first definition
459
+ in document order.
460
+ - Resolution is idempotent: already-linked elements are
461
+ skipped, and a second call returns ``0``.
462
+ - ``Reference``-kind elements store the link in ``ref_type``
463
+ (mirroring ``set_type``); other usages store it in
464
+ ``typedby``. Serialization is unaffected either way —
465
+ ``dump()`` output is identical before and after resolution.
466
+ """
467
+ # ---- index definitions -------------------------------------
468
+ by_qualified = {} # "Pkg::Engine" -> definition
469
+ by_simple = {} # "Engine" -> [definitions in doc order]
470
+ pkg_paths = {} # id(package) -> qualified name parts
471
+
472
+ def _index(elem, path):
473
+ for child in getattr(elem, "children", []) or []:
474
+ name = getattr(child, "name", None)
475
+ is_package = getattr(child, "sysml_type", None) == "package"
476
+ is_definition = getattr(child, "is_definition", False)
477
+ if not (is_package or is_definition):
478
+ continue
479
+ if not name:
480
+ _index(child, path)
481
+ continue
482
+ child_path = path + [name]
483
+ by_qualified.setdefault("::".join(child_path), child)
484
+ by_simple.setdefault(name, []).append(child)
485
+ if is_package:
486
+ pkg_paths[id(child)] = child_path
487
+ _index(child, child_path)
488
+
489
+ _index(self, [])
490
+
491
+ def _lookup(type_name, packages):
492
+ """Resolve a declared type name to a definition.
493
+
494
+ Tries the name as an absolute qualified path first, then as
495
+ a path relative to each enclosing package (nearest first) —
496
+ ``Types::Wheel`` declared inside package ``Vehicle`` matches
497
+ ``Vehicle::Types::Wheel``.
498
+ """
499
+ if "::" in type_name:
500
+ hit = by_qualified.get(type_name)
501
+ if hit is not None:
502
+ return hit
503
+ parts = type_name.split("::")
504
+ for pkg in reversed(packages):
505
+ prefix = pkg_paths.get(id(pkg), [])
506
+ hit = by_qualified.get("::".join(prefix + parts))
507
+ if hit is not None:
508
+ return hit
509
+ return None
510
+ if "." in type_name:
511
+ # Feature-chain (dotted) names are not type paths.
512
+ return None
513
+ candidates = by_simple.get(type_name, [])
514
+ if len(candidates) == 1:
515
+ return candidates[0]
516
+ if len(candidates) > 1:
517
+ # Prefer the definition in the usage's own package
518
+ # (nearest enclosing scope), else first in doc order.
519
+ for pkg in reversed(packages):
520
+ for cand in candidates:
521
+ if getattr(cand, "parent", None) is pkg:
522
+ return cand
523
+ return candidates[0]
524
+ return None
525
+
526
+ # ---- link usages --------------------------------------------
527
+ resolved = 0
528
+
529
+ def _walk(elem, packages):
530
+ nonlocal resolved
531
+ for child in getattr(elem, "children", []) or []:
532
+ type_name = getattr(child, "_typed_by_name", None)
533
+ if type_name and not isinstance(type_name, str):
534
+ type_name = None
535
+ if type_name:
536
+ has_typedby = hasattr(child, "typedby")
537
+ has_ref = hasattr(child, "ref_type")
538
+ already = (
539
+ (has_typedby and child.typedby is not None)
540
+ or (has_ref and child.ref_type is not None)
541
+ )
542
+ if not already:
543
+ target = _lookup(type_name, packages)
544
+ if target is not None:
545
+ if has_ref:
546
+ child.ref_type = target
547
+ if has_typedby:
548
+ child.typedby = target
549
+ resolved += 1
550
+ child_packages = packages
551
+ if getattr(child, "sysml_type", None) == "package":
552
+ child_packages = packages + [child]
553
+ _walk(child, child_packages)
554
+
555
+ _walk(self, [])
556
+ return resolved
557
+
432
558
 
433
559
  class Package(Searchable):
434
560
  """SysML v2 Package. Exposes typed accessors and ``find()`` / ``all()``
@@ -2468,6 +2468,211 @@ class CayleyStore(Store):
2468
2468
  "avg_degree": (2 * e) / n if n > 0 else 0,
2469
2469
  }
2470
2470
 
2471
+ # ── Query extensions (parity with NetworkX/Kuzu) ────────────────────
2472
+ #
2473
+ # Cayley gizmo has no unbounded path enumeration or server-side
2474
+ # aggregation over predicates, so these run client-side over the
2475
+ # existing primitives (relationships/children/parents/ids). Results
2476
+ # match the NetworkX/Kuzu shapes; see tests/store_test.py
2477
+ # (TestCayleyQueryExtensions).
2478
+
2479
+ def all_paths(self, source_id: str, target_id: str,
2480
+ rel_type: Optional[str] = None,
2481
+ max_paths: int = 20) -> list[list[str]]:
2482
+ """Find up to *max_paths* simple paths between two elements.
2483
+
2484
+ Mirrors :meth:`NetworkXStore.all_paths`. Depth-first enumeration
2485
+ over relationship edges (any type when *rel_type* is None).
2486
+ """
2487
+ if not self.has(source_id) or not self.has(target_id):
2488
+ return []
2489
+ results: list[list[str]] = []
2490
+
2491
+ def _dfs(node: str, path: list[str]) -> None:
2492
+ if len(results) >= max_paths:
2493
+ return
2494
+ if node == target_id:
2495
+ results.append(list(path))
2496
+ return
2497
+ for nxt, _rt, _d in self.relationships(
2498
+ node, rel_type=rel_type, direction="out"):
2499
+ if nxt in path: # simple paths only
2500
+ continue
2501
+ path.append(nxt)
2502
+ _dfs(nxt, path)
2503
+ path.pop()
2504
+
2505
+ _dfs(source_id, [source_id])
2506
+ return results
2507
+
2508
+ def in_degree_centrality(self, rel_type: Optional[str] = None) -> dict[str, float]:
2509
+ """In-degree fraction per element (how many elements reference *me*).
2510
+
2511
+ Mirrors :meth:`NetworkXStore.in_degree_centrality` (degree divided
2512
+ by ``n - 1``).
2513
+ """
2514
+ n = len(self)
2515
+ if n <= 1:
2516
+ return {eid: 0.0 for eid in self.ids()}
2517
+ denom = n - 1
2518
+ return {
2519
+ eid: len(self.relationships(eid, rel_type=rel_type,
2520
+ direction="in")) / denom
2521
+ for eid in self.ids()
2522
+ }
2523
+
2524
+ def out_degree_centrality(self, rel_type: Optional[str] = None) -> dict[str, float]:
2525
+ """Out-degree fraction per element (how many elements *I* reference)."""
2526
+ n = len(self)
2527
+ if n <= 1:
2528
+ return {eid: 0.0 for eid in self.ids()}
2529
+ denom = n - 1
2530
+ return {
2531
+ eid: len(self.relationships(eid, rel_type=rel_type,
2532
+ direction="out")) / denom
2533
+ for eid in self.ids()
2534
+ }
2535
+
2536
+ def descendants_depth_limited(self, root_id: str, max_depth: int = 3,
2537
+ rel_type: str = REL_PARENT_CHILD) -> list[str]:
2538
+ """Descendants within *max_depth* levels of *root_id*.
2539
+
2540
+ Mirrors :meth:`NetworkXStore.descendants_depth_limited` —
2541
+ breadth-first, each level sorted for deterministic output.
2542
+ """
2543
+ if not self.has(root_id):
2544
+ return []
2545
+ result: list[str] = []
2546
+ frontier = {root_id}
2547
+ visited = {root_id}
2548
+ for _ in range(max_depth):
2549
+ nxt: set[str] = set()
2550
+ for node in frontier:
2551
+ for child in self.children(node, rel_type):
2552
+ if child not in visited:
2553
+ nxt.add(child)
2554
+ visited |= nxt
2555
+ result.extend(sorted(nxt))
2556
+ frontier = nxt
2557
+ if not frontier:
2558
+ break
2559
+ return result
2560
+
2561
+ def neighborhood(self, element_id: str, radius: int = 2,
2562
+ rel_type: Optional[str] = None) -> set[str]:
2563
+ """Ego-neighborhood of *element_id* within *radius* hops.
2564
+
2565
+ Follows edges in both directions (like NetworkX's undirected
2566
+ ego graph); includes the element itself.
2567
+ """
2568
+ if not self.has(element_id):
2569
+ return set()
2570
+ seen = {element_id}
2571
+ frontier = {element_id}
2572
+ for _ in range(radius):
2573
+ nxt: set[str] = set()
2574
+ for node in frontier:
2575
+ for other, _rt, _d in self.relationships(
2576
+ node, rel_type=rel_type, direction="both"):
2577
+ if other not in seen:
2578
+ nxt.add(other)
2579
+ seen |= nxt
2580
+ frontier = nxt
2581
+ if not frontier:
2582
+ break
2583
+ return seen
2584
+
2585
+ def impact_analysis(self, element_id: str,
2586
+ rel_types: Optional[list[str]] = None,
2587
+ direction: str = "downstream") -> set[str]:
2588
+ """Elements transitively affected by changes to *element_id*.
2589
+
2590
+ Mirrors :meth:`NetworkXStore.impact_analysis` — *downstream*
2591
+ follows outgoing edges (what I affect), *upstream* follows
2592
+ incoming edges (what affects me).
2593
+ """
2594
+ if not self.has(element_id):
2595
+ return set()
2596
+ dirn = "out" if direction == "downstream" else "in"
2597
+ seen = {element_id}
2598
+ frontier = [element_id]
2599
+ while frontier:
2600
+ current = frontier.pop()
2601
+ for other, rt, _d in self.relationships(current, direction=dirn):
2602
+ if rel_types and rt not in rel_types:
2603
+ continue
2604
+ if other not in seen:
2605
+ seen.add(other)
2606
+ frontier.append(other)
2607
+ seen.discard(element_id)
2608
+ return seen
2609
+
2610
+ def siblings(self, element_id: str) -> list[str]:
2611
+ """Elements sharing a structural parent with *element_id*.
2612
+
2613
+ Mirrors :meth:`KuzuStore.siblings` (parent-child edges only);
2614
+ deterministic parent-then-child order, self excluded.
2615
+ """
2616
+ result: list[str] = []
2617
+ for parent in self.parents(element_id):
2618
+ for sib in self.children(parent):
2619
+ if sib != element_id and sib not in result:
2620
+ result.append(sib)
2621
+ return result
2622
+
2623
+ def hub_elements(self, min_degree: int = 3,
2624
+ direction: str = "outgoing") -> list[tuple[str, int]]:
2625
+ """Elements with high relationship degree.
2626
+
2627
+ Mirrors :meth:`KuzuStore.hub_elements` — *(element_id, degree)*
2628
+ pairs with degree ≥ *min_degree*, sorted by degree descending.
2629
+ *direction* selects which edge direction to count.
2630
+ """
2631
+ dirn = {"outgoing": "out", "incoming": "in", "both": "both"}.get(direction)
2632
+ if dirn is None:
2633
+ raise ValueError(
2634
+ f"direction must be 'outgoing', 'incoming' or 'both', "
2635
+ f"got {direction!r}")
2636
+ counts: list[tuple[str, int]] = []
2637
+ for eid in self.ids():
2638
+ degree = len(self.relationships(eid, direction=dirn))
2639
+ if degree >= min_degree:
2640
+ counts.append((eid, degree))
2641
+ counts.sort(key=lambda kv: (-kv[1], kv[0]))
2642
+ return counts
2643
+
2644
+ def shortest_path_between_named(self, source_name: str, target_name: str,
2645
+ max_hops: int = 10) -> Optional[list[str]]:
2646
+ """Shortest structural path between two *named* elements.
2647
+
2648
+ Mirrors :meth:`KuzuStore.shortest_path_between_named` — BFS over
2649
+ all relationship types, one hop-level at a time up to *max_hops*;
2650
+ returns the ID path or ``None`` when disconnected. When several
2651
+ elements share a name, the first path reaching any target wins.
2652
+ """
2653
+ sources = self.query(name=source_name)
2654
+ targets = set(self.query(name=target_name))
2655
+ if not sources or not targets:
2656
+ return None
2657
+ # Multi-source BFS, one level per hop.
2658
+ frontier = {sid: [sid] for sid in sources}
2659
+ visited = set(sources)
2660
+ for _ in range(max_hops):
2661
+ nxt_frontier = {}
2662
+ for node, path in frontier.items():
2663
+ for other, _rt, _d in self.relationships(node, direction="out"):
2664
+ if other in visited:
2665
+ continue
2666
+ new_path = path + [other]
2667
+ if other in targets:
2668
+ return new_path
2669
+ visited.add(other)
2670
+ nxt_frontier[other] = new_path
2671
+ if not nxt_frontier:
2672
+ break
2673
+ frontier = nxt_frontier
2674
+ return None
2675
+
2471
2676
 
2472
2677
  # ── ID Generation ───────────────────────────────────────────────────────────
2473
2678
 
@@ -398,6 +398,44 @@ class Usage(Searchable):
398
398
  """
399
399
  return getattr(self, '_typed_by_name', None)
400
400
 
401
+ def _typedby_serialized_elsewhere(self):
402
+ """True when ``self.typedby`` is already a member of the model tree.
403
+
404
+ The ``_get_definition`` output inserts the typed-by definition
405
+ as a sibling member so that a *standalone* programmatic usage
406
+ (one wired via ``set_typed_by`` whose definition was never
407
+ added to a package) still serializes completely. When the
408
+ definition is already part of the enclosing tree — the case
409
+ for every parsed model, where ``resolve_types()`` fills in
410
+ ``typedby`` — the insertion would duplicate it (the definition
411
+ is serialized by its own package), so it must be skipped.
412
+
413
+ Walks up ``parent`` to the tree root, then searches the tree
414
+ excluding this element's own subtree. O(model size) per typed
415
+ usage; ``dump()`` is not a hot path.
416
+ """
417
+ target = self.typedby
418
+ if target is None:
419
+ return False
420
+ root = self
421
+ depth = 0
422
+ while getattr(root, "parent", None) is not None and depth < 1000:
423
+ root = root.parent
424
+ depth += 1
425
+ stack = [root]
426
+ while stack:
427
+ node = stack.pop()
428
+ for child in getattr(node, "children", []) or []:
429
+ if child is self:
430
+ # Don't descend into our own subtree: the question
431
+ # is whether the definition is serialized anywhere
432
+ # *else*.
433
+ continue
434
+ if child is target:
435
+ return True
436
+ stack.append(child)
437
+ return False
438
+
401
439
  def _get_definition(self, child=None):
402
440
  """Build the grammar tree dict for this element.
403
441
 
@@ -429,8 +467,12 @@ class Usage(Searchable):
429
467
  "prefix": None,
430
468
  }
431
469
 
432
- # Add the typed by definition to the package output
433
- if self.typedby is not None:
470
+ # Add the typed by definition to the package output — but only
471
+ # when it is not already part of the tree (a parsed model whose
472
+ # ``typedby`` was filled in by ``Model.resolve_types()`` already
473
+ # serializes the definition from its own package; inserting it
474
+ # again would duplicate it).
475
+ if self.typedby is not None and not self._typedby_serialized_elsewhere():
434
476
  if child is None:
435
477
  package["ownedRelationship"].insert(
436
478
  0, self.typedby._get_definition(child="PackageBody")
@@ -4552,8 +4594,12 @@ class DefaultReference(Usage):
4552
4594
  "prefix": None,
4553
4595
  }
4554
4596
 
4555
- # Add the typed by definition to the package output
4556
- if self.typedby is not None:
4597
+ # Add the typed by definition to the package output — but only
4598
+ # when it is not already part of the tree (a parsed model whose
4599
+ # ``typedby`` was filled in by ``Model.resolve_types()`` already
4600
+ # serializes the definition from its own package; inserting it
4601
+ # again would duplicate it).
4602
+ if self.typedby is not None and not self._typedby_serialized_elsewhere():
4557
4603
  if child is None:
4558
4604
  package["ownedRelationship"].insert(
4559
4605
  0, self.typedby._get_definition(child="PackageBody")
File without changes
File without changes
File without changes
File without changes