sysmlpy 0.61.0__tar.gz → 0.62.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 (149) hide show
  1. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/__init__.py +7 -1
  4. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/__main__.py +68 -1
  5. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr_visitor.py +242 -12
  6. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/definition.py +16 -0
  7. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/classes.py +85 -1
  8. sysmlpy-0.62.0/src/sysmlpy/traceability.py +441 -0
  9. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/usage.py +85 -1
  10. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/LICENSE +0 -0
  11. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/README.md +0 -0
  12. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/README.md +0 -0
  13. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  14. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  15. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  16. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  17. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  18. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  19. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  20. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  21. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  22. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  23. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  24. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/antlr_parser.py +0 -0
  25. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/boxes_view.py +0 -0
  26. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  27. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  28. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  29. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/formatting.py +0 -0
  30. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  31. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  32. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  33. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  34. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  35. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  36. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  37. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  38. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  39. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  40. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  41. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  42. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  43. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  44. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  45. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  46. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/LICENSE +0 -0
  47. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/README.md +0 -0
  48. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/__init__.py +0 -0
  49. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  50. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  51. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  52. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  53. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  54. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  55. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  56. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  57. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  58. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  59. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  60. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  61. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  62. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  63. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  64. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  65. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  66. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  67. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  68. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  69. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  70. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  71. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  72. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  73. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  74. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  75. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  76. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  77. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  78. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  79. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  80. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  81. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  82. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  83. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  84. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  85. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  86. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  87. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  88. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  89. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  90. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  91. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  92. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  93. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  94. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  95. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  96. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  97. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  98. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  99. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  100. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  101. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  102. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  103. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  104. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  105. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  106. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  107. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  108. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  109. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  110. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  111. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  112. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  113. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  114. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  115. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  116. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  117. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  118. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  119. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  120. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  121. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  122. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  123. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  124. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  125. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  126. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  127. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  128. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  129. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  130. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  131. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  132. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  133. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  134. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  135. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  136. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  137. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  138. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  139. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  140. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  141. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  142. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  143. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/navigate.py +0 -0
  144. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/plantuml.py +0 -0
  145. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/project.py +0 -0
  146. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/semantic.py +0 -0
  147. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/store.py +0 -0
  148. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/us_customary_units.txt +0 -0
  149. {sysmlpy-0.61.0 → sysmlpy-0.62.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.61.0
3
+ Version: 0.62.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.61.0"
9
+ version = "0.62.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -16,7 +16,9 @@ __all__ = [
16
16
  "as_action_flow_view", "as_interconnection_view", "as_state_transition_view",
17
17
  "as_general_view", "as_package_view",
18
18
  "as_tabular_view", "as_data_value_tabular_view", "as_relationship_matrix_view",
19
+ "as_traceability_matrix_view",
19
20
  "as_sequence_view", "as_case_view", "as_browser_view",
21
+ "extract_traceability", "TraceabilityReport", "RequirementTrace",
20
22
  "analyze", "AnalysisResult", "SemanticIssue", "SemanticAnalyzer",
21
23
  "SysMLSyntaxError", "PartialParseError",
22
24
  "loads_partial", "load_partial",
@@ -25,7 +27,7 @@ __all__ = [
25
27
  "render_state_transition_view_svg", "boxes_view",
26
28
  ]
27
29
  __author__ = "Jon Fox"
28
- __version__ = "0.61.0"
30
+ __version__ = "0.62.0"
29
31
 
30
32
  from sysmlpy.usage import (
31
33
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -41,6 +43,10 @@ from sysmlpy.store import Store, InMemoryStore, NetworkXStore, KuzuStore, Cayley
41
43
 
42
44
  from sysmlpy.usage import ureg
43
45
  from sysmlpy.antlr_parser import SysMLSyntaxError
46
+ from sysmlpy.traceability import (
47
+ extract_traceability, TraceabilityReport, RequirementTrace,
48
+ as_traceability_matrix_view,
49
+ )
44
50
 
45
51
 
46
52
  class PartialParseError(Exception):
@@ -31,7 +31,7 @@ import sysmlpy
31
31
  from sysmlpy import loads
32
32
 
33
33
  # Subcommand table, also used to detect the legacy flat invocation form.
34
- SUBCOMMANDS = ("parse", "analyze", "view", "format", "fmt")
34
+ SUBCOMMANDS = ("parse", "analyze", "view", "trace", "format", "fmt")
35
35
 
36
36
 
37
37
  # ---------------------------------------------------------------------------
@@ -277,6 +277,46 @@ def cmd_format(args) -> int:
277
277
  return exit_code
278
278
 
279
279
 
280
+ def cmd_trace(args) -> int:
281
+ """Requirement traceability & verification coverage (v0.62.0, Goal 2)."""
282
+ from sysmlpy.traceability import extract_traceability
283
+
284
+ paths = [Path(f) for f in args.files]
285
+ for p in _missing_files(paths):
286
+ print(f"Error: File '{p}' not found.", file=sys.stderr)
287
+ return 2
288
+
289
+ try:
290
+ model = sysmlpy.load_files(paths, library=args.library)
291
+ except Exception as e:
292
+ print(f"Parse error: {e}", file=sys.stderr)
293
+ return 2
294
+
295
+ report = extract_traceability(model)
296
+
297
+ if args.format == "json":
298
+ output = json.dumps(report.to_json(), indent=2)
299
+ elif args.format == "markdown":
300
+ output = report.to_markdown()
301
+ else:
302
+ output = report.to_text()
303
+
304
+ if args.output:
305
+ Path(args.output).write_text(output + "\n", encoding="utf-8")
306
+ print(f"Wrote {args.output}")
307
+ else:
308
+ print(output)
309
+
310
+ if args.fail_on == "uncovered" and report.uncovered():
311
+ for trace in report.uncovered():
312
+ print(
313
+ f"uncovered: {trace.qualified_name or trace.name}",
314
+ file=sys.stderr,
315
+ )
316
+ return 1
317
+ return 0
318
+
319
+
280
320
  # ---------------------------------------------------------------------------
281
321
  # legacy flat invocation (kept for backward compatibility)
282
322
  # ---------------------------------------------------------------------------
@@ -474,6 +514,33 @@ def build_parser() -> argparse.ArgumentParser:
474
514
  )
475
515
  p_format.set_defaults(func=cmd_format)
476
516
 
517
+ p_trace = sub.add_parser(
518
+ "trace",
519
+ help="Requirement traceability \u0026 verification coverage report",
520
+ description="Load the files as one merged model, extract satisfy "
521
+ "and verify relationships, and report requirement "
522
+ "coverage. Exit codes: 0 clean, 1 uncovered "
523
+ "requirements (--fail-on uncovered), 2 parse error.",
524
+ )
525
+ p_trace.add_argument("files", nargs="+", help="SysML v2 file(s)")
526
+ p_trace.add_argument(
527
+ "--format", choices=("text", "markdown", "json"), default="text",
528
+ help="Report format (default: text)",
529
+ )
530
+ p_trace.add_argument(
531
+ "--fail-on", choices=("uncovered", "none"), default="none",
532
+ help="Exit 1 when uncovered requirements exist (default: none)",
533
+ )
534
+ p_trace.add_argument(
535
+ "-o", "--output",
536
+ help="Write the report to a file instead of stdout",
537
+ )
538
+ p_trace.add_argument(
539
+ "-l", "--library",
540
+ help="Path to SysML v2 library files to use for parsing",
541
+ )
542
+ p_trace.set_defaults(func=cmd_trace)
543
+
477
544
  return parser
478
545
 
479
546
 
@@ -2311,6 +2311,8 @@ def _visit_behavior_usage_member(bum_ctx):
2311
2311
  return _make_assert_constraint_usage_dict(bue.assertConstraintUsage(), prefix)
2312
2312
  elif hasattr(bue, 'satisfyRequirementUsage') and bue.satisfyRequirementUsage():
2313
2313
  return _make_satisfy_requirement_usage_dict(bue.satisfyRequirementUsage(), prefix)
2314
+ elif hasattr(bue, 'verificationCaseUsage') and bue.verificationCaseUsage():
2315
+ return _make_nested_verification_case_usage_dict(bue.verificationCaseUsage(), prefix)
2314
2316
 
2315
2317
  return None
2316
2318
 
@@ -7850,12 +7852,10 @@ def _make_verification_case_definition_dict(ctx, member_prefix=None):
7850
7852
  """
7851
7853
  name, shortname = _get_definition_identification(ctx)
7852
7854
  occ_prefix = _get_occurrence_definition_prefix(ctx)
7853
- # Get body items from definition body
7854
- body_items = []
7855
- if hasattr(ctx, "definition") and ctx.definition():
7856
- defn = ctx.definition()
7857
- if hasattr(defn, "definitionBody") and defn.definitionBody():
7858
- body_items = _visit_definition_body_dict(defn.definitionBody())
7855
+ # Parse caseBody (subject members, action bodies, etc.) — v0.62.0
7856
+ case_body = {"name": "CaseBody", "item": [], "ownedRelationship": None}
7857
+ if hasattr(ctx, "caseBody") and ctx.caseBody():
7858
+ case_body = _visit_case_body_dict(ctx.caseBody())
7859
7859
  if not name and not shortname:
7860
7860
  name = "VerificationCase_" + str(uuid.uuid4())[:8]
7861
7861
  return {
@@ -7875,11 +7875,7 @@ def _make_verification_case_definition_dict(ctx, member_prefix=None):
7875
7875
  },
7876
7876
  "subclassificationpart": _get_subclassification_part(ctx)
7877
7877
  },
7878
- "body": {
7879
- "name": "CaseBody",
7880
- "item": [],
7881
- "ownedRelationship": None
7882
- }
7878
+ "body": case_body
7883
7879
  }
7884
7880
  }
7885
7881
  }
@@ -9258,11 +9254,140 @@ def _visit_requirement_body_item_dict(item_ctx):
9258
9254
  # Check for actorMember (skip for now)
9259
9255
  # Check for stakeholderMember (skip for now)
9260
9256
  # Check for framedConcernMember (skip for now)
9261
- # Check for requirementVerificationMember (skip for now)
9257
+ # requirementVerificationMember (v0.62.0: requirement traceability)
9258
+ if hasattr(item_ctx, 'requirementVerificationMember') and item_ctx.requirementVerificationMember():
9259
+ rvm = item_ctx.requirementVerificationMember()
9260
+ if isinstance(rvm, list):
9261
+ rvm = rvm[0]
9262
+ verify_dict = _visit_requirement_verification_member_dict(rvm)
9263
+ if verify_dict:
9264
+ return {
9265
+ "name": "RequirementBodyItem",
9266
+ "ownedRelationship": verify_dict
9267
+ }
9262
9268
 
9263
9269
  return None
9264
9270
 
9265
9271
 
9272
+ def _visit_requirement_verification_member_dict(rvm_ctx):
9273
+ """Visit a requirementVerificationMember and return its member dict.
9274
+
9275
+ Grammar:
9276
+ requirementVerificationMember : memberPrefix VERIFY requirementVerificationUsage ;
9277
+ """
9278
+ if rvm_ctx is None:
9279
+ return None
9280
+
9281
+ prefix = None
9282
+ if hasattr(rvm_ctx, 'memberPrefix') and rvm_ctx.memberPrefix():
9283
+ mp = rvm_ctx.memberPrefix()
9284
+ if hasattr(mp, 'visibilityIndicator') and mp.visibilityIndicator():
9285
+ prefix = {
9286
+ "name": "MemberPrefix",
9287
+ "visibility": _visit_visibility_indicator_dict(mp.visibilityIndicator())
9288
+ }
9289
+
9290
+ vru = None
9291
+ if hasattr(rvm_ctx, 'requirementVerificationUsage') and rvm_ctx.requirementVerificationUsage():
9292
+ vru = rvm_ctx.requirementVerificationUsage()
9293
+ if isinstance(vru, list):
9294
+ vru = vru[0]
9295
+ usage = _make_verify_requirement_usage_dict(vru)
9296
+ if usage:
9297
+ return {
9298
+ "name": "RequirementVerificationMember",
9299
+ "prefix": prefix,
9300
+ "ownedRelatedElement": usage
9301
+ }
9302
+ return None
9303
+
9304
+
9305
+ def _make_verify_requirement_usage_dict(vru_ctx, prefix=None):
9306
+ """Create a VerifyRequirementUsage dictionary.
9307
+
9308
+ Grammar:
9309
+ requirementVerificationUsage
9310
+ : ownedReferenceSubsetting featureSpecialization* requirementBody
9311
+ | ( usageExtensionKeyword* REQUIREMENT | usageExtensionKeyword+ )
9312
+ constraintUsageDeclaration requirementBody
9313
+ ;
9314
+
9315
+ ``verify <ref>;`` references an existing verification case; the
9316
+ requirement-keyword form declares an inline verification usage.
9317
+ """
9318
+ if vru_ctx is None:
9319
+ return None
9320
+
9321
+ ors = None
9322
+ fsp = None
9323
+ declaration = None
9324
+
9325
+ if hasattr(vru_ctx, 'ownedReferenceSubsetting') and vru_ctx.ownedReferenceSubsetting():
9326
+ ors = _build_owned_reference_subsetting_dict(vru_ctx.ownedReferenceSubsetting())
9327
+ if hasattr(vru_ctx, 'featureSpecialization') and vru_ctx.featureSpecialization():
9328
+ fs_list = vru_ctx.featureSpecialization()
9329
+ if not isinstance(fs_list, list):
9330
+ fs_list = [fs_list]
9331
+ specs = []
9332
+ for fs_ctx in fs_list:
9333
+ spec = _build_full_specialization_from_fsp(fs_ctx)
9334
+ if spec is not None:
9335
+ specs.append(spec)
9336
+ if specs:
9337
+ fsp = specs
9338
+ elif hasattr(vru_ctx, 'constraintUsageDeclaration') and vru_ctx.constraintUsageDeclaration():
9339
+ cud = vru_ctx.constraintUsageDeclaration()
9340
+ name = None
9341
+ shortname = None
9342
+ if hasattr(cud, 'usageDeclaration') and cud.usageDeclaration():
9343
+ ud = cud.usageDeclaration()
9344
+ if hasattr(ud, 'identification') and ud.identification():
9345
+ ident = ud.identification()
9346
+ if hasattr(ident, 'name'):
9347
+ name_list = ident.name()
9348
+ if name_list and isinstance(name_list, list):
9349
+ if len(name_list) == 2:
9350
+ shortname = name_list[0].getText()
9351
+ name = name_list[1].getText()
9352
+ elif len(name_list) == 1:
9353
+ name_text = name_list[0].getText()
9354
+ name, shortname = _extract_name_shortname(name_text)
9355
+
9356
+ typed_by = _get_action_usage_typed_by(cud)
9357
+ if typed_by is None:
9358
+ typed_by = _get_action_usage_subsetted_by(cud)
9359
+
9360
+ specialization = _build_specialization(typed_by) if typed_by else None
9361
+ declaration = {
9362
+ "name": "UsageDeclaration",
9363
+ "declaration": {
9364
+ "name": "FeatureDeclaration",
9365
+ "identification": {
9366
+ "name": "Identification",
9367
+ "declaredShortName": shortname,
9368
+ "declaredName": name
9369
+ },
9370
+ "specialization": specialization
9371
+ }
9372
+ }
9373
+
9374
+ body_items = []
9375
+ if hasattr(vru_ctx, 'requirementBody') and vru_ctx.requirementBody():
9376
+ body_items = _visit_requirement_body_dict(vru_ctx.requirementBody())
9377
+
9378
+ return {
9379
+ "name": "VerifyRequirementUsage",
9380
+ "prefix": prefix,
9381
+ "ors": ors,
9382
+ "fsp": fsp,
9383
+ "declaration": declaration,
9384
+ "body": {
9385
+ "name": "RequirementBody",
9386
+ "item": body_items
9387
+ }
9388
+ }
9389
+
9390
+
9266
9391
  def _visit_subject_member_dict(sm_ctx):
9267
9392
  """Visit a subjectMember and return a SubjectMember dict.
9268
9393
 
@@ -10150,6 +10275,9 @@ def _visit_nested_occurrence_usage(occ_elem):
10150
10275
  }
10151
10276
  }
10152
10277
  return None
10278
+ elif hasattr(behav_elem, 'verificationCaseUsage') and behav_elem.verificationCaseUsage():
10279
+ ctx = behav_elem.verificationCaseUsage()
10280
+ return _make_nested_verification_case_usage_dict(ctx, None)
10153
10281
  elif hasattr(behav_elem, 'analysisCaseUsage') and behav_elem.analysisCaseUsage():
10154
10282
  ctx = behav_elem.analysisCaseUsage()
10155
10283
  return _make_nested_analysis_case_usage_dict(ctx, None)
@@ -13009,6 +13137,16 @@ def _visit_usage_element_dict(usage_elem_ctx, prefix=None):
13009
13137
  }
13010
13138
  }
13011
13139
  return result
13140
+ elif hasattr(behav_elem, 'verificationCaseUsage') and behav_elem.verificationCaseUsage():
13141
+ ctx = behav_elem.verificationCaseUsage()
13142
+ inner = _make_nested_verification_case_usage_dict(ctx, prefix)
13143
+ if inner:
13144
+ return {
13145
+ "name": "PackageMember",
13146
+ "prefix": None,
13147
+ "ownedRelatedElement": inner
13148
+ }
13149
+ return None
13012
13150
  elif hasattr(behav_elem, 'viewpointUsage') and behav_elem.viewpointUsage():
13013
13151
  ctx = behav_elem.viewpointUsage()
13014
13152
  return _make_viewpoint_usage_dict(ctx, prefix)
@@ -13018,6 +13156,9 @@ def _visit_usage_element_dict(usage_elem_ctx, prefix=None):
13018
13156
  elif hasattr(behav_elem, 'analysisCaseUsage') and behav_elem.analysisCaseUsage():
13019
13157
  ctx = behav_elem.analysisCaseUsage()
13020
13158
  return _make_nested_analysis_case_usage_dict(ctx, prefix)
13159
+ elif hasattr(behav_elem, 'verificationCaseUsage') and behav_elem.verificationCaseUsage():
13160
+ ctx = behav_elem.verificationCaseUsage()
13161
+ return _make_nested_verification_case_usage_dict(ctx, prefix)
13021
13162
  elif hasattr(behav_elem, 'caseUsage') and behav_elem.caseUsage():
13022
13163
  ctx = behav_elem.caseUsage()
13023
13164
  return _make_nested_case_usage_dict(ctx, prefix)
@@ -14159,6 +14300,95 @@ def _build_full_specialization_from_fsp(fsp):
14159
14300
  }
14160
14301
 
14161
14302
 
14303
+ def _make_nested_verification_case_usage_dict(ctx, prefix=None):
14304
+ """Create a VerificationCaseUsage dict for nested usage (v0.62.0).
14305
+
14306
+ Grammar:
14307
+ verificationCaseUsage : occurrenceUsagePrefix VERIFICATION
14308
+ constraintUsageDeclaration caseBody ;
14309
+
14310
+ Mirrors _make_nested_analysis_case_usage_dict; the emitted
14311
+ BehaviorUsageElement/VerificationCaseUsage pair is dispatched to the
14312
+ existing VerificationCaseUsage grammar class.
14313
+ """
14314
+ if ctx is None:
14315
+ return None
14316
+
14317
+ # Extract name and specialization from constraintUsageDeclaration
14318
+ name = None
14319
+ shortname = None
14320
+ specialization = None
14321
+
14322
+ if hasattr(ctx, 'constraintUsageDeclaration') and ctx.constraintUsageDeclaration():
14323
+ cud = ctx.constraintUsageDeclaration()
14324
+ if isinstance(cud, list):
14325
+ cud = cud[0] if cud else None
14326
+ if cud is not None and hasattr(cud, 'usageDeclaration') and cud.usageDeclaration():
14327
+ ud = cud.usageDeclaration()
14328
+ if isinstance(ud, list):
14329
+ ud = ud[0] if ud else None
14330
+ if ud is not None and hasattr(ud, 'identification') and ud.identification():
14331
+ ident = ud.identification()
14332
+ if isinstance(ident, list):
14333
+ ident = ident[0] if ident else None
14334
+ if ident is not None and hasattr(ident, 'name'):
14335
+ name_list = ident.name()
14336
+ if name_list and isinstance(name_list, list):
14337
+ if len(name_list) == 2:
14338
+ shortname = name_list[0].getText()
14339
+ name = name_list[1].getText()
14340
+ elif len(name_list) == 1:
14341
+ name_text = name_list[0].getText()
14342
+ name, shortname = _extract_name_shortname(name_text)
14343
+
14344
+ # Extract specialization (typing) from constraintUsageDeclaration
14345
+ typed_by = _get_action_usage_typed_by(cud)
14346
+ if typed_by:
14347
+ specialization = _build_specialization(typed_by)
14348
+
14349
+ occ_prefix = _get_occurrence_usage_prefix(ctx) if ctx else None
14350
+
14351
+ # Get body items from caseBody
14352
+ body_items = []
14353
+ if hasattr(ctx, 'caseBody') and ctx.caseBody():
14354
+ cb = ctx.caseBody()
14355
+ body_items = _visit_case_body_items(cb)
14356
+
14357
+ return {
14358
+ "name": "UsageElement",
14359
+ "ownedRelatedElement": {
14360
+ "name": "OccurrenceUsageElement",
14361
+ "ownedRelatedElement": {
14362
+ "name": "BehaviorUsageElement",
14363
+ "ownedRelationship": {
14364
+ "name": "VerificationCaseUsage",
14365
+ "prefix": occ_prefix or prefix,
14366
+ "declaration": {
14367
+ "name": "CalculationUsageDeclaration",
14368
+ "declaration": {
14369
+ "name": "UsageDeclaration",
14370
+ "declaration": {
14371
+ "name": "FeatureDeclaration",
14372
+ "identification": {
14373
+ "name": "Identification",
14374
+ "declaredShortName": shortname,
14375
+ "declaredName": name
14376
+ },
14377
+ "specialization": specialization
14378
+ }
14379
+ },
14380
+ "valuepart": None
14381
+ },
14382
+ "body": {
14383
+ "name": "CaseBody",
14384
+ "item": body_items
14385
+ }
14386
+ }
14387
+ }
14388
+ }
14389
+ }
14390
+
14391
+
14162
14392
  def _make_nested_analysis_case_usage_dict(ctx, prefix=None):
14163
14393
  """Create an AnalysisCaseUsage dict for nested usage."""
14164
14394
  if ctx is None:
@@ -1281,6 +1281,22 @@ class Package(Searchable):
1281
1281
  c.name = decl.identification.declaredName
1282
1282
  c.parent = self
1283
1283
  self.children.append(c)
1284
+ elif inner_class == "VerificationCaseUsage":
1285
+ # v0.62.0: `verification <name> : <Type>` usage at package
1286
+ # level (requirement traceability support).
1287
+ c = VerificationCase()
1288
+ c.grammar = inner_element
1289
+ if hasattr(inner_element, 'declaration') and inner_element.declaration:
1290
+ decl = inner_element.declaration
1291
+ # CalculationUsageDeclaration → UsageDeclaration →
1292
+ # FeatureDeclaration → Identification
1293
+ usage_decl = getattr(decl, 'declaration', None)
1294
+ if usage_decl := getattr(usage_decl, 'declaration', None) or usage_decl:
1295
+ feat_decl = usage_decl
1296
+ if hasattr(feat_decl, 'identification') and feat_decl.identification:
1297
+ c.name = feat_decl.identification.declaredName
1298
+ c.parent = self
1299
+ self.children.append(c)
1284
1300
  elif inner_class == "AnnotatingElement":
1285
1301
  wrapper = _GrammarAnnotationWrapper(inner_element)
1286
1302
  wrapper.parent = self
@@ -9650,9 +9650,93 @@ class CaseDefinition(_DeclaredDefinitionBase):
9650
9650
  body_class = CaseBody
9651
9651
 
9652
9652
 
9653
+ class VerifyRequirementUsage:
9654
+ # requirementVerificationUsage :
9655
+ # ownedReferenceSubsetting featureSpecialization* requirementBody
9656
+ # | ( usageExtensionKeyword* REQUIREMENT | usageExtensionKeyword+ )
9657
+ # constraintUsageDeclaration requirementBody
9658
+ # ;
9659
+ """A `verify <ref>` member inside a requirement body (v0.62.0).
9660
+
9661
+ Asserts that the referenced verification case verifies the owning
9662
+ requirement; the requirement-keyword form declares an inline
9663
+ verification usage.
9664
+ """
9665
+ def __init__(self, definition=None):
9666
+ self.keyword = "verify"
9667
+ self.ors = None
9668
+ self.fsp = []
9669
+ self.declaration = None
9670
+ self.body = RequirementBody(None)
9671
+ if definition is not None and valid_definition(definition, self.__class__.__name__):
9672
+ if definition.get("ors") is not None:
9673
+ self.ors = OwnedReferenceSubsetting(definition["ors"])
9674
+ for spec in (definition.get("fsp") or []):
9675
+ self.fsp.append(FeatureSpecializationPart(spec))
9676
+ if definition.get("declaration") is not None:
9677
+ decl_dict = definition["declaration"]
9678
+ if decl_dict.get("name") == "CalculationUsageDeclaration":
9679
+ # Already CUD-shaped (get_definition round-trip)
9680
+ self.declaration = CalculationUsageDeclaration(decl_dict)
9681
+ else:
9682
+ self.declaration = CalculationUsageDeclaration(
9683
+ {"name": "CalculationUsageDeclaration",
9684
+ "declaration": decl_dict,
9685
+ "valuepart": None}
9686
+ )
9687
+ if definition.get("body") is not None:
9688
+ self.body = RequirementBody(definition["body"])
9689
+
9690
+ def dump(self):
9691
+ output = [self.keyword]
9692
+ if self.ors is not None:
9693
+ output.append(self.ors.dump())
9694
+ for spec in self.fsp:
9695
+ output.append(spec.dump())
9696
+ elif self.declaration is not None:
9697
+ output.append("requirement")
9698
+ output.append(self.declaration.dump())
9699
+ output.append(self.body.dump())
9700
+ return " ".join(filter(None, output))
9701
+
9702
+ def get_definition(self):
9703
+ return {
9704
+ "name": self.__class__.__name__,
9705
+ "ors": self.ors.get_definition() if self.ors else None,
9706
+ "fsp": [spec.get_definition() for spec in self.fsp],
9707
+ "declaration": self.declaration.get_definition() if self.declaration else None,
9708
+ "body": self.body.get_definition() if hasattr(self.body, 'get_definition') else {"name": "RequirementBody", "item": []},
9709
+ }
9710
+
9711
+
9712
+ class RequirementVerificationMember:
9713
+ # RequirementVerificationMember :
9714
+ # prefix=MemberPrefix VERIFY requirementVerificationUsage
9715
+ # ;
9716
+ def __init__(self, definition=None):
9717
+ self.prefix = None
9718
+ self.child = None
9719
+ if definition is not None and valid_definition(definition, self.__class__.__name__):
9720
+ if definition.get("prefix") is not None:
9721
+ self.prefix = MemberPrefix(definition["prefix"])
9722
+ self.child = VerifyRequirementUsage(definition["ownedRelatedElement"])
9723
+
9724
+ def dump(self):
9725
+ if self.prefix is not None:
9726
+ return " ".join(filter(None, [self.prefix.dump(), self.child.dump()]))
9727
+ return self.child.dump()
9728
+
9729
+ def get_definition(self):
9730
+ return {
9731
+ "name": self.__class__.__name__,
9732
+ "prefix": self.prefix.get_definition() if self.prefix else None,
9733
+ "ownedRelatedElement": self.child.get_definition() if self.child else None,
9734
+ }
9735
+
9736
+
9653
9737
  class VerificationCaseDefinition(_DeclaredDefinitionBase):
9654
9738
  # verificationCaseDefinition : occurrenceDefinitionPrefix VERIFICATION DEF definitionDeclaration caseBody
9655
- keyword = "verification case def"
9739
+ keyword = "verification def"
9656
9740
  body_class = CaseBody
9657
9741
 
9658
9742