speclogician 0.0.0b1__py3-none-any.whl → 0.0.0.dev1__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 (153) hide show
  1. speclogician/agent/funcs.py +29 -0
  2. speclogician/cmd/agent_cmd.py +89 -0
  3. speclogician/cmd/data_cmd.py +24 -0
  4. speclogician/cmd/model_cmd.py +42 -0
  5. speclogician/cmd/overlay_cmd.py +30 -0
  6. speclogician/cmd/scenario_cmd.py +61 -0
  7. speclogician/cmd/state_cmd.py +52 -0
  8. speclogician/data/artifact.py +8 -50
  9. speclogician/data/container.py +18 -384
  10. speclogician/data/mapping.py +18 -17
  11. speclogician/data/refs.py +12 -11
  12. speclogician/data/reports.py +11 -0
  13. speclogician/data/traces.py +15 -6
  14. speclogician/llms/llmtools.py +102 -0
  15. speclogician/llms/overlay.py +264 -0
  16. speclogician/main.py +36 -102
  17. speclogician/modeling/__init__.py +0 -31
  18. speclogician/modeling/component.py +4 -60
  19. speclogician/modeling/conflict.py +5 -19
  20. speclogician/modeling/domain.py +93 -280
  21. speclogician/modeling/model.py +206 -0
  22. speclogician/modeling/predicates.py +20 -22
  23. speclogician/modeling/report.py +33 -0
  24. speclogician/modeling/scenario.py +119 -87
  25. speclogician/sl_cmd.py +76 -0
  26. speclogician/state/change.py +98 -378
  27. speclogician/state/state.py +183 -399
  28. speclogician/tui/box.tcss +10 -0
  29. speclogician/tui/tui.py +131 -0
  30. speclogician/utils/__init__.py +1 -70
  31. speclogician/utils/imx.py +195 -0
  32. speclogician/utils/load.py +25 -147
  33. speclogician/utils/prompt.md +1 -325
  34. speclogician-0.0.0.dev1.dist-info/METADATA +21 -0
  35. speclogician-0.0.0.dev1.dist-info/RECORD +43 -0
  36. speclogician/commands/__init__.py +0 -15
  37. speclogician/commands/cmd_ch.py +0 -616
  38. speclogician/commands/cmd_find.py +0 -256
  39. speclogician/commands/cmd_view.py +0 -202
  40. speclogician/commands/runner.py +0 -149
  41. speclogician/commands/utils.py +0 -101
  42. speclogician/demos/.DS_Store +0 -0
  43. speclogician/demos/cmd_demo.py +0 -278
  44. speclogician/demos/loader.py +0 -135
  45. speclogician/demos/model.py +0 -27
  46. speclogician/demos/runner.py +0 -51
  47. speclogician/logic/__init__.py +0 -11
  48. speclogician/logic/api/__init__.py +0 -29
  49. speclogician/logic/api/client.py +0 -606
  50. speclogician/logic/api/decomp.py +0 -67
  51. speclogician/logic/api/scenario.py +0 -102
  52. speclogician/logic/api/traces.py +0 -59
  53. speclogician/logic/lib/__init__.py +0 -19
  54. speclogician/logic/lib/complement.py +0 -107
  55. speclogician/logic/lib/domain_model.py +0 -59
  56. speclogician/logic/lib/predicates.py +0 -151
  57. speclogician/logic/lib/scenarios.py +0 -369
  58. speclogician/logic/lib/traces.py +0 -114
  59. speclogician/logic/lib/transitions.py +0 -104
  60. speclogician/logic/main.py +0 -246
  61. speclogician/logic/strings.py +0 -194
  62. speclogician/logic/utils.py +0 -135
  63. speclogician/modeling/complement.py +0 -104
  64. speclogician/modeling/spec.py +0 -306
  65. speclogician/modeling/spec_stats.py +0 -39
  66. speclogician/presentation/api.py +0 -244
  67. speclogician/presentation/builders/_links.py +0 -44
  68. speclogician/presentation/builders/container.py +0 -53
  69. speclogician/presentation/builders/data_artifact.py +0 -42
  70. speclogician/presentation/builders/domain.py +0 -54
  71. speclogician/presentation/builders/instances_list.py +0 -38
  72. speclogician/presentation/builders/predicate.py +0 -51
  73. speclogician/presentation/builders/recommendations.py +0 -41
  74. speclogician/presentation/builders/scenario.py +0 -41
  75. speclogician/presentation/builders/scenario_complement.py +0 -82
  76. speclogician/presentation/builders/smart_find.py +0 -39
  77. speclogician/presentation/builders/spec.py +0 -39
  78. speclogician/presentation/builders/state_diff.py +0 -150
  79. speclogician/presentation/builders/state_instance.py +0 -42
  80. speclogician/presentation/builders/state_instance_summary.py +0 -84
  81. speclogician/presentation/builders/trace.py +0 -58
  82. speclogician/presentation/ctx.py +0 -38
  83. speclogician/presentation/models/container.py +0 -44
  84. speclogician/presentation/models/data_artifact.py +0 -33
  85. speclogician/presentation/models/domain.py +0 -50
  86. speclogician/presentation/models/instances_list.py +0 -23
  87. speclogician/presentation/models/predicate.py +0 -60
  88. speclogician/presentation/models/recommendations.py +0 -34
  89. speclogician/presentation/models/scenario.py +0 -31
  90. speclogician/presentation/models/scenario_complement.py +0 -40
  91. speclogician/presentation/models/smart_find.py +0 -34
  92. speclogician/presentation/models/spec.py +0 -32
  93. speclogician/presentation/models/state_diff.py +0 -34
  94. speclogician/presentation/models/state_instance.py +0 -31
  95. speclogician/presentation/models/state_instance_summary.py +0 -102
  96. speclogician/presentation/models/trace.py +0 -42
  97. speclogician/presentation/preview/__init__.py +0 -13
  98. speclogician/presentation/preview/cli.py +0 -50
  99. speclogician/presentation/preview/fixtures/__init__.py +0 -205
  100. speclogician/presentation/preview/fixtures/artifact_container.py +0 -150
  101. speclogician/presentation/preview/fixtures/data_artifact.py +0 -144
  102. speclogician/presentation/preview/fixtures/domain_model.py +0 -162
  103. speclogician/presentation/preview/fixtures/instances_list.py +0 -162
  104. speclogician/presentation/preview/fixtures/predicate.py +0 -184
  105. speclogician/presentation/preview/fixtures/scenario.py +0 -84
  106. speclogician/presentation/preview/fixtures/scenario_complement.py +0 -81
  107. speclogician/presentation/preview/fixtures/smart_find.py +0 -140
  108. speclogician/presentation/preview/fixtures/spec.py +0 -95
  109. speclogician/presentation/preview/fixtures/state_diff.py +0 -158
  110. speclogician/presentation/preview/fixtures/state_instance.py +0 -128
  111. speclogician/presentation/preview/fixtures/state_instance_summary.py +0 -80
  112. speclogician/presentation/preview/fixtures/trace.py +0 -206
  113. speclogician/presentation/preview/registry.py +0 -42
  114. speclogician/presentation/renderers/__init__.py +0 -24
  115. speclogician/presentation/renderers/container.py +0 -136
  116. speclogician/presentation/renderers/data_artifact.py +0 -144
  117. speclogician/presentation/renderers/domain.py +0 -123
  118. speclogician/presentation/renderers/instances_list.py +0 -120
  119. speclogician/presentation/renderers/predicate.py +0 -180
  120. speclogician/presentation/renderers/recommendations.py +0 -90
  121. speclogician/presentation/renderers/scenario.py +0 -94
  122. speclogician/presentation/renderers/scenario_complement.py +0 -59
  123. speclogician/presentation/renderers/smart_find.py +0 -307
  124. speclogician/presentation/renderers/spec.py +0 -105
  125. speclogician/presentation/renderers/state_diff.py +0 -102
  126. speclogician/presentation/renderers/state_instance.py +0 -82
  127. speclogician/presentation/renderers/state_instance_summary.py +0 -143
  128. speclogician/presentation/renderers/trace.py +0 -122
  129. speclogician/shell/app.py +0 -170
  130. speclogician/shell/shell_ch.py +0 -263
  131. speclogician/shell/shell_view.py +0 -153
  132. speclogician/state/change_result.py +0 -32
  133. speclogician/state/diff.py +0 -191
  134. speclogician/state/inst.py +0 -574
  135. speclogician/state/recommendation.py +0 -13
  136. speclogician/state/recommender.py +0 -577
  137. speclogician/state/state_stats.py +0 -133
  138. speclogician/tui/__init__.py +0 -0
  139. speclogician/tui/app.py +0 -257
  140. speclogician/tui/app.tcss +0 -160
  141. speclogician/tui/demo.py +0 -45
  142. speclogician/tui/images/speclogician-full.png +0 -0
  143. speclogician/tui/images/speclogician-minimal.png +0 -0
  144. speclogician/tui/main_screen.py +0 -454
  145. speclogician/tui/splash_screen.py +0 -51
  146. speclogician/tui/stats_screen.py +0 -125
  147. speclogician/utils/testing.py +0 -151
  148. speclogician-0.0.0b1.dist-info/METADATA +0 -116
  149. speclogician-0.0.0b1.dist-info/RECORD +0 -139
  150. /speclogician/{presentation → agent}/__init__.py +0 -0
  151. /speclogician/{presentation/builders → cmd}/__init__.py +0 -0
  152. /speclogician/{presentation/models → llms}/__init__.py +0 -0
  153. {speclogician-0.0.0b1.dist-info → speclogician-0.0.0.dev1.dist-info}/WHEEL +0 -0
@@ -1,162 +0,0 @@
1
- #
2
- # Imandra Inc.
3
- #
4
- # speclogician/presentation/preview/fixtures/domain_model.py
5
- #
6
-
7
- from __future__ import annotations
8
-
9
- from speclogician.modeling.domain import BaseStatus
10
- from speclogician.presentation.models.domain import (
11
- DomainCountsPM,
12
- DomainCodePM,
13
- DomainModelPM,
14
- )
15
- from speclogician.presentation.ctx import RenderCtx
16
-
17
-
18
- # -----------------------------------------------------------------------------
19
- # PM builders (variants)
20
- # -----------------------------------------------------------------------------
21
-
22
- def make_domain_model_pm(ctx: RenderCtx, variant: str = "typical") -> DomainModelPM:
23
- v = (variant or "typical").lower()
24
- if v == "minimal":
25
- return minimal_domain_model_pm()
26
- if v == "edge":
27
- return edge_domain_model_pm()
28
- return typical_domain_model_pm()
29
-
30
-
31
- def minimal_domain_model_pm() -> DomainModelPM:
32
- # Minimal = almost empty, base unknown, no code.
33
- counts = DomainCountsPM(
34
- base_status=BaseStatus.UNKNOWN,
35
- base_has_state=False,
36
- base_has_action=False,
37
- num_state_preds_total=0,
38
- num_state_preds_valid_logic=0,
39
- num_state_preds_matched=0,
40
- num_action_preds_total=0,
41
- num_action_preds_valid_logic=0,
42
- num_action_preds_matched=0,
43
- num_preds_total=0,
44
- num_preds_valid_logic=0,
45
- num_preds_matched=0,
46
- num_trans_total=0,
47
- num_trans_valid_logic=0,
48
- num_trans_matched=0,
49
- )
50
- code = DomainCodePM(
51
- base="",
52
- state_preds_iml="",
53
- action_preds_iml="",
54
- transitions_iml="",
55
- )
56
- return DomainModelPM(counts=counts, code=code)
57
-
58
-
59
- def typical_domain_model_pm() -> DomainModelPM:
60
- # Typical = sane + readable, some matched/valid numbers.
61
- counts = DomainCountsPM(
62
- base_status=BaseStatus.VALID,
63
- base_has_state=True,
64
- base_has_action=True,
65
- # state preds
66
- num_state_preds_total=4,
67
- num_state_preds_valid_logic=3,
68
- num_state_preds_matched=2,
69
- # action preds
70
- num_action_preds_total=3,
71
- num_action_preds_valid_logic=3,
72
- num_action_preds_matched=1,
73
- # totals
74
- num_preds_total=7,
75
- num_preds_valid_logic=6,
76
- num_preds_matched=3,
77
- # transitions
78
- num_trans_total=2,
79
- num_trans_valid_logic=2,
80
- num_trans_matched=1,
81
- )
82
- code = DomainCodePM(
83
- base=(
84
- "type state = { x : int }\n"
85
- "type action = int\n"
86
- ),
87
- state_preds_iml=(
88
- "let pred_eq_ten (s: state) = s.x = 10\n"
89
- "let pred_lt_ten (s: state) = s.x < 10\n"
90
- "let pred_gt_zero (s: state) = s.x > 0\n"
91
- ),
92
- action_preds_iml=(
93
- "let act_gt_x (s: state) (a: action) = a > s.x\n"
94
- "let act_eq_zero (_s: state) (a: action) = a = 0\n"
95
- ),
96
- transitions_iml=(
97
- "let step1 (s: state) (a: action) : state = { x = s.x + a }\n"
98
- "let step2 (_s: state) (a: action) : state = { x = a }\n"
99
- ),
100
- )
101
- return DomainModelPM(counts=counts, code=code)
102
-
103
-
104
- def edge_domain_model_pm() -> DomainModelPM:
105
- # Edge = stress the renderer: long code, weird counts, invalid base.
106
- counts = DomainCountsPM(
107
- base_status=BaseStatus.INVALID_IML,
108
- base_has_state=True,
109
- base_has_action=False,
110
- # state preds
111
- num_state_preds_total=12,
112
- num_state_preds_valid_logic=7,
113
- num_state_preds_matched=0,
114
- # action preds
115
- num_action_preds_total=0,
116
- num_action_preds_valid_logic=0,
117
- num_action_preds_matched=0,
118
- # totals
119
- num_preds_total=12,
120
- num_preds_valid_logic=7,
121
- num_preds_matched=0,
122
- # transitions
123
- num_trans_total=5,
124
- num_trans_valid_logic=2,
125
- num_trans_matched=0,
126
- )
127
- code = DomainCodePM(
128
- base=(
129
- "type state = {\n"
130
- " x : int;\n"
131
- " (* missing action type on purpose to simulate INVALID base *)\n"
132
- "}\n"
133
- ),
134
- state_preds_iml=(
135
- "(* many predicates, including a long one to wrap *)\n"
136
- + "\n".join(
137
- f"let pred_{i} (s: state) = s.x = {i}"
138
- for i in range(1, 10)
139
- )
140
- + "\n"
141
- "let pred_very_long (s: state) = "
142
- "(s.x > 0 && s.x < 1000000 && (s.x mod 3 = 0 || s.x mod 5 = 0))\n"
143
- ),
144
- action_preds_iml="", # missing because base_has_action=False
145
- transitions_iml=(
146
- "(* some transitions, one intentionally sketchy *)\n"
147
- "let step_ok (s: state) (_a: int) : state = { x = s.x }\n"
148
- "let step_weird (s: state) (a: int) : state = { x = s.x + (a + 1) }\n"
149
- "(* malformed-ish snippet *)\n"
150
- "let step_bad (s: state) (a: int) : state = { x = s.x + }\n"
151
- ),
152
- )
153
- return DomainModelPM(counts=counts, code=code)
154
-
155
-
156
- # -----------------------------------------------------------------------------
157
- # renderer adapter (matches other fixtures style)
158
- # -----------------------------------------------------------------------------
159
-
160
- def render(pm: DomainModelPM, ctx: RenderCtx):
161
- from speclogician.presentation.renderers.domain import render_domain_model
162
- return render_domain_model(pm, ctx=ctx)
@@ -1,162 +0,0 @@
1
- #
2
- # Imandra Inc.
3
- #
4
- # speclogician/presentation/preview/fixtures/instances_list.py
5
- #
6
-
7
- from __future__ import annotations
8
-
9
- from speclogician.presentation.ctx import RenderCtx
10
- from speclogician.presentation.models.instances_list import (
11
- InstancesListPM,
12
- InstancesListRowPM,
13
- )
14
- from speclogician.presentation.models.state_instance_summary import StateInstanceSummaryPM
15
- from speclogician.utils import IMLValidity
16
- from speclogician.modeling.domain import BaseStatus
17
-
18
-
19
- # -----------------------------------------------------------------------------
20
- # helpers
21
- # -----------------------------------------------------------------------------
22
-
23
- def _summary(
24
- *,
25
- created_at: str,
26
- num_changes: int,
27
- base_status: BaseStatus = BaseStatus.UNKNOWN,
28
- base_has_state: bool = False,
29
- base_has_action: bool = False,
30
- num_preds_total: int = 0,
31
- num_preds_matched: int = 0,
32
- num_trans_total: int = 0,
33
- num_trans_valid_logic: int = 0,
34
- num_sc_total: int = 0,
35
- num_sc_missing: int = 0,
36
- num_sc_inconsistent: int = 0,
37
- num_sc_conflicted: int = 0,
38
- num_test_traces_total: int = 0,
39
- num_test_traces_logic_good: int = 0,
40
- num_log_traces_total: int = 0,
41
- num_log_traces_logic_good: int = 0,
42
- ) -> StateInstanceSummaryPM:
43
- return StateInstanceSummaryPM(
44
- created_at=created_at,
45
- num_changes=num_changes,
46
- base_status=base_status,
47
- base_has_state=base_has_state,
48
- base_has_action=base_has_action,
49
- num_preds_total=num_preds_total,
50
- num_preds_matched=num_preds_matched,
51
- num_trans_total=num_trans_total,
52
- num_trans_valid_logic=num_trans_valid_logic,
53
- num_sc_total=num_sc_total,
54
- num_sc_missing=num_sc_missing,
55
- num_sc_inconsistent=num_sc_inconsistent,
56
- num_sc_conflicted=num_sc_conflicted,
57
- num_test_traces_total=num_test_traces_total,
58
- num_test_traces_logic_good=num_test_traces_logic_good,
59
- num_log_traces_total=num_log_traces_total,
60
- num_log_traces_logic_good=num_log_traces_logic_good,
61
- )
62
-
63
-
64
- # -----------------------------------------------------------------------------
65
- # fixtures
66
- # -----------------------------------------------------------------------------
67
-
68
- def minimal_instances_list_pm() -> InstancesListPM:
69
- return InstancesListPM(rows=[])
70
-
71
-
72
- def typical_instances_list_pm() -> InstancesListPM:
73
- return InstancesListPM(
74
- rows=[
75
- InstancesListRowPM(
76
- state_label="latest",
77
- changes="DomainModelBaseEdit, PredicateAdd",
78
- summary=_summary(
79
- created_at="2026-01-09T10:12:00Z",
80
- num_changes=2,
81
- base_status=BaseStatus.VALID,
82
- base_has_state=True,
83
- base_has_action=True,
84
- num_preds_total=12,
85
- num_preds_matched=7,
86
- num_trans_total=4,
87
- num_trans_valid_logic=3,
88
- num_sc_total=9,
89
- num_sc_missing=1,
90
- num_test_traces_total=8,
91
- num_test_traces_logic_good=6,
92
- num_log_traces_total=4,
93
- num_log_traces_logic_good=4,
94
- ),
95
- ),
96
- InstancesListRowPM(
97
- state_label="1",
98
- changes="PredicateEdit",
99
- summary=_summary(
100
- created_at="2026-01-09T09:55:10Z",
101
- num_changes=1,
102
- base_status=BaseStatus.VALID,
103
- base_has_state=True,
104
- base_has_action=True,
105
- num_preds_total=11,
106
- num_preds_matched=6,
107
- num_trans_total=4,
108
- num_trans_valid_logic=3,
109
- num_sc_total=8,
110
- num_sc_missing=0,
111
- num_test_traces_total=7,
112
- num_test_traces_logic_good=6,
113
- num_log_traces_total=3,
114
- num_log_traces_logic_good=3,
115
- ),
116
- ),
117
- ]
118
- )
119
-
120
-
121
- def edge_instances_list_pm() -> InstancesListPM:
122
- return InstancesListPM(
123
- rows=[
124
- InstancesListRowPM(
125
- state_label="latest",
126
- changes="",
127
- summary=_summary(
128
- created_at="2026-01-09T10:12:00.123456Z",
129
- num_changes=0,
130
- base_status=BaseStatus.UNKNOWN,
131
- base_has_state=False,
132
- base_has_action=False,
133
- num_preds_total=0,
134
- num_preds_matched=0,
135
- num_trans_total=0,
136
- num_trans_valid_logic=0,
137
- num_sc_total=0,
138
- num_sc_missing=0,
139
- num_test_traces_total=0,
140
- num_test_traces_logic_good=0,
141
- num_log_traces_total=0,
142
- num_log_traces_logic_good=0,
143
- ),
144
- )
145
- ]
146
- )
147
-
148
- def make_instances_list_pm(ctx: RenderCtx, variant: str = "typical") -> InstancesListPM:
149
- v = (variant or "typical").strip().lower()
150
-
151
- if v == "minimal":
152
- return minimal_instances_list_pm()
153
-
154
- if v == "edge":
155
- return edge_instances_list_pm()
156
-
157
- return typical_instances_list_pm()
158
-
159
-
160
- def render(pm: InstancesListPM, ctx : RenderCtx):
161
- from speclogician.presentation.renderers.instances_list import render_instances_list
162
- return render_instances_list(pm, ctx=ctx)
@@ -1,184 +0,0 @@
1
- #
2
- # Imandra Inc.
3
- #
4
- # speclogician/presentation/preview/fixtures/predicate.py
5
- #
6
-
7
- from __future__ import annotations
8
-
9
- from datetime import datetime, timezone
10
- from speclogician.presentation.ctx import RenderCtx
11
- from speclogician.presentation.models.predicate import (
12
- PredicatePM,
13
- TransitionPM,
14
- LinkedArtifactsPM,
15
- )
16
- from speclogician.modeling.predicates import PredicateType
17
- from speclogician.utils import IMLValidity
18
-
19
-
20
- NOW = datetime(2026, 1, 9, 10, 12, tzinfo=timezone.utc)
21
-
22
-
23
- # -----------------------------------------------------------------------------
24
- # Shared helpers
25
- # -----------------------------------------------------------------------------
26
-
27
- def _minimal_links() -> LinkedArtifactsPM:
28
- return LinkedArtifactsPM()
29
-
30
-
31
- def _typical_links() -> LinkedArtifactsPM:
32
- return LinkedArtifactsPM(
33
- total=4,
34
- test_traces=2,
35
- log_traces=1,
36
- doc_refs=1,
37
- src_code_refs=0,
38
- unresolved_ids=0,
39
- art_ids=["tt-1", "tt-2", "log-1", "doc-1"],
40
- )
41
-
42
-
43
- def _edge_links() -> LinkedArtifactsPM:
44
- return LinkedArtifactsPM(
45
- total=12,
46
- test_traces=5,
47
- log_traces=3,
48
- doc_refs=2,
49
- src_code_refs=1,
50
- unresolved_ids=1,
51
- art_ids=[f"art-{i}" for i in range(12)],
52
- )
53
-
54
-
55
- # -----------------------------------------------------------------------------
56
- # PredicatePM variants
57
- # -----------------------------------------------------------------------------
58
-
59
- def _predicate_minimal() -> PredicatePM:
60
- return PredicatePM(
61
- kind="state_predicate",
62
- comp_id="pred-min",
63
- name="",
64
- last_updated=NOW,
65
- pred_type=PredicateType.STATE,
66
- signature="",
67
- src_code="",
68
- iml="",
69
- is_iml_valid=IMLValidity.UNKNOWN,
70
- iml_error=None,
71
- links=_minimal_links(),
72
- )
73
-
74
-
75
- def _predicate_typical() -> PredicatePM:
76
- return PredicatePM(
77
- kind="state_predicate",
78
- comp_id="pred-001",
79
- name="pred_eq_ten",
80
- last_updated=NOW,
81
- pred_type=PredicateType.STATE,
82
- signature="state -> bool",
83
- src_code="s.x = 10",
84
- iml="let pred_eq_ten (s: state) = s.x = 10",
85
- is_iml_valid=IMLValidity.VALID,
86
- iml_error=None,
87
- links=_typical_links(),
88
- )
89
-
90
-
91
- def _predicate_edge() -> PredicatePM:
92
- return PredicatePM(
93
- kind="action_predicate",
94
- comp_id="pred-edge-999",
95
- name="pred_complex_action_condition_with_long_name",
96
- last_updated=NOW,
97
- pred_type=PredicateType.ACTION,
98
- signature="state -> action -> bool",
99
- src_code="a.qty > s.max_qty &&\n(a.price > 0 || a.kind = Market)",
100
- iml=(
101
- "let pred_complex_action_condition_with_long_name (s: state) (a: action) =\n"
102
- " a.qty > s.max_qty && (a.price > 0 || a.kind = Market)"
103
- ),
104
- is_iml_valid=IMLValidity.INVALID,
105
- iml_error="Type error: cannot compare int and option<int> in expression a.price > 0",
106
- links=_edge_links(),
107
- )
108
-
109
-
110
- def make_predicate_pm(ctx: RenderCtx, variant: str = "typical") -> PredicatePM:
111
- v = (variant or "typical").strip().lower()
112
- if v == "minimal":
113
- return _predicate_minimal()
114
- if v == "edge":
115
- return _predicate_edge()
116
- return _predicate_typical()
117
-
118
- def render_predicate(pm: PredicatePM, ctx: RenderCtx):
119
- from speclogician.presentation.renderers.predicate import render_predicate
120
- return render_predicate(pm, ctx=ctx)
121
-
122
- # -----------------------------------------------------------------------------
123
- # TransitionPM variants
124
- # -----------------------------------------------------------------------------
125
-
126
- def _transition_minimal() -> TransitionPM:
127
- return TransitionPM(
128
- kind="transition",
129
- comp_id="trans-min",
130
- name="",
131
- last_updated=NOW,
132
- signature="",
133
- src_code="",
134
- iml="",
135
- is_iml_valid=IMLValidity.UNKNOWN,
136
- iml_error=None,
137
- links=_minimal_links(),
138
- )
139
-
140
-
141
- def _transition_typical() -> TransitionPM:
142
- return TransitionPM(
143
- kind="transition",
144
- comp_id="trans-001",
145
- name="step1",
146
- last_updated=NOW,
147
- signature="state -> action -> state",
148
- src_code="{ x = s.x + a }",
149
- iml="let step1 (s: state) (a: action) : state =\n { x = s.x + a }",
150
- is_iml_valid=IMLValidity.VALID,
151
- iml_error=None,
152
- links=_typical_links(),
153
- )
154
-
155
-
156
- def _transition_edge() -> TransitionPM:
157
- return TransitionPM(
158
- kind="transition",
159
- comp_id="trans-edge-888",
160
- name="step_with_very_long_and_descriptive_name",
161
- last_updated=NOW,
162
- signature="state -> action -> state",
163
- src_code="{ x = if a > 0 then s.x + a else false }",
164
- iml=(
165
- "let step_with_very_long_and_descriptive_name (s: state) (a: action) : state =\n"
166
- " { x = if a > 0 then s.x + a else false }"
167
- ),
168
- is_iml_valid=IMLValidity.INVALID,
169
- iml_error="Type error: expected int, got bool in field x",
170
- links=_edge_links(),
171
- )
172
-
173
-
174
- def make_transition_pm(ctx: RenderCtx, variant: str = "typical") -> TransitionPM:
175
- v = (variant or "typical").strip().lower()
176
- if v == "minimal":
177
- return _transition_minimal()
178
- if v == "edge":
179
- return _transition_edge()
180
- return _transition_typical()
181
-
182
- def render_transition(pm: TransitionPM, ctx: RenderCtx):
183
- from speclogician.presentation.renderers.predicate import render_transition
184
- return render_transition(pm, ctx=ctx)
@@ -1,84 +0,0 @@
1
- #
2
- # Imandra Inc.
3
- #
4
- # speclogician/presentation/preview/fixtures/scenario.py
5
- #
6
-
7
- from __future__ import annotations
8
-
9
- from speclogician.presentation.ctx import RenderCtx
10
- from speclogician.presentation.models.scenario import (
11
- ScenarioPM,
12
- ScenarioStatusPM,
13
- )
14
-
15
- # -----------------------------------------------------------------------------
16
- # variants
17
- # -----------------------------------------------------------------------------
18
-
19
- def _minimal() -> ScenarioPM:
20
- return ScenarioPM(
21
- comp_id="sc:0000",
22
- name="",
23
- status=ScenarioStatusPM(kind="valid"),
24
- given=[],
25
- when=[],
26
- then=[],
27
- given_preds_consistent=True,
28
- when_preds_consistent=True,
29
- all_preds_consistent=True,
30
- )
31
-
32
-
33
- def _typical() -> ScenarioPM:
34
- return ScenarioPM(
35
- comp_id="sc:0001",
36
- name="scenario_1",
37
- status=ScenarioStatusPM(kind="valid"),
38
- given=["pred_eq_ten", "pred_ne_ten"],
39
- when=["act_gt_x"],
40
- then=["step1"],
41
- given_preds_consistent=True,
42
- when_preds_consistent=True,
43
- all_preds_consistent=True,
44
- )
45
-
46
-
47
- def _edge() -> ScenarioPM:
48
- return ScenarioPM(
49
- comp_id="sc:9999",
50
- name="scenario_" + ("very_long_name_" * 6) + "end",
51
- status=ScenarioStatusPM(
52
- kind="missing",
53
- missing_preds=["pred_missing_1", "pred_missing_2"],
54
- missing_trans=["step_missing"],
55
- ),
56
- given=["pred_eq_ten", "pred_missing_1"],
57
- when=["act_gt_x", "act_weird_pred"],
58
- then=["step1", "step_missing"],
59
- given_preds_consistent=False,
60
- when_preds_consistent=False,
61
- all_preds_consistent=False,
62
- )
63
-
64
-
65
- # -----------------------------------------------------------------------------
66
- # public fixture entrypoint (matches PreviewSpec.make)
67
- # -----------------------------------------------------------------------------
68
-
69
- def make_scenario_pm(ctx: RenderCtx, variant: str = "typical") -> ScenarioPM:
70
- v = (variant or "typical").lower().strip()
71
- if v == "minimal":
72
- return _minimal()
73
- if v == "edge":
74
- return _edge()
75
- return _typical()
76
-
77
-
78
- # -----------------------------------------------------------------------------
79
- # renderer adapter (matches other fixtures style)
80
- # -----------------------------------------------------------------------------
81
-
82
- def render(pm: ScenarioPM, ctx: RenderCtx):
83
- from speclogician.presentation.renderers.scenario import render_scenario
84
- return render_scenario(pm, ctx=ctx)
@@ -1,81 +0,0 @@
1
- #
2
- # Imandra Inc.
3
- #
4
- # speclogician/presentation/preview/fixtures/scenario_complement.py
5
- #
6
-
7
- from __future__ import annotations
8
-
9
- from speclogician.presentation.models.scenario_complement import (
10
- ScenarioComplementPM,
11
- ScenarioComplementRegionPM,
12
- )
13
-
14
-
15
- def make_scenario_complement_pm(variant: str = "typical") -> ScenarioComplementPM:
16
- v = (variant or "typical").strip().lower()
17
-
18
- if v == "empty":
19
- return ScenarioComplementPM(
20
- count_regions=0,
21
- regions_preview=[],
22
- regions_all=None,
23
- )
24
-
25
- if v == "edge":
26
- preview = [
27
- ScenarioComplementRegionPM(
28
- fp="a3f91c0d12e9ab01",
29
- num_constraints=12,
30
- invariant="x >= 0",
31
- model="{x = 0}",
32
- model_eval="ok",
33
- constraints_preview=["x >= 0", "y = 1", "z != 3"],
34
- ),
35
- ScenarioComplementRegionPM(
36
- fp="bb92e44caa10fe88",
37
- num_constraints=7,
38
- invariant="balance < limit",
39
- model="{balance = 5, limit = 10}",
40
- model_eval="ok",
41
- constraints_preview=["balance < limit", "limit = 10"],
42
- ),
43
- ScenarioComplementRegionPM(
44
- fp="0f12caa903bc9e77",
45
- num_constraints=3,
46
- invariant=None,
47
- model=None,
48
- model_eval=None,
49
- constraints_preview=["flag = true"],
50
- ),
51
- ]
52
- return ScenarioComplementPM(
53
- count_regions=42,
54
- regions_preview=preview,
55
- regions_all=None,
56
- )
57
-
58
- # typical
59
- preview = [
60
- ScenarioComplementRegionPM(
61
- fp="e19caa903bc9e771",
62
- num_constraints=4,
63
- invariant="state_ok",
64
- model="{s = {...}}",
65
- model_eval="ok",
66
- constraints_preview=["state_ok", "x != 0"],
67
- ),
68
- ScenarioComplementRegionPM(
69
- fp="a2ff10d12e9ab013",
70
- num_constraints=2,
71
- invariant=None,
72
- model="{x = 1}",
73
- model_eval="ok",
74
- constraints_preview=["x = 1"],
75
- ),
76
- ]
77
- return ScenarioComplementPM(
78
- count_regions=7,
79
- regions_preview=preview,
80
- regions_all=None,
81
- )