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
@@ -0,0 +1,29 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # agent.py
5
+ #
6
+
7
+
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ from ..state.state import State
12
+ from ..llms.llmtools import test_formalizer
13
+ from ..llms.overlay import Overlay
14
+
15
+ def process_test_file (
16
+ path : Path,
17
+ state : State,
18
+ overlay : Overlay
19
+ ) -> State:
20
+ """
21
+ Process a file state to the state
22
+ """
23
+
24
+ try:
25
+ tf = test_formalizer (str(path), overlay, state)
26
+ except Exception as e:
27
+ raise Exception (f"Failed to process test file: []")
28
+
29
+ return state.add_test_formalization(tf)
@@ -0,0 +1,89 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # agent_cmd.py
5
+ #
6
+
7
+ import typer
8
+ import os
9
+ from pathlib import Path
10
+ from typing import Annotated
11
+
12
+ from rich.progress import track
13
+
14
+ from ..llms.overlay import Overlays
15
+ from ..agent.funcs import process_test_file
16
+ from ..state.state import State
17
+ from ..utils import console
18
+ from ..utils.load import load_overlays, load_state
19
+
20
+ app = typer.Typer()
21
+
22
+
23
+ @app.command(help="Add a single file to the formalization state")
24
+ def proc_test_file (
25
+ filepath : Annotated[str, typer.Argument()],
26
+ overlay_name : Annotated[str, typer.Argument(help="Overlay to use. It should also contain the file extension we'll use")]
27
+ ):
28
+
29
+ overlays = load_overlays()
30
+ state = load_state()
31
+
32
+ tgt_path = Path(filepath).parent / filepath
33
+
34
+ overlay = overlays.get(overlay_name)
35
+ if overlay is None:
36
+ console.print(f":warning: Could not find an overlay named {overlay_name}!")
37
+ return
38
+
39
+ try:
40
+ process_test_file(tgt_path, state, overlay)
41
+ except Exception as e:
42
+ console.print(f"🛑 Caught an error when adding file: {e}")
43
+ return
44
+
45
+ # Add the state definition here
46
+
47
+ typer.secho(f"✅ Successfully added {filepath} to the formalization state!")
48
+
49
+ @app.command(help="Run full cycle formalization for a specified directory")
50
+ def proc_test_dir (
51
+ dirpath : Annotated[str, typer.Argument(help="Target directory with tests that should be formalized")],
52
+ overlay_name : Annotated[str, typer.Argument(help="Overlay to use. It should also contain the file extension we'll use")],
53
+ clean : Annotated[bool, typer.Option(help="Should we override any tests from these files already present in the state?")] = False
54
+ ):
55
+
56
+ state = load_state()
57
+
58
+ overlays = load_overlays()
59
+ overlay = overlays.get(overlay_name)
60
+
61
+ if overlay is None:
62
+ typer.secho(f"🛑 Could not find an overlay named {overlay_name}!", err=True)
63
+ return
64
+
65
+ filepaths = os.listdir(dirpath)
66
+ filepaths = list(filter(lambda x: x.endswith(overlay.ext.strip()), filepaths))
67
+
68
+ console.print(f"Identified {len(filepaths)} to process")
69
+
70
+ count = 0
71
+
72
+ for i in track(range(len(filepaths)), description=f"Processing {dirpath}..."):
73
+
74
+ try:
75
+ process_test_file(Path(filepaths[i]), state, overlay)
76
+ except Exception as e:
77
+ console.print(f"Failed on {filepaths[i]}: {e}")
78
+
79
+ count += 1
80
+
81
+ console.print(f":robot:Processed {count} files!")
82
+
83
+ try:
84
+ state.save(dirpath)
85
+ except Exception as e:
86
+ typer.echo(f"🛑 Caught error when saving the formalization state: {e}")
87
+ return
88
+
89
+ typer.secho(f"✅ Successfully saved the formalization state to {dirpath}")
@@ -0,0 +1,24 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # data_cmd.py
5
+ #
6
+
7
+ import typer
8
+ from typing import Annotated
9
+
10
+ app = typer.Typer()
11
+
12
+ @app.command(name="list")
13
+ def data_list():
14
+ """
15
+ List the available data sources
16
+ """
17
+ pass
18
+
19
+ tests_app = typer.Typer()
20
+ @tests_app.command(name="tests")
21
+ def list (
22
+ max_num_tests : Annotated[int, typer.Argument(help="Maximum number of tests to displayed")]
23
+ ):
24
+ pass
@@ -0,0 +1,42 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # model_cmd.py
5
+ #
6
+
7
+ import typer
8
+ from typing import Annotated
9
+ from rich.syntax import Syntax
10
+
11
+ from ..utils import console
12
+ from ..utils.load import load_state
13
+
14
+ app = typer.Typer()
15
+
16
+ @app.command(name="summary", help="")
17
+ def summary():
18
+ """
19
+ """
20
+
21
+ state = load_state()
22
+
23
+ console.print(state.curr_state().model.report())
24
+
25
+ @app.command(name="code", help="Generate the IML code for the Domain Model")
26
+ def get_code(
27
+ filepath : Annotated[str|None, typer.Option(help="Output filepath")] = None
28
+ ):
29
+
30
+ state = load_state()
31
+
32
+ console.print(Syntax(state.curr_state().model.domain_model.to_iml(), "OCaml"))
33
+
34
+ if filepath is not None:
35
+ try:
36
+ with open(filepath, 'w') as outfile:
37
+ print(state.curr_state().model.domain_model.to_iml(), file=outfile)
38
+ except Exception as e:
39
+ console.print(f"🛑 Failed to write domain model to disk: {e}",)
40
+ return
41
+
42
+ console.print(f"✅ Successfully wrote domain model to disk: {filepath}")
@@ -0,0 +1,30 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # overlay_cmd.py
5
+ #
6
+
7
+ from typing import Annotated
8
+ from rich import print as printr
9
+ import typer
10
+
11
+ from ..utils.load import load_overlays
12
+
13
+ app = typer.Typer()
14
+
15
+ @app.command(name="list", help="list the available overlays")
16
+ def list_():
17
+ overlays = load_overlays()
18
+ overlays.list_overlays()
19
+
20
+ @app.command(name="view", help="View individual template")
21
+ def view(
22
+ name : Annotated[str, typer.Argument(help="Name of the template to view")]
23
+ ):
24
+
25
+ overlays = load_overlays()
26
+ if name not in overlays.names():
27
+ typer.secho(f"🛑 No template with name {name} found!", err=True)
28
+ return
29
+
30
+ printr(overlays.get(name))
@@ -0,0 +1,61 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # scenario_cmd.py
5
+ #
6
+
7
+ import typer
8
+
9
+ from ..state.state import State
10
+ from ..utils.load import load_state
11
+
12
+ from typing import Annotated
13
+
14
+
15
+ app = typer.Typer()
16
+
17
+ @app.command(name="summary", help="Summary of the available scenarios")
18
+ def summary():
19
+ """
20
+ """
21
+
22
+ state = load_state()
23
+
24
+ @app.command(name="view", help="View a specific scenario")
25
+ def view(
26
+ sc_id : int,
27
+ scenario_name : str
28
+ ):
29
+ """
30
+ """
31
+
32
+ state = load_state()
33
+
34
+ @app.command(name="rm", help="Remove a scenario")
35
+ def rm_scenario():
36
+ """
37
+ """
38
+
39
+ state = load_state()
40
+
41
+ @app.command(name="add", help="Add a scenario")
42
+ def add_scenario(
43
+ name : Annotated[str, typer.Argument(help="Name to be given to the scenario, must be unique")]
44
+ ):
45
+ """
46
+ """
47
+ state = load_state()
48
+
49
+ @app.command(name="edit", help="Edit a scenario")
50
+ def edit_scenario():
51
+ """
52
+ """
53
+
54
+ state = load_state()
55
+
56
+ @app.command(name="search", help="Search for a particular scenario by predicate/transition functions")
57
+ def search(q : str):
58
+ """
59
+ """
60
+
61
+ state = load_state()
@@ -0,0 +1,52 @@
1
+ #
2
+ # Imandra Inc.
3
+ #
4
+ # state_cmd.py
5
+ #
6
+
7
+ import typer
8
+ import sys
9
+ from typing import Annotated
10
+
11
+ from ..state.state import State
12
+ from ..utils import console
13
+ from ..utils.load import load_state
14
+
15
+ global state
16
+ state : State
17
+
18
+ app = typer.Typer()
19
+
20
+ @app.command(name="list", help="List all state instances")
21
+ def list_states (
22
+ max_num_states : Annotated[int, typer.Argument(help="Maximum number of states")]=10
23
+ ):
24
+ """
25
+ List the state instances
26
+ """
27
+ state = load_state()
28
+ console.print(state.inst_list())
29
+
30
+ @app.command(name="set", help="Set current state to a specific idx in the list")
31
+ def set (
32
+ state_idx : Annotated[int, typer.Argument(help="")]
33
+ ):
34
+
35
+ state = load_state()
36
+
37
+ try:
38
+ state.set_curr_state_idx (state_idx)
39
+ except Exception as e:
40
+ console.print(f"Caught error: {e}")
41
+ sys.exit(0)
42
+
43
+ console.print("Update current state idx to {state_idx}")
44
+
45
+ @app.command(name="summary", help="Provide summary of the current state instance")
46
+ def summary():
47
+ """
48
+ Provide a summary of the current state
49
+ """
50
+
51
+ state : State = load_state()
52
+ console.print(state.curr_state().report())
@@ -1,63 +1,21 @@
1
1
  #
2
2
  # Imandra Inc.
3
3
  #
4
- # speclogician/data/artifact.py
4
+ # artifact.py
5
5
  #
6
6
 
7
- from __future__ import annotations
8
-
9
7
  import uuid
10
- from pydantic import BaseModel, Field, field_validator
11
- from ..utils import IMLValidity
8
+ from pydantic import BaseModel, Field
12
9
 
13
10
  class Artifact(BaseModel):
14
11
  """
15
- Base class for an Artifact
16
12
  """
17
- # Assigned task ID, new one created if not provided
18
- art_id : str | None = Field(default_factory=lambda: str(uuid.uuid4()))
19
-
20
- @field_validator("art_id", mode="before")
21
- @classmethod
22
- def _coerce_none_to_uuid(cls, v:str|None):
23
- if v is None:
24
- return str(uuid.uuid4())
25
- return v
26
-
27
- class TraceIMLValidity(BaseModel):
28
- iml_valid: IMLValidity
29
- err: str | None = None
30
-
31
- class TraceScenarioMatchResult(BaseModel):
32
- scenario_name: str
33
- iml_valid: bool
34
- err: str | None = None
35
- when_matches: bool = False
36
- given_matches: bool = False
37
- transition_matches: bool = False
13
+ art_id : str = Field(default_factory=lambda: str(uuid.uuid4())) # assigned task ID, new one created if not provided
38
14
 
39
15
  class TraceArtifact(Artifact):
40
- """
41
- Concrete execution trace:
42
- - given : concrete state value
43
- - when : optional concrete action value
44
- - then : optional resulting state value
45
- """
46
-
47
- given: str # state
48
- when: str | None = None # action (optional)
49
- then: str | None = None # state (optional)
50
-
51
- iml_validity: TraceIMLValidity = Field(
52
- default_factory=lambda: TraceIMLValidity(
53
- iml_valid=IMLValidity.UNKNOWN,
54
- err=None,
55
- )
56
- )
57
- time: str = ""
16
+
17
+ given : str
18
+ when : str
19
+ then : str
58
20
 
59
- class DataArtifact(Artifact):
60
- """
61
- Data may be either source code or documentation
62
- """
63
- pass
21
+ valid_iml : bool = False