ReForma 0.1.0__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.
@@ -0,0 +1,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: ReForma
3
+ Version: 0.1.0
4
+ Summary: Python bindings for the RePA/ReForma probabilistic automaton tool
5
+ Author-email: Joshua Dourado <joshuadourado@ua.pt>
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Topic :: Scientific/Engineering
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: networkx
14
+ Requires-Dist: matplotlib
15
+
16
+ # ReForma — Python bindings for the RePA/ReForma tool
17
+
18
+ A clean Python library that wraps the `ReFormaTool.jar` CLI via subprocess,
19
+ giving you a Pythonic interface for simulation, training, PDL/PCTL
20
+ verification, and export.
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ # From the project root (where pyproject.toml lives)
28
+ pip install -e .
29
+ ```
30
+
31
+ Requires **Python 3.10+** and a working `java` on your PATH.
32
+
33
+ ---
34
+
35
+ ## Quick Start
36
+
37
+ ```python
38
+ from ReForma import ReForma
39
+
40
+ # Point to your compiled JAR
41
+ ReForma = ReForma("path/to/ReFormaTool.jar")
42
+
43
+ # Load a model
44
+ state = ReForma.load_file("examples/recommender.r")
45
+
46
+ print(state.current_states) # ['Home']
47
+ print(state.enabled) # [Transition('go_work': Home → Office, p=0.500), ...]
48
+
49
+ # Simulate
50
+ state = ReForma.step("go_work")
51
+ state = ReForma.step("easy_task")
52
+ state = ReForma.undo() # undo last step
53
+
54
+ # Reset to initial state
55
+ ReForma.reset()
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Simulation
61
+
62
+ ```python
63
+ state = ReForma.load_file("model.r")
64
+
65
+ # Check what's enabled
66
+ for t in state.enabled:
67
+ print(f"{t.label}: {t.from_state} → {t.to_state} (p={t.probability:.3f})")
68
+
69
+ # Take a step by label
70
+ state = ReForma.step("go_work")
71
+
72
+ # Undo / reset
73
+ state = ReForma.undo()
74
+ state = ReForma.reset()
75
+
76
+ # Inspect variables
77
+ print(state.variables) # {'counter': 0, 'flag': 1}
78
+
79
+ # History of labels taken
80
+ print(ReForma.history) # ['go_work']
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Training
86
+
87
+ Train the model on a batch of sessions (lists of event labels):
88
+
89
+ ```python
90
+ ReForma.train([
91
+ ["go_work", "easy_task", "easy_task", "go_home"],
92
+ ["battery_low", "go_charge", "finish_charge", "socialize"],
93
+ ["no_money", "go_work", "go_home"],
94
+ ])
95
+
96
+ # Or train directly from a log file (one session per line, comma-separated)
97
+ ReForma.train_from_file("logs/sessions.txt")
98
+
99
+ # sessions.txt format:
100
+ # go_work,easy_task,go_home
101
+ # battery_low,go_charge,finish_charge
102
+
103
+ # Save the updated model with new weights
104
+ ReForma.save_source("model_trained.r")
105
+ ```
106
+
107
+ ---
108
+
109
+ ## PDL / PCTL Verification
110
+
111
+ ```python
112
+ # Quantitative: probability of eventually reaching Office
113
+ prob = ReForma.check_pdl_value("Home", "{P=?[F Office]}")
114
+ print(f"P(reach Office from Home) = {prob:.4f}")
115
+
116
+ # Qualitative: is it probable?
117
+ holds = ReForma.check_pdl_value("Home", "{P>=0.4[F Office]}")
118
+ print(f"P>=0.4? {holds}") # True / False
119
+
120
+ # PDL: is there a path via go_work to Office?
121
+ holds = ReForma.check_pdl_value("Home", "<go_work>Office")
122
+ print(holds) # True
123
+
124
+ # Get the raw string result
125
+ raw = ReForma.check_pdl("Home", "{P=?[F Office]}")
126
+ print(raw) # "Result: 0.50000"
127
+ ```
128
+
129
+ ### Formula syntax reference
130
+
131
+ | Formula | Meaning |
132
+ |-----------------------------|------------------------------------------------|
133
+ | `{P=?[F target]}` | Probability of eventually reaching `target` |
134
+ | `{P=?[G safe]}` | Probability of staying in `safe` forever |
135
+ | `{P=?[X next]}` | Probability of reaching `next` in one step |
136
+ | `{P=?[a U b]}` | Probability of `a` until `b` |
137
+ | `{P>=0.5[F target]}` | Is probability of reaching target ≥ 0.5? |
138
+ | `<action>state` | There exists a path via `action` to `state` |
139
+ | `[action]state` | All paths via `action` lead to `state` |
140
+
141
+ ---
142
+
143
+ ## Export
144
+
145
+ ```python
146
+ # PRISM DTMC
147
+ prism_code = ReForma.export_prism()
148
+ ReForma.save_prism("output/model.pm")
149
+
150
+ # mCRL2
151
+ mcrl2_code = ReForma.export_mcrl2()
152
+
153
+ # GLTS (imperative translation)
154
+ glts_code = ReForma.export_glts()
155
+
156
+ # Mermaid diagram (initial state)
157
+ diagram = ReForma.export_mermaid()
158
+
159
+ # Mermaid diagram (full LTS — all reachable states)
160
+ full_diagram = ReForma.export_mermaid(full_lts=True)
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Loading from a string
166
+
167
+ ```python
168
+ source = """
169
+ name MyModel
170
+ init s0
171
+ s0 ---> s1: a (0.6)
172
+ s0 ---> s2: b (0.4)
173
+ s1 ---> s0: back (1.0)
174
+ """
175
+
176
+ state = ReForma.load(source, name="MyModel")
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Running the tests
182
+
183
+ ```bash
184
+ pip install pytest
185
+ pytest tests/ -v
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Project structure
191
+
192
+ ```
193
+ ReForma/
194
+ ├── __init__.py # Public API exports
195
+ ├── client.py # ReForma — high-level Python API
196
+ ├── jar_bridge.py # JarBridge — low-level subprocess wrapper
197
+ └── model.py # ReFormaModel, SimulationState, Transition data classes
198
+ tests/
199
+ └── test_ReForma.py # Full test suite (mocked, no JAR needed)
200
+ pyproject.toml
201
+ README.md
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Error handling
207
+
208
+ ```python
209
+ from ReForma.jar_bridge import JarError
210
+
211
+ try:
212
+ result = ReForma.check_pdl("Home", "{P=?[F Office]}")
213
+ except JarError as e:
214
+ print(f"JAR error: {e}")
215
+ except RuntimeError as e:
216
+ print(f"Usage error: {e}") # e.g. no model loaded, invalid transition
217
+ ```
@@ -0,0 +1,4 @@
1
+ reforma-0.1.0.dist-info/METADATA,sha256=rvdQrmXiHSdPIZWO19pD6R-HV-iJSU5XKDByUGo5soQ,5180
2
+ reforma-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
3
+ reforma-0.1.0.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
4
+ reforma-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+