speclogician 0.0.0b1__py3-none-any.whl

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 (139) hide show
  1. speclogician/__init__.py +0 -0
  2. speclogician/commands/__init__.py +15 -0
  3. speclogician/commands/cmd_ch.py +616 -0
  4. speclogician/commands/cmd_find.py +256 -0
  5. speclogician/commands/cmd_view.py +202 -0
  6. speclogician/commands/runner.py +149 -0
  7. speclogician/commands/utils.py +101 -0
  8. speclogician/data/__init__.py +0 -0
  9. speclogician/data/artifact.py +63 -0
  10. speclogician/data/container.py +402 -0
  11. speclogician/data/mapping.py +88 -0
  12. speclogician/data/refs.py +24 -0
  13. speclogician/data/traces.py +26 -0
  14. speclogician/demos/.DS_Store +0 -0
  15. speclogician/demos/cmd_demo.py +278 -0
  16. speclogician/demos/loader.py +135 -0
  17. speclogician/demos/model.py +27 -0
  18. speclogician/demos/runner.py +51 -0
  19. speclogician/logic/__init__.py +11 -0
  20. speclogician/logic/api/__init__.py +29 -0
  21. speclogician/logic/api/client.py +606 -0
  22. speclogician/logic/api/decomp.py +67 -0
  23. speclogician/logic/api/scenario.py +102 -0
  24. speclogician/logic/api/traces.py +59 -0
  25. speclogician/logic/lib/__init__.py +19 -0
  26. speclogician/logic/lib/complement.py +107 -0
  27. speclogician/logic/lib/domain_model.py +59 -0
  28. speclogician/logic/lib/predicates.py +151 -0
  29. speclogician/logic/lib/scenarios.py +369 -0
  30. speclogician/logic/lib/traces.py +114 -0
  31. speclogician/logic/lib/transitions.py +104 -0
  32. speclogician/logic/main.py +246 -0
  33. speclogician/logic/strings.py +194 -0
  34. speclogician/logic/utils.py +135 -0
  35. speclogician/main.py +139 -0
  36. speclogician/modeling/__init__.py +31 -0
  37. speclogician/modeling/complement.py +104 -0
  38. speclogician/modeling/component.py +71 -0
  39. speclogician/modeling/conflict.py +26 -0
  40. speclogician/modeling/domain.py +349 -0
  41. speclogician/modeling/predicates.py +59 -0
  42. speclogician/modeling/scenario.py +162 -0
  43. speclogician/modeling/spec.py +306 -0
  44. speclogician/modeling/spec_stats.py +39 -0
  45. speclogician/presentation/__init__.py +0 -0
  46. speclogician/presentation/api.py +244 -0
  47. speclogician/presentation/builders/__init__.py +0 -0
  48. speclogician/presentation/builders/_links.py +44 -0
  49. speclogician/presentation/builders/container.py +53 -0
  50. speclogician/presentation/builders/data_artifact.py +42 -0
  51. speclogician/presentation/builders/domain.py +54 -0
  52. speclogician/presentation/builders/instances_list.py +38 -0
  53. speclogician/presentation/builders/predicate.py +51 -0
  54. speclogician/presentation/builders/recommendations.py +41 -0
  55. speclogician/presentation/builders/scenario.py +41 -0
  56. speclogician/presentation/builders/scenario_complement.py +82 -0
  57. speclogician/presentation/builders/smart_find.py +39 -0
  58. speclogician/presentation/builders/spec.py +39 -0
  59. speclogician/presentation/builders/state_diff.py +150 -0
  60. speclogician/presentation/builders/state_instance.py +42 -0
  61. speclogician/presentation/builders/state_instance_summary.py +84 -0
  62. speclogician/presentation/builders/trace.py +58 -0
  63. speclogician/presentation/ctx.py +38 -0
  64. speclogician/presentation/models/__init__.py +0 -0
  65. speclogician/presentation/models/container.py +44 -0
  66. speclogician/presentation/models/data_artifact.py +33 -0
  67. speclogician/presentation/models/domain.py +50 -0
  68. speclogician/presentation/models/instances_list.py +23 -0
  69. speclogician/presentation/models/predicate.py +60 -0
  70. speclogician/presentation/models/recommendations.py +34 -0
  71. speclogician/presentation/models/scenario.py +31 -0
  72. speclogician/presentation/models/scenario_complement.py +40 -0
  73. speclogician/presentation/models/smart_find.py +34 -0
  74. speclogician/presentation/models/spec.py +32 -0
  75. speclogician/presentation/models/state_diff.py +34 -0
  76. speclogician/presentation/models/state_instance.py +31 -0
  77. speclogician/presentation/models/state_instance_summary.py +102 -0
  78. speclogician/presentation/models/trace.py +42 -0
  79. speclogician/presentation/preview/__init__.py +13 -0
  80. speclogician/presentation/preview/cli.py +50 -0
  81. speclogician/presentation/preview/fixtures/__init__.py +205 -0
  82. speclogician/presentation/preview/fixtures/artifact_container.py +150 -0
  83. speclogician/presentation/preview/fixtures/data_artifact.py +144 -0
  84. speclogician/presentation/preview/fixtures/domain_model.py +162 -0
  85. speclogician/presentation/preview/fixtures/instances_list.py +162 -0
  86. speclogician/presentation/preview/fixtures/predicate.py +184 -0
  87. speclogician/presentation/preview/fixtures/scenario.py +84 -0
  88. speclogician/presentation/preview/fixtures/scenario_complement.py +81 -0
  89. speclogician/presentation/preview/fixtures/smart_find.py +140 -0
  90. speclogician/presentation/preview/fixtures/spec.py +95 -0
  91. speclogician/presentation/preview/fixtures/state_diff.py +158 -0
  92. speclogician/presentation/preview/fixtures/state_instance.py +128 -0
  93. speclogician/presentation/preview/fixtures/state_instance_summary.py +80 -0
  94. speclogician/presentation/preview/fixtures/trace.py +206 -0
  95. speclogician/presentation/preview/registry.py +42 -0
  96. speclogician/presentation/renderers/__init__.py +24 -0
  97. speclogician/presentation/renderers/container.py +136 -0
  98. speclogician/presentation/renderers/data_artifact.py +144 -0
  99. speclogician/presentation/renderers/domain.py +123 -0
  100. speclogician/presentation/renderers/instances_list.py +120 -0
  101. speclogician/presentation/renderers/predicate.py +180 -0
  102. speclogician/presentation/renderers/recommendations.py +90 -0
  103. speclogician/presentation/renderers/scenario.py +94 -0
  104. speclogician/presentation/renderers/scenario_complement.py +59 -0
  105. speclogician/presentation/renderers/smart_find.py +307 -0
  106. speclogician/presentation/renderers/spec.py +105 -0
  107. speclogician/presentation/renderers/state_diff.py +102 -0
  108. speclogician/presentation/renderers/state_instance.py +82 -0
  109. speclogician/presentation/renderers/state_instance_summary.py +143 -0
  110. speclogician/presentation/renderers/trace.py +122 -0
  111. speclogician/py.typed +0 -0
  112. speclogician/shell/app.py +170 -0
  113. speclogician/shell/shell_ch.py +263 -0
  114. speclogician/shell/shell_view.py +153 -0
  115. speclogician/state/__init__.py +0 -0
  116. speclogician/state/change.py +428 -0
  117. speclogician/state/change_result.py +32 -0
  118. speclogician/state/diff.py +191 -0
  119. speclogician/state/inst.py +574 -0
  120. speclogician/state/recommendation.py +13 -0
  121. speclogician/state/recommender.py +577 -0
  122. speclogician/state/state.py +465 -0
  123. speclogician/state/state_stats.py +133 -0
  124. speclogician/tui/__init__.py +0 -0
  125. speclogician/tui/app.py +257 -0
  126. speclogician/tui/app.tcss +160 -0
  127. speclogician/tui/demo.py +45 -0
  128. speclogician/tui/images/speclogician-full.png +0 -0
  129. speclogician/tui/images/speclogician-minimal.png +0 -0
  130. speclogician/tui/main_screen.py +454 -0
  131. speclogician/tui/splash_screen.py +51 -0
  132. speclogician/tui/stats_screen.py +125 -0
  133. speclogician/utils/__init__.py +78 -0
  134. speclogician/utils/load.py +166 -0
  135. speclogician/utils/prompt.md +325 -0
  136. speclogician/utils/testing.py +151 -0
  137. speclogician-0.0.0b1.dist-info/METADATA +116 -0
  138. speclogician-0.0.0b1.dist-info/RECORD +139 -0
  139. speclogician-0.0.0b1.dist-info/WHEEL +4 -0
@@ -0,0 +1,191 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # speclogician/state/diff.py
5
+ #
6
+
7
+ from enum import StrEnum
8
+ from typing import TypeAlias, Callable, TypeVar, Generic
9
+ from pydantic import BaseModel, Field
10
+
11
+ from ..modeling.domain import BaseStatus
12
+ from speclogician.modeling.complement import ScenarioComplementDiff
13
+
14
+
15
+ class ComparisonOutcome(StrEnum):
16
+ """ When we compare the before/after values, we'll use this as the comparison outcome """
17
+ UNKNOWN = "unknown"
18
+ NO_CHANGE = "no_change"
19
+ NO_CHANGE_GOOD = "no_change_good"
20
+ NO_CHANGE_BAD = "no_change_bad"
21
+ IMPROVED = "improved"
22
+ DECLINED = "declined"
23
+
24
+
25
+ T = TypeVar("T")
26
+
27
+ ComparisonFn: TypeAlias = Callable[[T, T], ComparisonOutcome]
28
+
29
+ class ValueDiff(BaseModel, Generic[T]):
30
+ """ Represents a change (before → after) with an explanatory label
31
+ and an interpretation of whether increases/decreases are “good”. """
32
+
33
+ label : str
34
+ before: T
35
+ after: T
36
+ comp_func : ComparisonFn[T] | None = Field(default=None, exclude=True)
37
+ hint : None | dict[ComparisonOutcome, str] = None
38
+
39
+ def is_different(self) -> bool:
40
+ if self.comp_func:
41
+ return self.comp_func(self.before, self.after) in (ComparisonOutcome.IMPROVED, ComparisonOutcome.DECLINED)
42
+ return self.before != self.after
43
+
44
+
45
+ # comparison functions
46
+
47
+ def base_status_comp (before : BaseStatus, after : BaseStatus) -> ComparisonOutcome:
48
+ """ """
49
+ # TODO there's prob a nice way to do this without explicit write out...
50
+ match (before, after):
51
+ case (BaseStatus.UNKNOWN, BaseStatus.UNKNOWN):
52
+ return ComparisonOutcome.NO_CHANGE_BAD
53
+ case (BaseStatus.UNKNOWN, _):
54
+ return ComparisonOutcome.IMPROVED
55
+ case (BaseStatus.INVALID_IML, BaseStatus.VALID):
56
+ return ComparisonOutcome.IMPROVED
57
+ case (BaseStatus.INVALID_IML, BaseStatus.INVALID_IML):
58
+ return ComparisonOutcome.NO_CHANGE_BAD
59
+ case (BaseStatus.VALID, BaseStatus.VALID):
60
+ return ComparisonOutcome.NO_CHANGE_GOOD
61
+ case (BaseStatus.VALID, _):
62
+ return ComparisonOutcome.DECLINED
63
+ case (_, _):
64
+ return ComparisonOutcome.UNKNOWN
65
+
66
+ def bool_true_is_good (before : bool, after : bool) -> ComparisonOutcome:
67
+ """ Compare two boolean values where `true` is good """
68
+ match (before, after):
69
+ case (False, False):
70
+ return ComparisonOutcome.NO_CHANGE_BAD
71
+ case (False, True):
72
+ return ComparisonOutcome.IMPROVED
73
+ case (True, False):
74
+ return ComparisonOutcome.DECLINED
75
+ case (True, True):
76
+ return ComparisonOutcome.NO_CHANGE_GOOD
77
+
78
+ def bool_true_is_bad(before: bool, after: bool) -> ComparisonOutcome:
79
+ match (before, after):
80
+ case (False, False):
81
+ return ComparisonOutcome.NO_CHANGE_GOOD
82
+ case (False, True):
83
+ return ComparisonOutcome.DECLINED
84
+ case (True, False):
85
+ return ComparisonOutcome.IMPROVED
86
+ case (True, True):
87
+ return ComparisonOutcome.NO_CHANGE_BAD
88
+
89
+ def numeric_increase_good(before: int | float, after: int | float) -> ComparisonOutcome:
90
+ """
91
+ Increase is good (e.g. matched counts).
92
+ """
93
+ if before == after:
94
+ return ComparisonOutcome.NO_CHANGE_GOOD if before > 0 else ComparisonOutcome.NO_CHANGE
95
+ elif before < after:
96
+ return ComparisonOutcome.IMPROVED
97
+ else:
98
+ return ComparisonOutcome.DECLINED
99
+
100
+
101
+ def numeric_increase_bad(before: int | float, after: int | float) -> ComparisonOutcome:
102
+ """
103
+ Increase is bad (e.g. errors, inconsistencies).
104
+ """
105
+ if before == after:
106
+ return ComparisonOutcome.NO_CHANGE_BAD if before > 0 else ComparisonOutcome.NO_CHANGE_GOOD
107
+ elif before < after:
108
+ return ComparisonOutcome.DECLINED
109
+ else:
110
+ return ComparisonOutcome.IMPROVED
111
+
112
+ def complement_regions_decrease_good(before: int | None, after: int | None) -> ComparisonOutcome:
113
+ """
114
+ Complement represents uncovered space.
115
+ Smaller complement => improved coverage.
116
+ """
117
+ if before is None or after is None:
118
+ return ComparisonOutcome.UNKNOWN
119
+ if after < before:
120
+ return ComparisonOutcome.IMPROVED
121
+ if after > before:
122
+ return ComparisonOutcome.DECLINED
123
+ return ComparisonOutcome.NO_CHANGE
124
+
125
+
126
+ def complement_present_comp(before: bool, after: bool) -> ComparisonOutcome:
127
+ """
128
+ Presence itself isn't strictly good/bad; treat as UNKNOWN unless equal.
129
+ (We separately judge region count where smaller is better.)
130
+ """
131
+ if before == after:
132
+ return ComparisonOutcome.NO_CHANGE
133
+ return ComparisonOutcome.UNKNOWN
134
+
135
+
136
+ class StateDiff(BaseModel):
137
+ """ Statistical summary of changes between two states """
138
+
139
+ # Domain model-related value diffs
140
+ base_status : ValueDiff[BaseStatus] # Base status
141
+ base_has_state : ValueDiff[bool] # Does the base have state defined?
142
+ base_has_action : ValueDiff[bool] # Does the base have action defined?
143
+
144
+ # State predicates
145
+ num_state_preds_total : ValueDiff[int] #
146
+ num_state_preds_matched : ValueDiff[int] #
147
+ num_state_preds_valid_logic : ValueDiff[int] #
148
+ num_state_preds_errored : ValueDiff[int] #
149
+
150
+ # state x action predicates
151
+ num_action_preds_total : ValueDiff[int] #
152
+ num_action_preds_matched : ValueDiff[int] #
153
+ num_action_preds_valid_logic : ValueDiff[int] #
154
+ num_action_preds_errored : ValueDiff[int] #
155
+
156
+ # Predicates
157
+ num_preds_total : ValueDiff[int] # Total number of predicates
158
+ num_preds_matched : ValueDiff[int] # Predicates matched
159
+ num_preds_valid_logic : ValueDiff[int] # Number of predicates with valid logic
160
+ num_preds_errored : ValueDiff[int] # Number of predicates with errors
161
+
162
+ # Transitions
163
+ num_trans_total : ValueDiff[int] # Total number
164
+ num_trans_matched : ValueDiff[int] # Number matched
165
+ num_trans_valid_logic : ValueDiff[int] # Number with valid logic
166
+ num_trans_errored : ValueDiff[int] # Number of transitions with errors
167
+
168
+ # Scenarios
169
+ num_sc_total : ValueDiff[int] # Total number of scenarios
170
+ num_sc_missing : ValueDiff[int] # Missing predicates/transitions
171
+ num_sc_matched : ValueDiff[int] # Scenarios matched vs artifacts
172
+ num_sc_inconsistent : ValueDiff[int] # Scenarios inconsistent
173
+
174
+ # Conflicts (spec-level)
175
+ num_sc_conflicted : ValueDiff[int] # Total conflicts (all kinds)
176
+ num_sc_overlap : ValueDiff[int] # Overlap conflicts
177
+ num_sc_consumed : ValueDiff[int] # Consumed conflicts
178
+
179
+ # Test traces
180
+ num_test_traces_total : ValueDiff[int] # Total number of test traces
181
+ num_test_traces_logic_good : ValueDiff[int] # Valid logic
182
+ num_test_traces_matched : ValueDiff[int] # Matched traces
183
+
184
+ # Log traces
185
+ num_log_traces_total : ValueDiff[int] # Total number of log traces
186
+ num_log_traces_logic_good : ValueDiff[int] # Number of log traces with valid logic
187
+ num_log_traces_matched : ValueDiff[int] # Number of matched traces
188
+
189
+ scenario_comp_present: ValueDiff[bool]
190
+ num_comp_regions_total: ValueDiff[int | None]
191
+ scenario_comp_diff: ScenarioComplementDiff | None = None