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.
- speclogician/agent/funcs.py +29 -0
- speclogician/cmd/agent_cmd.py +89 -0
- speclogician/cmd/data_cmd.py +24 -0
- speclogician/cmd/model_cmd.py +42 -0
- speclogician/cmd/overlay_cmd.py +30 -0
- speclogician/cmd/scenario_cmd.py +61 -0
- speclogician/cmd/state_cmd.py +52 -0
- speclogician/data/artifact.py +8 -50
- speclogician/data/container.py +18 -384
- speclogician/data/mapping.py +18 -17
- speclogician/data/refs.py +12 -11
- speclogician/data/reports.py +11 -0
- speclogician/data/traces.py +15 -6
- speclogician/llms/llmtools.py +102 -0
- speclogician/llms/overlay.py +264 -0
- speclogician/main.py +36 -102
- speclogician/modeling/__init__.py +0 -31
- speclogician/modeling/component.py +4 -60
- speclogician/modeling/conflict.py +5 -19
- speclogician/modeling/domain.py +93 -280
- speclogician/modeling/model.py +206 -0
- speclogician/modeling/predicates.py +20 -22
- speclogician/modeling/report.py +33 -0
- speclogician/modeling/scenario.py +119 -87
- speclogician/sl_cmd.py +76 -0
- speclogician/state/change.py +98 -378
- speclogician/state/state.py +183 -399
- speclogician/tui/box.tcss +10 -0
- speclogician/tui/tui.py +131 -0
- speclogician/utils/__init__.py +1 -70
- speclogician/utils/imx.py +195 -0
- speclogician/utils/load.py +25 -147
- speclogician/utils/prompt.md +1 -325
- speclogician-0.0.0.dev1.dist-info/METADATA +21 -0
- speclogician-0.0.0.dev1.dist-info/RECORD +43 -0
- speclogician/commands/__init__.py +0 -15
- speclogician/commands/cmd_ch.py +0 -616
- speclogician/commands/cmd_find.py +0 -256
- speclogician/commands/cmd_view.py +0 -202
- speclogician/commands/runner.py +0 -149
- speclogician/commands/utils.py +0 -101
- speclogician/demos/.DS_Store +0 -0
- speclogician/demos/cmd_demo.py +0 -278
- speclogician/demos/loader.py +0 -135
- speclogician/demos/model.py +0 -27
- speclogician/demos/runner.py +0 -51
- speclogician/logic/__init__.py +0 -11
- speclogician/logic/api/__init__.py +0 -29
- speclogician/logic/api/client.py +0 -606
- speclogician/logic/api/decomp.py +0 -67
- speclogician/logic/api/scenario.py +0 -102
- speclogician/logic/api/traces.py +0 -59
- speclogician/logic/lib/__init__.py +0 -19
- speclogician/logic/lib/complement.py +0 -107
- speclogician/logic/lib/domain_model.py +0 -59
- speclogician/logic/lib/predicates.py +0 -151
- speclogician/logic/lib/scenarios.py +0 -369
- speclogician/logic/lib/traces.py +0 -114
- speclogician/logic/lib/transitions.py +0 -104
- speclogician/logic/main.py +0 -246
- speclogician/logic/strings.py +0 -194
- speclogician/logic/utils.py +0 -135
- speclogician/modeling/complement.py +0 -104
- speclogician/modeling/spec.py +0 -306
- speclogician/modeling/spec_stats.py +0 -39
- speclogician/presentation/api.py +0 -244
- speclogician/presentation/builders/_links.py +0 -44
- speclogician/presentation/builders/container.py +0 -53
- speclogician/presentation/builders/data_artifact.py +0 -42
- speclogician/presentation/builders/domain.py +0 -54
- speclogician/presentation/builders/instances_list.py +0 -38
- speclogician/presentation/builders/predicate.py +0 -51
- speclogician/presentation/builders/recommendations.py +0 -41
- speclogician/presentation/builders/scenario.py +0 -41
- speclogician/presentation/builders/scenario_complement.py +0 -82
- speclogician/presentation/builders/smart_find.py +0 -39
- speclogician/presentation/builders/spec.py +0 -39
- speclogician/presentation/builders/state_diff.py +0 -150
- speclogician/presentation/builders/state_instance.py +0 -42
- speclogician/presentation/builders/state_instance_summary.py +0 -84
- speclogician/presentation/builders/trace.py +0 -58
- speclogician/presentation/ctx.py +0 -38
- speclogician/presentation/models/container.py +0 -44
- speclogician/presentation/models/data_artifact.py +0 -33
- speclogician/presentation/models/domain.py +0 -50
- speclogician/presentation/models/instances_list.py +0 -23
- speclogician/presentation/models/predicate.py +0 -60
- speclogician/presentation/models/recommendations.py +0 -34
- speclogician/presentation/models/scenario.py +0 -31
- speclogician/presentation/models/scenario_complement.py +0 -40
- speclogician/presentation/models/smart_find.py +0 -34
- speclogician/presentation/models/spec.py +0 -32
- speclogician/presentation/models/state_diff.py +0 -34
- speclogician/presentation/models/state_instance.py +0 -31
- speclogician/presentation/models/state_instance_summary.py +0 -102
- speclogician/presentation/models/trace.py +0 -42
- speclogician/presentation/preview/__init__.py +0 -13
- speclogician/presentation/preview/cli.py +0 -50
- speclogician/presentation/preview/fixtures/__init__.py +0 -205
- speclogician/presentation/preview/fixtures/artifact_container.py +0 -150
- speclogician/presentation/preview/fixtures/data_artifact.py +0 -144
- speclogician/presentation/preview/fixtures/domain_model.py +0 -162
- speclogician/presentation/preview/fixtures/instances_list.py +0 -162
- speclogician/presentation/preview/fixtures/predicate.py +0 -184
- speclogician/presentation/preview/fixtures/scenario.py +0 -84
- speclogician/presentation/preview/fixtures/scenario_complement.py +0 -81
- speclogician/presentation/preview/fixtures/smart_find.py +0 -140
- speclogician/presentation/preview/fixtures/spec.py +0 -95
- speclogician/presentation/preview/fixtures/state_diff.py +0 -158
- speclogician/presentation/preview/fixtures/state_instance.py +0 -128
- speclogician/presentation/preview/fixtures/state_instance_summary.py +0 -80
- speclogician/presentation/preview/fixtures/trace.py +0 -206
- speclogician/presentation/preview/registry.py +0 -42
- speclogician/presentation/renderers/__init__.py +0 -24
- speclogician/presentation/renderers/container.py +0 -136
- speclogician/presentation/renderers/data_artifact.py +0 -144
- speclogician/presentation/renderers/domain.py +0 -123
- speclogician/presentation/renderers/instances_list.py +0 -120
- speclogician/presentation/renderers/predicate.py +0 -180
- speclogician/presentation/renderers/recommendations.py +0 -90
- speclogician/presentation/renderers/scenario.py +0 -94
- speclogician/presentation/renderers/scenario_complement.py +0 -59
- speclogician/presentation/renderers/smart_find.py +0 -307
- speclogician/presentation/renderers/spec.py +0 -105
- speclogician/presentation/renderers/state_diff.py +0 -102
- speclogician/presentation/renderers/state_instance.py +0 -82
- speclogician/presentation/renderers/state_instance_summary.py +0 -143
- speclogician/presentation/renderers/trace.py +0 -122
- speclogician/shell/app.py +0 -170
- speclogician/shell/shell_ch.py +0 -263
- speclogician/shell/shell_view.py +0 -153
- speclogician/state/change_result.py +0 -32
- speclogician/state/diff.py +0 -191
- speclogician/state/inst.py +0 -574
- speclogician/state/recommendation.py +0 -13
- speclogician/state/recommender.py +0 -577
- speclogician/state/state_stats.py +0 -133
- speclogician/tui/__init__.py +0 -0
- speclogician/tui/app.py +0 -257
- speclogician/tui/app.tcss +0 -160
- speclogician/tui/demo.py +0 -45
- speclogician/tui/images/speclogician-full.png +0 -0
- speclogician/tui/images/speclogician-minimal.png +0 -0
- speclogician/tui/main_screen.py +0 -454
- speclogician/tui/splash_screen.py +0 -51
- speclogician/tui/stats_screen.py +0 -125
- speclogician/utils/testing.py +0 -151
- speclogician-0.0.0b1.dist-info/METADATA +0 -116
- speclogician-0.0.0b1.dist-info/RECORD +0 -139
- /speclogician/{presentation → agent}/__init__.py +0 -0
- /speclogician/{presentation/builders → cmd}/__init__.py +0 -0
- /speclogician/{presentation/models → llms}/__init__.py +0 -0
- {speclogician-0.0.0b1.dist-info → speclogician-0.0.0.dev1.dist-info}/WHEEL +0 -0
speclogician/shell/shell_view.py
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Imandra Inc.
|
|
3
|
-
#
|
|
4
|
-
# speclogician/shell/shell_view.py
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
import json
|
|
10
|
-
from cmd2 import Cmd, with_argparser
|
|
11
|
-
import argparse
|
|
12
|
-
|
|
13
|
-
from speclogician.presentation.ctx import RenderCtx
|
|
14
|
-
from speclogician.presentation.api import (
|
|
15
|
-
present_state_instance,
|
|
16
|
-
present_spec,
|
|
17
|
-
present_domain_model,
|
|
18
|
-
present_artifact_container,
|
|
19
|
-
present_instances_list,
|
|
20
|
-
)
|
|
21
|
-
from speclogician.utils import console
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _mk_ctx(args) -> RenderCtx:
|
|
25
|
-
return RenderCtx(
|
|
26
|
-
compact=getattr(args, "compact", False),
|
|
27
|
-
show_stats_only=getattr(args, "stats_only", False),
|
|
28
|
-
show_code=not getattr(args, "no_code", False),
|
|
29
|
-
show_ids=getattr(args, "ids", False),
|
|
30
|
-
show_art_ids=getattr(args, "art_ids", False),
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class ViewShell(Cmd):
|
|
35
|
-
prompt = "sl:view> "
|
|
36
|
-
allow_cli_args = False
|
|
37
|
-
|
|
38
|
-
def __init__(self, parent_shell, *args, **kwargs):
|
|
39
|
-
super().__init__(*args, **kwargs)
|
|
40
|
-
self.parent = parent_shell
|
|
41
|
-
self.rich = console
|
|
42
|
-
|
|
43
|
-
# ---- shared flags for all view commands ----
|
|
44
|
-
def _add_common(self, p: argparse.ArgumentParser) -> None:
|
|
45
|
-
p.add_argument("--idx", type=int, default=0)
|
|
46
|
-
p.add_argument("--json", action="store_true")
|
|
47
|
-
p.add_argument("--compact", action="store_true")
|
|
48
|
-
p.add_argument("--stats-only", dest="stats_only", action="store_true")
|
|
49
|
-
p.add_argument("--no-code", action="store_true")
|
|
50
|
-
p.add_argument("--ids", action="store_true")
|
|
51
|
-
p.add_argument("--art-ids", dest="art_ids", action="store_true")
|
|
52
|
-
|
|
53
|
-
def _emit(self, x, *, json_only: bool) -> None:
|
|
54
|
-
if json_only:
|
|
55
|
-
self.rich.print_json(json.dumps(x, indent=2, default=str))
|
|
56
|
-
else:
|
|
57
|
-
self.rich.print(x)
|
|
58
|
-
|
|
59
|
-
def do_back(self, _arg) -> bool:
|
|
60
|
-
"""Return to main shell."""
|
|
61
|
-
return True
|
|
62
|
-
|
|
63
|
-
do_exit = do_back
|
|
64
|
-
do_quit = do_back
|
|
65
|
-
|
|
66
|
-
# ----------------------
|
|
67
|
-
# view state/spec/domain/artifacts/instances
|
|
68
|
-
# ----------------------
|
|
69
|
-
|
|
70
|
-
state_p = argparse.ArgumentParser()
|
|
71
|
-
_ = state_p.add_argument
|
|
72
|
-
# common
|
|
73
|
-
# (cmd2 doesn't support easy composition; just call helper)
|
|
74
|
-
# We'll patch it in __init__? easiest: do it here:
|
|
75
|
-
# (but need self, so do it in method; use a helper below instead)
|
|
76
|
-
|
|
77
|
-
@with_argparser(argparse.ArgumentParser())
|
|
78
|
-
def do_state(self, args) -> None:
|
|
79
|
-
"""View full state instance."""
|
|
80
|
-
if self.parent.state is None:
|
|
81
|
-
self.perror("No state loaded.")
|
|
82
|
-
return
|
|
83
|
-
|
|
84
|
-
# build parser on the fly so we can reuse helper
|
|
85
|
-
p = argparse.ArgumentParser()
|
|
86
|
-
self._add_common(p)
|
|
87
|
-
a = p.parse_args(args.argv)
|
|
88
|
-
|
|
89
|
-
si = self.parent.state.instances[a.idx]
|
|
90
|
-
rctx = _mk_ctx(a)
|
|
91
|
-
out = present_state_instance(si, ctx=rctx, json_only=a.json)
|
|
92
|
-
self._emit(out, json_only=a.json)
|
|
93
|
-
|
|
94
|
-
@with_argparser(argparse.ArgumentParser())
|
|
95
|
-
def do_spec(self, args) -> None:
|
|
96
|
-
if self.parent.state is None:
|
|
97
|
-
self.perror("No state loaded.")
|
|
98
|
-
return
|
|
99
|
-
p = argparse.ArgumentParser()
|
|
100
|
-
self._add_common(p)
|
|
101
|
-
a = p.parse_args(args.argv)
|
|
102
|
-
|
|
103
|
-
si = self.parent.state.instances[a.idx]
|
|
104
|
-
rctx = _mk_ctx(a)
|
|
105
|
-
out = present_spec(si.spec, ctx=rctx, json_only=a.json)
|
|
106
|
-
self._emit(out, json_only=a.json)
|
|
107
|
-
|
|
108
|
-
@with_argparser(argparse.ArgumentParser())
|
|
109
|
-
def do_domain(self, args) -> None:
|
|
110
|
-
if self.parent.state is None:
|
|
111
|
-
self.perror("No state loaded.")
|
|
112
|
-
return
|
|
113
|
-
p = argparse.ArgumentParser()
|
|
114
|
-
self._add_common(p)
|
|
115
|
-
a = p.parse_args(args.argv)
|
|
116
|
-
|
|
117
|
-
si = self.parent.state.instances[a.idx]
|
|
118
|
-
rctx = _mk_ctx(a)
|
|
119
|
-
out = present_domain_model(si.spec.domain_model, ctx=rctx, json_only=a.json)
|
|
120
|
-
self._emit(out, json_only=a.json)
|
|
121
|
-
|
|
122
|
-
@with_argparser(argparse.ArgumentParser())
|
|
123
|
-
def do_artifacts(self, args) -> None:
|
|
124
|
-
if self.parent.state is None:
|
|
125
|
-
self.perror("No state loaded.")
|
|
126
|
-
return
|
|
127
|
-
p = argparse.ArgumentParser()
|
|
128
|
-
self._add_common(p)
|
|
129
|
-
a = p.parse_args(args.argv)
|
|
130
|
-
|
|
131
|
-
si = self.parent.state.instances[a.idx]
|
|
132
|
-
rctx = _mk_ctx(a)
|
|
133
|
-
out = present_artifact_container(si.art_container, ctx=rctx, json_only=a.json)
|
|
134
|
-
self._emit(out, json_only=a.json)
|
|
135
|
-
|
|
136
|
-
@with_argparser(argparse.ArgumentParser())
|
|
137
|
-
def do_instances(self, args) -> None:
|
|
138
|
-
if self.parent.state is None:
|
|
139
|
-
self.perror("No state loaded.")
|
|
140
|
-
return
|
|
141
|
-
p = argparse.ArgumentParser()
|
|
142
|
-
# instances view doesn’t need --idx but keep flags consistent:
|
|
143
|
-
p.add_argument("--json", action="store_true")
|
|
144
|
-
p.add_argument("--compact", action="store_true")
|
|
145
|
-
p.add_argument("--stats-only", dest="stats_only", action="store_true")
|
|
146
|
-
p.add_argument("--no-code", action="store_true")
|
|
147
|
-
p.add_argument("--ids", action="store_true")
|
|
148
|
-
p.add_argument("--art-ids", dest="art_ids", action="store_true")
|
|
149
|
-
a = p.parse_args(args.argv)
|
|
150
|
-
|
|
151
|
-
rctx = _mk_ctx(a)
|
|
152
|
-
out = present_instances_list(self.parent.state.instances, ctx=rctx, json_only=a.json)
|
|
153
|
-
self._emit(out, json_only=a.json)
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Imandra Inc.
|
|
3
|
-
#
|
|
4
|
-
# speclogician/state/change_result.py
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
from __future__ import annotations
|
|
8
|
-
|
|
9
|
-
from typing import Literal, TypedDict
|
|
10
|
-
|
|
11
|
-
from ..state.change import StateChange
|
|
12
|
-
from ..state.inst import StateInstance
|
|
13
|
-
from ..state.diff import StateDiff
|
|
14
|
-
from typing import Union
|
|
15
|
-
|
|
16
|
-
class ProcessChangeError(TypedDict):
|
|
17
|
-
ok: Literal[False]
|
|
18
|
-
stage: Literal["apply_change", "analyze_change", "calc_diff", "refresh_stats"]
|
|
19
|
-
error: Exception
|
|
20
|
-
change: StateChange
|
|
21
|
-
old_state: StateInstance
|
|
22
|
-
|
|
23
|
-
class ProcessChangeSuccess(TypedDict):
|
|
24
|
-
ok: Literal[True]
|
|
25
|
-
stage: Literal["ok"]
|
|
26
|
-
change: StateChange
|
|
27
|
-
old_state: StateInstance
|
|
28
|
-
new_state: StateInstance
|
|
29
|
-
state_diff: StateDiff | None # this is because it could potentially be the first state instance
|
|
30
|
-
new_num_instances: int
|
|
31
|
-
|
|
32
|
-
ProcessChangeResult = Union[ProcessChangeError, ProcessChangeSuccess]
|
speclogician/state/diff.py
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
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
|