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.
- speclogician/__init__.py +0 -0
- speclogician/commands/__init__.py +15 -0
- speclogician/commands/cmd_ch.py +616 -0
- speclogician/commands/cmd_find.py +256 -0
- speclogician/commands/cmd_view.py +202 -0
- speclogician/commands/runner.py +149 -0
- speclogician/commands/utils.py +101 -0
- speclogician/data/__init__.py +0 -0
- speclogician/data/artifact.py +63 -0
- speclogician/data/container.py +402 -0
- speclogician/data/mapping.py +88 -0
- speclogician/data/refs.py +24 -0
- speclogician/data/traces.py +26 -0
- speclogician/demos/.DS_Store +0 -0
- speclogician/demos/cmd_demo.py +278 -0
- speclogician/demos/loader.py +135 -0
- speclogician/demos/model.py +27 -0
- speclogician/demos/runner.py +51 -0
- speclogician/logic/__init__.py +11 -0
- speclogician/logic/api/__init__.py +29 -0
- speclogician/logic/api/client.py +606 -0
- speclogician/logic/api/decomp.py +67 -0
- speclogician/logic/api/scenario.py +102 -0
- speclogician/logic/api/traces.py +59 -0
- speclogician/logic/lib/__init__.py +19 -0
- speclogician/logic/lib/complement.py +107 -0
- speclogician/logic/lib/domain_model.py +59 -0
- speclogician/logic/lib/predicates.py +151 -0
- speclogician/logic/lib/scenarios.py +369 -0
- speclogician/logic/lib/traces.py +114 -0
- speclogician/logic/lib/transitions.py +104 -0
- speclogician/logic/main.py +246 -0
- speclogician/logic/strings.py +194 -0
- speclogician/logic/utils.py +135 -0
- speclogician/main.py +139 -0
- speclogician/modeling/__init__.py +31 -0
- speclogician/modeling/complement.py +104 -0
- speclogician/modeling/component.py +71 -0
- speclogician/modeling/conflict.py +26 -0
- speclogician/modeling/domain.py +349 -0
- speclogician/modeling/predicates.py +59 -0
- speclogician/modeling/scenario.py +162 -0
- speclogician/modeling/spec.py +306 -0
- speclogician/modeling/spec_stats.py +39 -0
- speclogician/presentation/__init__.py +0 -0
- speclogician/presentation/api.py +244 -0
- speclogician/presentation/builders/__init__.py +0 -0
- speclogician/presentation/builders/_links.py +44 -0
- speclogician/presentation/builders/container.py +53 -0
- speclogician/presentation/builders/data_artifact.py +42 -0
- speclogician/presentation/builders/domain.py +54 -0
- speclogician/presentation/builders/instances_list.py +38 -0
- speclogician/presentation/builders/predicate.py +51 -0
- speclogician/presentation/builders/recommendations.py +41 -0
- speclogician/presentation/builders/scenario.py +41 -0
- speclogician/presentation/builders/scenario_complement.py +82 -0
- speclogician/presentation/builders/smart_find.py +39 -0
- speclogician/presentation/builders/spec.py +39 -0
- speclogician/presentation/builders/state_diff.py +150 -0
- speclogician/presentation/builders/state_instance.py +42 -0
- speclogician/presentation/builders/state_instance_summary.py +84 -0
- speclogician/presentation/builders/trace.py +58 -0
- speclogician/presentation/ctx.py +38 -0
- speclogician/presentation/models/__init__.py +0 -0
- speclogician/presentation/models/container.py +44 -0
- speclogician/presentation/models/data_artifact.py +33 -0
- speclogician/presentation/models/domain.py +50 -0
- speclogician/presentation/models/instances_list.py +23 -0
- speclogician/presentation/models/predicate.py +60 -0
- speclogician/presentation/models/recommendations.py +34 -0
- speclogician/presentation/models/scenario.py +31 -0
- speclogician/presentation/models/scenario_complement.py +40 -0
- speclogician/presentation/models/smart_find.py +34 -0
- speclogician/presentation/models/spec.py +32 -0
- speclogician/presentation/models/state_diff.py +34 -0
- speclogician/presentation/models/state_instance.py +31 -0
- speclogician/presentation/models/state_instance_summary.py +102 -0
- speclogician/presentation/models/trace.py +42 -0
- speclogician/presentation/preview/__init__.py +13 -0
- speclogician/presentation/preview/cli.py +50 -0
- speclogician/presentation/preview/fixtures/__init__.py +205 -0
- speclogician/presentation/preview/fixtures/artifact_container.py +150 -0
- speclogician/presentation/preview/fixtures/data_artifact.py +144 -0
- speclogician/presentation/preview/fixtures/domain_model.py +162 -0
- speclogician/presentation/preview/fixtures/instances_list.py +162 -0
- speclogician/presentation/preview/fixtures/predicate.py +184 -0
- speclogician/presentation/preview/fixtures/scenario.py +84 -0
- speclogician/presentation/preview/fixtures/scenario_complement.py +81 -0
- speclogician/presentation/preview/fixtures/smart_find.py +140 -0
- speclogician/presentation/preview/fixtures/spec.py +95 -0
- speclogician/presentation/preview/fixtures/state_diff.py +158 -0
- speclogician/presentation/preview/fixtures/state_instance.py +128 -0
- speclogician/presentation/preview/fixtures/state_instance_summary.py +80 -0
- speclogician/presentation/preview/fixtures/trace.py +206 -0
- speclogician/presentation/preview/registry.py +42 -0
- speclogician/presentation/renderers/__init__.py +24 -0
- speclogician/presentation/renderers/container.py +136 -0
- speclogician/presentation/renderers/data_artifact.py +144 -0
- speclogician/presentation/renderers/domain.py +123 -0
- speclogician/presentation/renderers/instances_list.py +120 -0
- speclogician/presentation/renderers/predicate.py +180 -0
- speclogician/presentation/renderers/recommendations.py +90 -0
- speclogician/presentation/renderers/scenario.py +94 -0
- speclogician/presentation/renderers/scenario_complement.py +59 -0
- speclogician/presentation/renderers/smart_find.py +307 -0
- speclogician/presentation/renderers/spec.py +105 -0
- speclogician/presentation/renderers/state_diff.py +102 -0
- speclogician/presentation/renderers/state_instance.py +82 -0
- speclogician/presentation/renderers/state_instance_summary.py +143 -0
- speclogician/presentation/renderers/trace.py +122 -0
- speclogician/py.typed +0 -0
- speclogician/shell/app.py +170 -0
- speclogician/shell/shell_ch.py +263 -0
- speclogician/shell/shell_view.py +153 -0
- speclogician/state/__init__.py +0 -0
- speclogician/state/change.py +428 -0
- speclogician/state/change_result.py +32 -0
- speclogician/state/diff.py +191 -0
- speclogician/state/inst.py +574 -0
- speclogician/state/recommendation.py +13 -0
- speclogician/state/recommender.py +577 -0
- speclogician/state/state.py +465 -0
- speclogician/state/state_stats.py +133 -0
- speclogician/tui/__init__.py +0 -0
- speclogician/tui/app.py +257 -0
- speclogician/tui/app.tcss +160 -0
- speclogician/tui/demo.py +45 -0
- speclogician/tui/images/speclogician-full.png +0 -0
- speclogician/tui/images/speclogician-minimal.png +0 -0
- speclogician/tui/main_screen.py +454 -0
- speclogician/tui/splash_screen.py +51 -0
- speclogician/tui/stats_screen.py +125 -0
- speclogician/utils/__init__.py +78 -0
- speclogician/utils/load.py +166 -0
- speclogician/utils/prompt.md +325 -0
- speclogician/utils/testing.py +151 -0
- speclogician-0.0.0b1.dist-info/METADATA +116 -0
- speclogician-0.0.0b1.dist-info/RECORD +139 -0
- speclogician-0.0.0b1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/builders/state_instance_summary.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from speclogician.presentation.ctx import RenderCtx
|
|
10
|
+
from speclogician.presentation.models.state_instance_summary import StateInstanceSummaryPM
|
|
11
|
+
from speclogician.state.inst import StateInstance
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _g(obj: object, name: str, default):
|
|
15
|
+
return getattr(obj, name, default)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def build_state_instance_summary_pm(si: StateInstance, ctx: RenderCtx) -> StateInstanceSummaryPM:
|
|
19
|
+
dm = si.spec.domain_model
|
|
20
|
+
spec = si.spec
|
|
21
|
+
art = si.art_container
|
|
22
|
+
|
|
23
|
+
return StateInstanceSummaryPM(
|
|
24
|
+
created_at=si.created_at.isoformat() if si.created_at else None,
|
|
25
|
+
num_changes=len(si.changes or []),
|
|
26
|
+
|
|
27
|
+
# ---- Domain model (base) ----
|
|
28
|
+
base_status=str(_g(dm, "base_status", None)),
|
|
29
|
+
base_has_state=_g(dm, "base_has_state", False),
|
|
30
|
+
base_has_action=_g(dm, "base_has_action", False),
|
|
31
|
+
|
|
32
|
+
# ---- State predicates ----
|
|
33
|
+
num_state_preds_total=_g(dm, "num_state_preds_total", 0),
|
|
34
|
+
num_state_preds_matched=_g(dm, "num_state_preds_matched", 0),
|
|
35
|
+
num_state_preds_valid_logic=_g(dm, "num_state_preds_valid_logic", 0),
|
|
36
|
+
num_state_preds_errored=_g(dm, "num_state_preds_errored", 0),
|
|
37
|
+
|
|
38
|
+
# ---- Action predicates ----
|
|
39
|
+
num_action_preds_total=_g(dm, "num_action_preds_total", 0),
|
|
40
|
+
num_action_preds_matched=_g(dm, "num_action_preds_matched", 0),
|
|
41
|
+
num_action_preds_valid_logic=_g(dm, "num_action_preds_valid_logic", 0),
|
|
42
|
+
num_action_preds_errored=_g(dm, "num_action_preds_errored", 0),
|
|
43
|
+
|
|
44
|
+
# ---- Predicates totals ----
|
|
45
|
+
num_preds_total=_g(dm, "num_preds_total", 0),
|
|
46
|
+
num_preds_matched=_g(dm, "num_preds_matched", 0),
|
|
47
|
+
num_preds_valid_logic=_g(dm, "num_preds_valid_logic", 0),
|
|
48
|
+
num_preds_errored=_g(dm, "num_preds_errored", 0),
|
|
49
|
+
|
|
50
|
+
# ---- Transitions ----
|
|
51
|
+
num_trans_total=_g(dm, "num_trans_total", 0),
|
|
52
|
+
num_trans_matched=_g(dm, "num_trans_matched", 0),
|
|
53
|
+
num_trans_valid_logic=_g(dm, "num_trans_valid_logic", 0),
|
|
54
|
+
num_trans_errored=_g(dm, "num_trans_errored", 0),
|
|
55
|
+
|
|
56
|
+
# ---- Scenarios ----
|
|
57
|
+
num_sc_total=_g(spec, "num_sc_total", 0),
|
|
58
|
+
num_sc_missing=_g(spec, "num_sc_missing", 0),
|
|
59
|
+
num_sc_matched=_g(spec, "num_sc_matched", 0),
|
|
60
|
+
num_sc_inconsistent=_g(spec, "num_sc_inconsistent", 0),
|
|
61
|
+
|
|
62
|
+
# ---- Conflicts (spec-level) ----
|
|
63
|
+
num_sc_conflicted=_g(spec, "num_sc_conflicted", 0),
|
|
64
|
+
num_sc_overlap=_g(spec, "num_sc_overlap", 0),
|
|
65
|
+
num_sc_consumed=_g(spec, "num_sc_consumed", 0),
|
|
66
|
+
|
|
67
|
+
# ---- ArtifactContainer: test traces ----
|
|
68
|
+
num_test_traces_total=_g(art, "num_test_traces_total", 0),
|
|
69
|
+
num_test_traces_logic_good=_g(art, "num_test_traces_logic_good", 0),
|
|
70
|
+
num_test_traces_matched=_g(art, "num_test_traces_matched", 0),
|
|
71
|
+
|
|
72
|
+
# ---- ArtifactContainer: log traces ----
|
|
73
|
+
num_log_traces_total=_g(art, "num_log_traces_total", 0),
|
|
74
|
+
num_log_traces_logic_good=_g(art, "num_log_traces_logic_good", 0),
|
|
75
|
+
num_log_traces_matched=_g(art, "num_log_traces_matched", 0),
|
|
76
|
+
|
|
77
|
+
# ---- ArtifactContainer: src code ----
|
|
78
|
+
num_src_code_arts_total=_g(art, "num_src_code_arts_total", 0),
|
|
79
|
+
num_src_code_arts_matched=_g(art, "num_src_code_arts_matched", 0),
|
|
80
|
+
|
|
81
|
+
# ---- ArtifactContainer: docs ----
|
|
82
|
+
num_doc_arts_total=_g(art, "num_doc_arts_total", 0),
|
|
83
|
+
num_doc_arts_matched=_g(art, "num_doc_arts_matched", 0),
|
|
84
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/builders/trace.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from speclogician.presentation.ctx import RenderCtx
|
|
10
|
+
from speclogician.presentation.models.trace import (
|
|
11
|
+
TraceIMLValidityPM,
|
|
12
|
+
TraceCorePM,
|
|
13
|
+
TestTracePM,
|
|
14
|
+
LogTracePM,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from speclogician.data.traces import TestTrace, LogTrace
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _build_validity_pm(v) -> TraceIMLValidityPM:
|
|
21
|
+
# v: TraceIMLValidity(iml_valid=IMLValidity, err=...)
|
|
22
|
+
iml_valid = getattr(v, "iml_valid", None)
|
|
23
|
+
# enum -> "valid"/"invalid"/"unknown"
|
|
24
|
+
iml_valid_s = getattr(iml_valid, "value", None) or str(iml_valid)
|
|
25
|
+
return TraceIMLValidityPM(iml_valid=str(iml_valid_s), err=getattr(v, "err", None))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _build_core_pm(tr: TestTrace | LogTrace) -> TraceCorePM:
|
|
29
|
+
return TraceCorePM(
|
|
30
|
+
art_id=tr.art_id,
|
|
31
|
+
given=tr.given,
|
|
32
|
+
when=tr.when,
|
|
33
|
+
then=tr.then,
|
|
34
|
+
time=tr.time or "",
|
|
35
|
+
iml_validity=_build_validity_pm(tr.iml_validity),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def build_test_trace_pm(tr: TestTrace, ctx: RenderCtx) -> TestTracePM:
|
|
40
|
+
# heavy fields obey ctx.show_code (or rename to ctx.show_contents if you prefer)
|
|
41
|
+
contents = tr.contents if getattr(ctx, "show_code", True) else None
|
|
42
|
+
return TestTracePM(
|
|
43
|
+
core=_build_core_pm(tr),
|
|
44
|
+
name=tr.name,
|
|
45
|
+
filepath=tr.filepath or "",
|
|
46
|
+
language=tr.language,
|
|
47
|
+
contents=contents,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def build_log_trace_pm(tr: LogTrace, ctx: RenderCtx) -> LogTracePM:
|
|
52
|
+
# heavy log contents also obey ctx.show_code
|
|
53
|
+
contents = tr.contents if getattr(ctx, "show_code", True) else None
|
|
54
|
+
return LogTracePM(
|
|
55
|
+
core=_build_core_pm(tr),
|
|
56
|
+
filename=tr.filename,
|
|
57
|
+
contents=contents,
|
|
58
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/ctx.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
from pydantic import BaseModel
|
|
9
|
+
from speclogician.data.container import ArtifactContainer
|
|
10
|
+
from speclogician.data.mapping import ArtifactMap
|
|
11
|
+
|
|
12
|
+
class RenderCtx(BaseModel):
|
|
13
|
+
art_cont: ArtifactContainer | None = None
|
|
14
|
+
art_map: ArtifactMap | None = None
|
|
15
|
+
|
|
16
|
+
show_ids: bool = False
|
|
17
|
+
show_art_ids: bool = False
|
|
18
|
+
|
|
19
|
+
# --- global presentation toggles ---
|
|
20
|
+
compact: bool = False # tighter tables/panels
|
|
21
|
+
show_stats_only: bool = False # render only summary stats (no code blocks)
|
|
22
|
+
show_code: bool = True # include code blocks (IML, src snippets)
|
|
23
|
+
|
|
24
|
+
# --- domain-model specific ---
|
|
25
|
+
show_base: bool = True
|
|
26
|
+
show_predicates: bool = True
|
|
27
|
+
show_transitions: bool = True
|
|
28
|
+
|
|
29
|
+
# --- scenario specific (when you wire it) ---
|
|
30
|
+
show_scenario_conflicts: bool = True
|
|
31
|
+
show_missing_components: bool = True
|
|
32
|
+
|
|
33
|
+
# --- artifacts/mapping (when you wire it) ---
|
|
34
|
+
show_traces: bool = True
|
|
35
|
+
show_artifacts: bool = True
|
|
36
|
+
|
|
37
|
+
show_empty_sections: bool = False
|
|
38
|
+
show_recommendations: bool = True
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/container.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from speclogician.presentation.models.trace import TestTracePM, LogTracePM
|
|
13
|
+
from speclogician.presentation.models.data_artifact import DocRefPM, SrcCodeRefPM
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ArtifactContainerCountsPM(BaseModel):
|
|
17
|
+
# traces
|
|
18
|
+
num_test_traces_total: int = 0
|
|
19
|
+
num_test_traces_matched: int = 0
|
|
20
|
+
num_test_traces_logic_good: int = 0
|
|
21
|
+
|
|
22
|
+
num_log_traces_total: int = 0
|
|
23
|
+
num_log_traces_matched: int = 0
|
|
24
|
+
num_log_traces_logic_good: int = 0
|
|
25
|
+
|
|
26
|
+
# data artifacts
|
|
27
|
+
num_src_code_arts_total: int = 0
|
|
28
|
+
num_src_code_arts_matched: int = 0
|
|
29
|
+
|
|
30
|
+
num_doc_arts_total: int = 0
|
|
31
|
+
num_doc_arts_matched: int = 0
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ArtifactContainerItemsPM(BaseModel):
|
|
35
|
+
test_traces: list[TestTracePM] = Field(default_factory=list)
|
|
36
|
+
log_traces: list[LogTracePM] = Field(default_factory=list)
|
|
37
|
+
doc_refs: list[DocRefPM] = Field(default_factory=list)
|
|
38
|
+
src_code_refs: list[SrcCodeRefPM] = Field(default_factory=list)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ArtifactContainerPM(BaseModel):
|
|
42
|
+
kind: Literal["artifact_container"] = "artifact_container"
|
|
43
|
+
counts: ArtifactContainerCountsPM
|
|
44
|
+
items: ArtifactContainerItemsPM
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/data_artifact.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DataArtifactCorePM(BaseModel):
|
|
14
|
+
art_id: str
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DocRefPM(BaseModel):
|
|
18
|
+
kind: Literal["doc_ref"] = "doc_ref"
|
|
19
|
+
core: DataArtifactCorePM
|
|
20
|
+
|
|
21
|
+
text: str
|
|
22
|
+
meta: str | None = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SrcCodeRefPM(BaseModel):
|
|
26
|
+
kind: Literal["src_code_ref"] = "src_code_ref"
|
|
27
|
+
core: DataArtifactCorePM
|
|
28
|
+
|
|
29
|
+
src_code: str
|
|
30
|
+
language: str | None = None
|
|
31
|
+
file_path: str | None = None
|
|
32
|
+
iml_code: str | None = None
|
|
33
|
+
meta: str | None = None
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/domain.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
from speclogician.modeling.domain import BaseStatus
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DomainCountsPM(BaseModel):
|
|
16
|
+
# base flags
|
|
17
|
+
base_status: BaseStatus
|
|
18
|
+
base_has_state: bool
|
|
19
|
+
base_has_action: bool
|
|
20
|
+
|
|
21
|
+
# predicates
|
|
22
|
+
num_state_preds_total: int = 0
|
|
23
|
+
num_state_preds_valid_logic: int = 0
|
|
24
|
+
num_state_preds_matched: int = 0
|
|
25
|
+
|
|
26
|
+
num_action_preds_total: int = 0
|
|
27
|
+
num_action_preds_valid_logic: int = 0
|
|
28
|
+
num_action_preds_matched: int = 0
|
|
29
|
+
|
|
30
|
+
num_preds_total: int = 0
|
|
31
|
+
num_preds_valid_logic: int = 0
|
|
32
|
+
num_preds_matched: int = 0
|
|
33
|
+
|
|
34
|
+
# transitions
|
|
35
|
+
num_trans_total: int = 0
|
|
36
|
+
num_trans_valid_logic: int = 0
|
|
37
|
+
num_trans_matched: int = 0
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DomainCodePM(BaseModel):
|
|
41
|
+
base: str = ""
|
|
42
|
+
state_preds_iml: str = ""
|
|
43
|
+
action_preds_iml: str = ""
|
|
44
|
+
transitions_iml: str = ""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class DomainModelPM(BaseModel):
|
|
48
|
+
kind: Literal["domain_model"] = "domain_model"
|
|
49
|
+
counts: DomainCountsPM
|
|
50
|
+
code: DomainCodePM
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/instances_list.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from speclogician.presentation.models.state_instance_summary import StateInstanceSummaryPM
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class InstancesListRowPM(BaseModel):
|
|
16
|
+
state_label: str # "latest" or index string
|
|
17
|
+
changes: str # already formatted (short_str / class name join)
|
|
18
|
+
summary: StateInstanceSummaryPM
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class InstancesListPM(BaseModel):
|
|
22
|
+
kind: Literal["instances_list"] = "instances_list"
|
|
23
|
+
rows: list[InstancesListRowPM] = Field(default_factory=list[InstancesListRowPM])
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/predicate.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from speclogician.modeling.predicates import PredicateType
|
|
15
|
+
from speclogician.utils import IMLValidity
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LinkedArtifactsPM(BaseModel):
|
|
19
|
+
total: int = 0
|
|
20
|
+
test_traces: int = 0
|
|
21
|
+
log_traces: int = 0
|
|
22
|
+
doc_refs: int = 0
|
|
23
|
+
src_code_refs: int = 0
|
|
24
|
+
unresolved_ids: int = 0
|
|
25
|
+
art_ids: list[str] = Field(default_factory=list)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PredicatePM(BaseModel):
|
|
29
|
+
kind: Literal["state_predicate", "action_predicate"] # matches your model
|
|
30
|
+
comp_id: str
|
|
31
|
+
name: str
|
|
32
|
+
last_updated: datetime
|
|
33
|
+
|
|
34
|
+
pred_type: PredicateType
|
|
35
|
+
signature: str
|
|
36
|
+
|
|
37
|
+
src_code: str = ""
|
|
38
|
+
iml: str = ""
|
|
39
|
+
|
|
40
|
+
is_iml_valid: IMLValidity = IMLValidity.UNKNOWN
|
|
41
|
+
iml_error: str | None = None
|
|
42
|
+
|
|
43
|
+
links: LinkedArtifactsPM = Field(default_factory=LinkedArtifactsPM)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TransitionPM(BaseModel):
|
|
47
|
+
kind: Literal["transition"] = "transition"
|
|
48
|
+
comp_id: str
|
|
49
|
+
name: str
|
|
50
|
+
last_updated: datetime
|
|
51
|
+
|
|
52
|
+
signature: str
|
|
53
|
+
|
|
54
|
+
src_code: str = ""
|
|
55
|
+
iml: str = ""
|
|
56
|
+
|
|
57
|
+
is_iml_valid: IMLValidity = IMLValidity.UNKNOWN
|
|
58
|
+
iml_error: str | None = None
|
|
59
|
+
|
|
60
|
+
links: LinkedArtifactsPM = Field(default_factory=LinkedArtifactsPM)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/recommendations.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Literal
|
|
11
|
+
from pydantic import BaseModel, Field
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
RecommendationKind = Literal["error", "warning", "next", "info"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RecommendationPM(BaseModel):
|
|
18
|
+
kind: RecommendationKind = "next"
|
|
19
|
+
priority: int = 50 # lower = higher priority
|
|
20
|
+
text: str
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RecommendationsPM(BaseModel):
|
|
24
|
+
"""
|
|
25
|
+
A presentable bundle of recommendations (already deduped/sorted upstream).
|
|
26
|
+
"""
|
|
27
|
+
count: int = 0
|
|
28
|
+
items: list[RecommendationPM] = Field(default_factory=list)
|
|
29
|
+
|
|
30
|
+
# Optional: quick counts by kind (useful for compact views)
|
|
31
|
+
num_error: int = 0
|
|
32
|
+
num_warning: int = 0
|
|
33
|
+
num_next: int = 0
|
|
34
|
+
num_info: int = 0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/scenario.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ScenarioStatusPM(BaseModel):
|
|
14
|
+
kind: Literal["valid", "missing", "inconsistent"]
|
|
15
|
+
missing_preds: list[str] = Field(default_factory=list)
|
|
16
|
+
missing_trans: list[str] = Field(default_factory=list)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ScenarioPM(BaseModel):
|
|
20
|
+
comp_id: str
|
|
21
|
+
name: str
|
|
22
|
+
|
|
23
|
+
status: ScenarioStatusPM
|
|
24
|
+
|
|
25
|
+
given: list[str] = Field(default_factory=list)
|
|
26
|
+
when: list[str] = Field(default_factory=list)
|
|
27
|
+
then: list[str] = Field(default_factory=list)
|
|
28
|
+
|
|
29
|
+
given_preds_consistent: bool = True
|
|
30
|
+
when_preds_consistent: bool = True
|
|
31
|
+
all_preds_consistent: bool = True
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/scenario_complement.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ScenarioComplementRegionPM(BaseModel):
|
|
14
|
+
"""
|
|
15
|
+
Lightweight representation of a single region.
|
|
16
|
+
|
|
17
|
+
We store:
|
|
18
|
+
- fp: stable-ish short fingerprint (from modeling/complement.py)
|
|
19
|
+
- invariant/model/model_eval/constraints: optional strings for display
|
|
20
|
+
"""
|
|
21
|
+
fp: str
|
|
22
|
+
|
|
23
|
+
num_constraints: int = 0
|
|
24
|
+
invariant: str | None = None
|
|
25
|
+
model: str | None = None
|
|
26
|
+
model_eval: str | None = None
|
|
27
|
+
|
|
28
|
+
# optional: include a few constraints for preview
|
|
29
|
+
constraints_preview: list[str] = []
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ScenarioComplementPM(BaseModel):
|
|
33
|
+
kind: Literal["scenario_complement"] = "scenario_complement"
|
|
34
|
+
|
|
35
|
+
count_regions: int = 0
|
|
36
|
+
|
|
37
|
+
# a small sample for UI
|
|
38
|
+
regions_preview: list[ScenarioComplementRegionPM] = []
|
|
39
|
+
|
|
40
|
+
regions_all: list[ScenarioComplementRegionPM] | None = None
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/smart_find.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from speclogician.presentation.models.trace import TestTracePM, LogTracePM
|
|
13
|
+
from speclogician.presentation.models.data_artifact import DocRefPM, SrcCodeRefPM
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SmartFindCountsPM(BaseModel):
|
|
17
|
+
needle: str
|
|
18
|
+
num_test_traces: int = 0
|
|
19
|
+
num_log_traces: int = 0
|
|
20
|
+
num_doc_refs: int = 0
|
|
21
|
+
num_src_code_refs: int = 0
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SmartFindItemsPM(BaseModel):
|
|
25
|
+
test_traces: list[TestTracePM] = Field(default_factory=list)
|
|
26
|
+
log_traces: list[LogTracePM] = Field(default_factory=list)
|
|
27
|
+
doc_refs: list[DocRefPM] = Field(default_factory=list)
|
|
28
|
+
src_code_refs: list[SrcCodeRefPM] = Field(default_factory=list)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SmartFindPM(BaseModel):
|
|
32
|
+
kind: Literal["smart_find"] = "smart_find"
|
|
33
|
+
counts: SmartFindCountsPM
|
|
34
|
+
items: SmartFindItemsPM
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/spec.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
from speclogician.presentation.models.domain import DomainModelPM
|
|
13
|
+
from speclogician.presentation.models.scenario_complement import ScenarioComplementPM
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SpecCountsPM(BaseModel):
|
|
17
|
+
num_sc_total: int = 0
|
|
18
|
+
num_sc_missing: int = 0
|
|
19
|
+
num_sc_matched: int = 0
|
|
20
|
+
num_sc_inconsistent: int = 0
|
|
21
|
+
num_sc_conflicted: int = 0
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SpecPM(BaseModel):
|
|
25
|
+
kind: Literal["spec"] = "spec"
|
|
26
|
+
domain: DomainModelPM
|
|
27
|
+
counts: SpecCountsPM
|
|
28
|
+
|
|
29
|
+
# cheap “list view” for CLI
|
|
30
|
+
scenario_names: list[str] = []
|
|
31
|
+
|
|
32
|
+
scenario_complement: ScenarioComplementPM | None = None
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/state_diff.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any, Literal
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from speclogician.state.diff import ComparisonOutcome
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DiffRowPM(BaseModel):
|
|
16
|
+
label: str
|
|
17
|
+
before: Any
|
|
18
|
+
after: Any
|
|
19
|
+
outcome: ComparisonOutcome = ComparisonOutcome.UNKNOWN
|
|
20
|
+
message: str = ""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class DiffSectionPM(BaseModel):
|
|
24
|
+
title: str
|
|
25
|
+
rows: list[DiffRowPM] = Field(default_factory=list)
|
|
26
|
+
|
|
27
|
+
def empty(self) -> bool:
|
|
28
|
+
return not self.rows
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StateDiffPM(BaseModel):
|
|
32
|
+
kind: Literal["state_diff"] = "state_diff"
|
|
33
|
+
has_changes: bool
|
|
34
|
+
sections: list[DiffSectionPM] = Field(default_factory=list)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Imandra Inc.
|
|
3
|
+
#
|
|
4
|
+
# speclogician/presentation/models/state_instance.py
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Literal
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from speclogician.presentation.models.state_instance_summary import StateInstanceSummaryPM
|
|
14
|
+
from speclogician.presentation.models.spec import SpecPM
|
|
15
|
+
from speclogician.presentation.models.container import ArtifactContainerPM
|
|
16
|
+
from speclogician.presentation.models.state_diff import StateDiffPM
|
|
17
|
+
from speclogician.presentation.models.recommendations import RecommendationsPM
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StateInstancePM(BaseModel):
|
|
21
|
+
kind: Literal["state_instance"] = "state_instance"
|
|
22
|
+
|
|
23
|
+
summary: StateInstanceSummaryPM
|
|
24
|
+
|
|
25
|
+
# Optional heavy sections
|
|
26
|
+
spec: SpecPM | None = None
|
|
27
|
+
artifacts: ArtifactContainerPM | None = None
|
|
28
|
+
state_diff: StateDiffPM | None = None
|
|
29
|
+
|
|
30
|
+
# Recommendations (computed after change/diff)
|
|
31
|
+
recommendations: RecommendationsPM
|