setreplace 0.1.0__cp39-abi3-win_amd64.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.
- setreplace/__init__.py +5 -0
- setreplace/__init__.pyi +123 -0
- setreplace/py.typed +0 -0
- setreplace/setreplace.pyd +0 -0
- setreplace-0.1.0.dist-info/METADATA +81 -0
- setreplace-0.1.0.dist-info/RECORD +8 -0
- setreplace-0.1.0.dist-info/WHEEL +4 -0
- setreplace-0.1.0.dist-info/sboms/setreplace-python.cyclonedx.json +2829 -0
setreplace/__init__.py
ADDED
setreplace/__init__.pyi
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Wolfram model (SetReplace) hypergraph substitution and visualization."""
|
|
2
|
+
|
|
3
|
+
from typing import Union
|
|
4
|
+
|
|
5
|
+
__version__: str
|
|
6
|
+
|
|
7
|
+
Rules = Union["Rule", str, list[Union["Rule", str]]]
|
|
8
|
+
|
|
9
|
+
class SetReplaceError(Exception):
|
|
10
|
+
"""Evolution-time failure (e.g. disconnected rule inputs)."""
|
|
11
|
+
|
|
12
|
+
class Rule:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
inputs: list[list[int | str]],
|
|
16
|
+
outputs: list[list[int | str]],
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Structured form: strings are pattern variables, ints are concrete atoms."""
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def parse(s: str) -> Rule:
|
|
22
|
+
"""Wolfram-ish text: '{{x, y}} -> {{x, y}, {y, z}}' or '{{a_, b_}} :> ...'."""
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def inputs(self) -> list[list[int]]: ...
|
|
26
|
+
@property
|
|
27
|
+
def outputs(self) -> list[list[int]]: ...
|
|
28
|
+
|
|
29
|
+
class Token:
|
|
30
|
+
atoms: list[int]
|
|
31
|
+
creator_event: int
|
|
32
|
+
destroyer_event: int | None
|
|
33
|
+
generation: int
|
|
34
|
+
|
|
35
|
+
class Event:
|
|
36
|
+
rule: int | None
|
|
37
|
+
inputs: list[int]
|
|
38
|
+
outputs: list[int]
|
|
39
|
+
generation: int
|
|
40
|
+
|
|
41
|
+
class Plot:
|
|
42
|
+
@property
|
|
43
|
+
def svg(self) -> str: ...
|
|
44
|
+
def save(self, path: str) -> None:
|
|
45
|
+
"""Writes .svg or .png by extension (PNG rasterized in-process)."""
|
|
46
|
+
def _repr_svg_(self) -> str: ...
|
|
47
|
+
|
|
48
|
+
class HypergraphSystem:
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
rules: Rules,
|
|
52
|
+
initial_state: list[list[int]],
|
|
53
|
+
*,
|
|
54
|
+
event_ordering: list[str] | None = None,
|
|
55
|
+
random_seed: int = 0,
|
|
56
|
+
) -> None: ...
|
|
57
|
+
def evolve(
|
|
58
|
+
self,
|
|
59
|
+
*,
|
|
60
|
+
max_events: int | None = None,
|
|
61
|
+
max_generations: int | None = None,
|
|
62
|
+
max_vertices: int | None = None,
|
|
63
|
+
max_vertex_degree: int | None = None,
|
|
64
|
+
max_edges: int | None = None,
|
|
65
|
+
) -> int: ...
|
|
66
|
+
def replace_once(self) -> bool: ...
|
|
67
|
+
@property
|
|
68
|
+
def final_state(self) -> list[list[int]]: ...
|
|
69
|
+
@property
|
|
70
|
+
def termination_reason(self) -> str: ...
|
|
71
|
+
@property
|
|
72
|
+
def events_count(self) -> int: ...
|
|
73
|
+
@property
|
|
74
|
+
def generations_count(self) -> int: ...
|
|
75
|
+
@property
|
|
76
|
+
def final_atom_count(self) -> int: ...
|
|
77
|
+
def state_after_event(self, k: int) -> list[list[int]]: ...
|
|
78
|
+
def states_by_event(self) -> list[list[list[int]]]: ...
|
|
79
|
+
def state_at_generation(self, g: int) -> list[list[int]]: ...
|
|
80
|
+
def max_complete_generation(self) -> int: ...
|
|
81
|
+
def tokens(self) -> list[Token]: ...
|
|
82
|
+
def events(self) -> list[Event]: ...
|
|
83
|
+
def causal_graph_edges(self, include_initial: bool = False) -> list[tuple[int, int]]: ...
|
|
84
|
+
def causal_graph_dot(self, include_initial: bool = False) -> str: ...
|
|
85
|
+
def plot(
|
|
86
|
+
self,
|
|
87
|
+
*,
|
|
88
|
+
labels: bool | dict[int, str] | None = None,
|
|
89
|
+
seed: int = 0,
|
|
90
|
+
width: float = 478.0,
|
|
91
|
+
) -> Plot: ...
|
|
92
|
+
def causal_graph_plot(
|
|
93
|
+
self, *, include_initial: bool = False, width: float = 478.0
|
|
94
|
+
) -> Plot: ...
|
|
95
|
+
|
|
96
|
+
def plot(
|
|
97
|
+
edges: list[list[int]],
|
|
98
|
+
*,
|
|
99
|
+
labels: bool | dict[int, str] | None = None,
|
|
100
|
+
seed: int = 0,
|
|
101
|
+
width: float = 478.0,
|
|
102
|
+
) -> Plot: ...
|
|
103
|
+
def layout(edges: list[list[int]], *, seed: int = 0) -> dict[int, tuple[float, float]]: ...
|
|
104
|
+
def evolve(
|
|
105
|
+
rules: Rules,
|
|
106
|
+
initial_state: list[list[int]],
|
|
107
|
+
*,
|
|
108
|
+
generations: int | None = None,
|
|
109
|
+
events: int | None = None,
|
|
110
|
+
max_vertices: int | None = None,
|
|
111
|
+
max_vertex_degree: int | None = None,
|
|
112
|
+
max_edges: int | None = None,
|
|
113
|
+
event_ordering: list[str] | None = None,
|
|
114
|
+
random_seed: int = 0,
|
|
115
|
+
) -> HypergraphSystem: ...
|
|
116
|
+
def set_replace(state: list[list[int]], rules: Rules, events: int = 1) -> list[list[int]]: ...
|
|
117
|
+
def set_replace_list(
|
|
118
|
+
state: list[list[int]], rules: Rules, events: int
|
|
119
|
+
) -> list[list[list[int]]]: ...
|
|
120
|
+
def set_replace_all(
|
|
121
|
+
state: list[list[int]], rules: Rules, generations: int = 1
|
|
122
|
+
) -> list[list[int]]: ...
|
|
123
|
+
def set_replace_fixed_point(state: list[list[int]], rules: Rules) -> list[list[int]]: ...
|
setreplace/py.typed
ADDED
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: setreplace
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Rust
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
11
|
+
Summary: Wolfram models in Python: SetReplace-exact hypergraph substitution and HypergraphPlot-style rendering, powered by Rust
|
|
12
|
+
Keywords: wolfram-model,hypergraph,rewriting,setreplace,graph-layout
|
|
13
|
+
Author: Kovas Boguta
|
|
14
|
+
License: MIT
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
17
|
+
Project-URL: Documentation, https://github.com/kovasb/setreplace-py/blob/main/docs/python-api.md
|
|
18
|
+
Project-URL: Repository, https://github.com/kovasb/setreplace-py
|
|
19
|
+
|
|
20
|
+
# setreplace
|
|
21
|
+
|
|
22
|
+
**Wolfram models in Python** — hypergraph substitution systems with the exact
|
|
23
|
+
semantics of Wolfram's [SetReplace](https://github.com/maxitg/SetReplace),
|
|
24
|
+
plus `HypergraphPlot`-style rendering, powered by a Rust engine. No Wolfram
|
|
25
|
+
Language license, no graphviz, no native dependencies to install.
|
|
26
|
+
|
|
27
|
+
<img src="https://raw.githubusercontent.com/kovasb/setreplace-py/main/docs/images/showcase/announcement_web.png" width="500"
|
|
28
|
+
alt="1500 events of the Wolfram Physics Project announcement's rule">
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import setreplace as sr
|
|
32
|
+
|
|
33
|
+
# The rule from the Wolfram Physics Project announcement
|
|
34
|
+
system = sr.evolve("{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}",
|
|
35
|
+
[[1, 2], [2, 3], [3, 4], [2, 4]], events=1500)
|
|
36
|
+
system.plot() # ↑ renders inline in Jupyter
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
States are plain `list[list[int]]`; rules are the same strings the
|
|
40
|
+
SetReplace docs use. Evolution is incremental and fully deterministic
|
|
41
|
+
(seeded), and every token and event keeps its causal history:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
rule = "{{v1, v2, v3}, {v2, v4, v5}} -> {{v5, v6, v1}, {v6, v4, v2}, {v4, v5, v3}}"
|
|
45
|
+
system = sr.evolve(rule, [[1, 2, 3], [2, 4, 5], [4, 6, 7]], events=10)
|
|
46
|
+
|
|
47
|
+
system # <HypergraphSystem: 10 events, 5 generations, 13 edges, MaxEvents>
|
|
48
|
+
system.final_state # [[7, 2, 9], [7, 14, 6], ...]
|
|
49
|
+
system.evolve(max_events=100)
|
|
50
|
+
system.termination_reason # "MaxEvents" | "FixedPoint" | "MaxGenerations" | ...
|
|
51
|
+
system.tokens()[0] # Token(atoms=[1, 2, 3], creator_event=0, ...)
|
|
52
|
+
system.causal_graph_plot() # layered causal graph, inline
|
|
53
|
+
system.plot().save("state.png")
|
|
54
|
+
|
|
55
|
+
sr.set_replace([[1, 2], [2, 3]], "{{a_, b_}, {b_, c_}} :> {{a, c}}") # [[1, 3]]
|
|
56
|
+
pos = sr.layout(system.final_state) # {atom: (x, y)} for matplotlib & friends
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| Wolfram Language | Python |
|
|
60
|
+
|---|---|
|
|
61
|
+
| `WolframModel[rules, init, g]` | `sr.evolve(rules, init, generations=g)` |
|
|
62
|
+
| `SetReplace[set, rules, n]` | `sr.set_replace(set, rules, n)` |
|
|
63
|
+
| `<\|"MaxEvents" -> n, "MaxVertices" -> v\|>` | `system.evolve(max_events=n, max_vertices=v)` |
|
|
64
|
+
| `"EventOrderingFunction" -> {"OldestEdge", ...}` | `event_ordering=["OldestEdge", ...]` |
|
|
65
|
+
| `"CausalGraph"` / `"LayeredCausalGraph"` | `system.causal_graph_edges()` / `.causal_graph_plot()` |
|
|
66
|
+
| `HypergraphPlot[state, VertexLabels -> Automatic]` | `sr.plot(state, labels=True)` |
|
|
67
|
+
|
|
68
|
+
The engine is a verified port of SetReplace's C++ core: test vectors lifted
|
|
69
|
+
from SetReplace's own suite, plus live cross-checks against SetReplace under
|
|
70
|
+
wolframscript — final states, event traces, causal graphs, and every event
|
|
71
|
+
ordering agree exactly. The renderer's palette and arrowhead geometry are
|
|
72
|
+
transcribed from SetReplace's style sources, and large states lay out in
|
|
73
|
+
seconds via a multilevel spring-electrical embedding.
|
|
74
|
+
|
|
75
|
+
Docs, gallery, and the Rust crates:
|
|
76
|
+
[github.com/kovasb/setreplace-py](https://github.com/kovasb/setreplace-py).
|
|
77
|
+
|
|
78
|
+
Independent reimplementation of [SetReplace](https://github.com/maxitg/SetReplace)
|
|
79
|
+
(MIT) by Max Piskunov and contributors; not affiliated with the SetReplace
|
|
80
|
+
project, the Wolfram Physics Project, or Wolfram Research. MIT licensed.
|
|
81
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
setreplace/__init__.py,sha256=LscnJ1XqXVpnolL4ncZLpCLKN1PKabeJDv5bOMTpF9g,123
|
|
2
|
+
setreplace/__init__.pyi,sha256=7kHE07eP5wnNuOUtZO_Tm-aNaXLbIGS09weeCNy63Wk,3896
|
|
3
|
+
setreplace/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
setreplace/setreplace.pyd,sha256=bQu_7dFLsgdopbC41uyJBDiF3CLOegOx-txia4NWEy0,3559936
|
|
5
|
+
setreplace-0.1.0.dist-info/METADATA,sha256=__5nIAudYuHUMy3shiW2I9HcxQKyEHtaHBDZ5zoYwTc,4068
|
|
6
|
+
setreplace-0.1.0.dist-info/WHEEL,sha256=dB50znGoqD95tHNeV5UBZvlfLNwgEh0iQcswp5YahQ4,95
|
|
7
|
+
setreplace-0.1.0.dist-info/sboms/setreplace-python.cyclonedx.json,sha256=pyco4UGLaz4h5a_wyTMzErL2x52AfRTTcWb4FPjXj4s,87717
|
|
8
|
+
setreplace-0.1.0.dist-info/RECORD,,
|