bigraph-schema 1.0.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.
- bigraph_schema/__init__.py +112 -0
- bigraph_schema/core.py +759 -0
- bigraph_schema/edge.py +138 -0
- bigraph_schema/methods/__init__.py +12 -0
- bigraph_schema/methods/apply.py +276 -0
- bigraph_schema/methods/check.py +213 -0
- bigraph_schema/methods/default.py +204 -0
- bigraph_schema/methods/generalize.py +309 -0
- bigraph_schema/methods/handle_parameters.py +182 -0
- bigraph_schema/methods/infer.py +217 -0
- bigraph_schema/methods/jump.py +432 -0
- bigraph_schema/methods/merge.py +405 -0
- bigraph_schema/methods/realize.py +527 -0
- bigraph_schema/methods/resolve.py +692 -0
- bigraph_schema/methods/serialize.py +491 -0
- bigraph_schema/methods/validate.py +249 -0
- bigraph_schema/package/__init__.py +1 -0
- bigraph_schema/package/discover.py +122 -0
- bigraph_schema/parse.py +183 -0
- bigraph_schema/protocols.py +57 -0
- bigraph_schema/schema.py +370 -0
- bigraph_schema/units.py +133 -0
- bigraph_schema-1.0.0.dist-info/METADATA +66 -0
- bigraph_schema-1.0.0.dist-info/RECORD +28 -0
- bigraph_schema-1.0.0.dist-info/WHEEL +5 -0
- bigraph_schema-1.0.0.dist-info/licenses/AUTHORS.md +6 -0
- bigraph_schema-1.0.0.dist-info/licenses/LICENSE +201 -0
- bigraph_schema-1.0.0.dist-info/top_level.txt +1 -0
bigraph_schema/schema.py
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing
|
|
4
|
+
import numpy as np
|
|
5
|
+
import numpy.lib.format as nf
|
|
6
|
+
import collections
|
|
7
|
+
|
|
8
|
+
from plum import dispatch
|
|
9
|
+
from dataclasses import dataclass, is_dataclass, field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
NONE_SYMBOL = '__nil__'
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(kw_only=True)
|
|
16
|
+
class Node():
|
|
17
|
+
_default: object = None
|
|
18
|
+
|
|
19
|
+
@dataclass(kw_only=True)
|
|
20
|
+
class Place(Node):
|
|
21
|
+
_subnodes: dict = field(default_factory=dict)
|
|
22
|
+
|
|
23
|
+
@dataclass(kw_only=True)
|
|
24
|
+
class Atom(Node):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
@dataclass(kw_only=True)
|
|
28
|
+
class Empty(Atom):
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
@dataclass(kw_only=True)
|
|
32
|
+
class Union(Node):
|
|
33
|
+
_options: typing.Tuple[Node] = field(default_factory=tuple)
|
|
34
|
+
|
|
35
|
+
@dataclass(kw_only=True)
|
|
36
|
+
class Tuple(Node):
|
|
37
|
+
_values: typing.List[Node] = field(default_factory=list)
|
|
38
|
+
|
|
39
|
+
@dataclass(kw_only=True)
|
|
40
|
+
class Boolean(Atom):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
@dataclass(kw_only=True)
|
|
44
|
+
class Or(Boolean):
|
|
45
|
+
_default: bool = False
|
|
46
|
+
|
|
47
|
+
@dataclass(kw_only=True)
|
|
48
|
+
class And(Boolean):
|
|
49
|
+
_default: bool = True
|
|
50
|
+
|
|
51
|
+
@dataclass(kw_only=True)
|
|
52
|
+
class Xor(Boolean):
|
|
53
|
+
_default: bool = False
|
|
54
|
+
|
|
55
|
+
@dataclass(kw_only=True)
|
|
56
|
+
class Number(Atom):
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
@dataclass(kw_only=True)
|
|
60
|
+
class Integer(Number):
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
@dataclass(kw_only=True)
|
|
64
|
+
class Float(Number):
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
@dataclass(kw_only=True)
|
|
68
|
+
class Complex(Float):
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
@dataclass(kw_only=True)
|
|
72
|
+
class Delta(Float):
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
@dataclass(kw_only=True)
|
|
76
|
+
class Nonnegative(Float):
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
@dataclass(kw_only=True)
|
|
80
|
+
class NPRandom(Node):
|
|
81
|
+
state: Tuple() = field(default_factory=tuple)
|
|
82
|
+
|
|
83
|
+
@dataclass(kw_only=True)
|
|
84
|
+
class String(Atom):
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
@dataclass(kw_only=True)
|
|
88
|
+
class Enum(String):
|
|
89
|
+
_values: typing.Tuple[str] = field(default_factory=tuple)
|
|
90
|
+
|
|
91
|
+
@dataclass(kw_only=True)
|
|
92
|
+
class Wrap(Node):
|
|
93
|
+
_value: Node = field(default_factory=Node)
|
|
94
|
+
|
|
95
|
+
@dataclass(kw_only=True)
|
|
96
|
+
class Maybe(Wrap):
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
@dataclass(kw_only=True)
|
|
100
|
+
class Overwrite(Wrap):
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
@dataclass(kw_only=True)
|
|
104
|
+
class List(Node):
|
|
105
|
+
_element: Node = field(default_factory=Node)
|
|
106
|
+
|
|
107
|
+
@dataclass(kw_only=True)
|
|
108
|
+
class Map(Node):
|
|
109
|
+
_key: Node = field(default_factory=String)
|
|
110
|
+
_value: Node = field(default_factory=Node)
|
|
111
|
+
|
|
112
|
+
@dataclass(kw_only=True)
|
|
113
|
+
class Tree(Node):
|
|
114
|
+
_leaf: Node = field(default_factory=Node)
|
|
115
|
+
|
|
116
|
+
@dataclass(kw_only=True)
|
|
117
|
+
class Array(Node):
|
|
118
|
+
_shape: typing.Tuple[int] = field(default_factory=tuple)
|
|
119
|
+
_data: np.dtype = field(default_factory=lambda:np.dtype('float64'))
|
|
120
|
+
|
|
121
|
+
@dataclass(kw_only=True)
|
|
122
|
+
class Path(List):
|
|
123
|
+
_element: Node = field(default_factory=Node)
|
|
124
|
+
|
|
125
|
+
@dataclass(kw_only=True)
|
|
126
|
+
class Wires(Tree):
|
|
127
|
+
_leaf: Node = field(default_factory=Path)
|
|
128
|
+
|
|
129
|
+
@dataclass(kw_only=True)
|
|
130
|
+
class Schema(Tree):
|
|
131
|
+
_leaf: Node = field(default_factory=Node)
|
|
132
|
+
|
|
133
|
+
@dataclass(kw_only=True)
|
|
134
|
+
class Protocol(Node):
|
|
135
|
+
protocol: String = field(default_factory=String)
|
|
136
|
+
data: Node = field(default_factory=Node)
|
|
137
|
+
|
|
138
|
+
@dataclass(kw_only=True)
|
|
139
|
+
class LocalProtocol(Protocol):
|
|
140
|
+
data: String = field(default_factory=String)
|
|
141
|
+
|
|
142
|
+
@dataclass(kw_only=True)
|
|
143
|
+
class Link(Node):
|
|
144
|
+
address: Protocol = field(default_factory=Protocol)
|
|
145
|
+
config: Node = field(default_factory=Node)
|
|
146
|
+
_inputs: dict = field(default_factory=dict)
|
|
147
|
+
_outputs: dict = field(default_factory=dict)
|
|
148
|
+
inputs: Wires = field(default_factory=Wires)
|
|
149
|
+
outputs: Wires = field(default_factory=Wires)
|
|
150
|
+
|
|
151
|
+
# types for jumps in traversals
|
|
152
|
+
|
|
153
|
+
@dataclass(kw_only=True)
|
|
154
|
+
class Jump():
|
|
155
|
+
_value: object
|
|
156
|
+
|
|
157
|
+
@dataclass(kw_only=True)
|
|
158
|
+
class Key(Jump):
|
|
159
|
+
_value: str
|
|
160
|
+
|
|
161
|
+
@dataclass(kw_only=True)
|
|
162
|
+
class Index(Jump):
|
|
163
|
+
_value: int
|
|
164
|
+
|
|
165
|
+
@dataclass(kw_only=True)
|
|
166
|
+
class Slice(Jump):
|
|
167
|
+
_value: slice
|
|
168
|
+
|
|
169
|
+
@dataclass(kw_only=True)
|
|
170
|
+
class Star(Jump):
|
|
171
|
+
_value: str = '*'
|
|
172
|
+
|
|
173
|
+
@dataclass(kw_only=True)
|
|
174
|
+
class Match(Jump):
|
|
175
|
+
_match = str # regex
|
|
176
|
+
|
|
177
|
+
def convert_jump(key):
|
|
178
|
+
if isinstance(key, Jump):
|
|
179
|
+
return key
|
|
180
|
+
|
|
181
|
+
convert_key = None
|
|
182
|
+
if isinstance(key, str):
|
|
183
|
+
if key == '*':
|
|
184
|
+
convert_key = Star(_value=key)
|
|
185
|
+
else:
|
|
186
|
+
convert_key = Key(_value=key)
|
|
187
|
+
elif isinstance(key, int):
|
|
188
|
+
convert_key = Index(_value=key)
|
|
189
|
+
|
|
190
|
+
return convert_key or Jump(_value=key)
|
|
191
|
+
|
|
192
|
+
def resolve_path(path):
|
|
193
|
+
"""
|
|
194
|
+
Given a path that includes '..' steps, resolve the path to a canonical form
|
|
195
|
+
"""
|
|
196
|
+
resolve = []
|
|
197
|
+
|
|
198
|
+
for step in path:
|
|
199
|
+
if step == '..':
|
|
200
|
+
if len(resolve) == 0:
|
|
201
|
+
raise Exception(f'cannot go above the top in path: "{path}"')
|
|
202
|
+
else:
|
|
203
|
+
resolve = resolve[:-1]
|
|
204
|
+
else:
|
|
205
|
+
resolve.append(step)
|
|
206
|
+
|
|
207
|
+
return tuple(resolve)
|
|
208
|
+
|
|
209
|
+
def deep_merge(dct, merge_dct):
|
|
210
|
+
"""
|
|
211
|
+
Deep merge `merge_dct` into `dct`, modifying `dct` in-place.
|
|
212
|
+
|
|
213
|
+
Nested dictionaries are recursively merged.
|
|
214
|
+
"""
|
|
215
|
+
if dct is None:
|
|
216
|
+
dct = {}
|
|
217
|
+
if merge_dct is None:
|
|
218
|
+
merge_dct = {}
|
|
219
|
+
if not isinstance(merge_dct, dict):
|
|
220
|
+
return merge_dct
|
|
221
|
+
|
|
222
|
+
for k, v in merge_dct.items():
|
|
223
|
+
if (k in dct and isinstance(dct[k], dict)
|
|
224
|
+
and isinstance(v, collections.abc.Mapping)):
|
|
225
|
+
deep_merge(dct[k], v)
|
|
226
|
+
else:
|
|
227
|
+
dct[k] = v
|
|
228
|
+
return dct
|
|
229
|
+
|
|
230
|
+
def is_empty(value):
|
|
231
|
+
return value is None or value == {} or value == []
|
|
232
|
+
|
|
233
|
+
def convert_path(path):
|
|
234
|
+
resolved = resolve_path(path)
|
|
235
|
+
return [
|
|
236
|
+
convert_jump(key)
|
|
237
|
+
for key in resolved]
|
|
238
|
+
|
|
239
|
+
def blank_context(schema, state, path):
|
|
240
|
+
return {
|
|
241
|
+
'schema': schema,
|
|
242
|
+
'state': state,
|
|
243
|
+
'path': (),
|
|
244
|
+
'subpath': path}
|
|
245
|
+
|
|
246
|
+
def walk_path(context, to, subpath=None):
|
|
247
|
+
return {
|
|
248
|
+
**context,
|
|
249
|
+
'path': context['path'] + (to,),
|
|
250
|
+
'subpath': subpath}
|
|
251
|
+
|
|
252
|
+
def dtype_schema(dtype: np.dtype):
|
|
253
|
+
data = nf.dtype_to_descr(dtype)
|
|
254
|
+
if isinstance(data, str):
|
|
255
|
+
if 'f' in data or 'd' in data:
|
|
256
|
+
return Float()
|
|
257
|
+
elif 'U' in data:
|
|
258
|
+
return String()
|
|
259
|
+
elif 'i' in data or 'b' in data or 'h' in data:
|
|
260
|
+
return Integer()
|
|
261
|
+
elif 'F' in data or 'D' in data:
|
|
262
|
+
return Complex()
|
|
263
|
+
elif isinstance(data, list):
|
|
264
|
+
result = {}
|
|
265
|
+
for group in data:
|
|
266
|
+
key = group[0]
|
|
267
|
+
subschema = np.dtype(group[1])
|
|
268
|
+
if len(group) > 2:
|
|
269
|
+
shape = group[2]
|
|
270
|
+
subschema = Array(_shape=shape, _data=subschema)
|
|
271
|
+
result[key] = subschema
|
|
272
|
+
|
|
273
|
+
return result
|
|
274
|
+
else:
|
|
275
|
+
raise Exception('do not know how to interpret dtype as schema:\n\n{dtype}\n\n')
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def make_default(schema, state):
|
|
279
|
+
return {
|
|
280
|
+
'_type': schema,
|
|
281
|
+
'_default': state}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
@dispatch
|
|
285
|
+
def schema_dtype(schema: Complex):
|
|
286
|
+
return np.dtype('complex128')
|
|
287
|
+
|
|
288
|
+
@dispatch
|
|
289
|
+
def schema_dtype(schema: Float):
|
|
290
|
+
return np.dtype('float64')
|
|
291
|
+
|
|
292
|
+
@dispatch
|
|
293
|
+
def schema_dtype(schema: Integer):
|
|
294
|
+
return np.dtype('int32')
|
|
295
|
+
|
|
296
|
+
@dispatch
|
|
297
|
+
def schema_dtype(schema: Boolean):
|
|
298
|
+
return np.dtype('bool')
|
|
299
|
+
|
|
300
|
+
@dispatch
|
|
301
|
+
def schema_dtype(schema: String):
|
|
302
|
+
return np.dtype('unicode')
|
|
303
|
+
|
|
304
|
+
@dispatch
|
|
305
|
+
def schema_dtype(schema: str):
|
|
306
|
+
return np.dtype(schema)
|
|
307
|
+
|
|
308
|
+
@dispatch
|
|
309
|
+
def schema_dtype(schema: list):
|
|
310
|
+
return np.dtype(schema)
|
|
311
|
+
|
|
312
|
+
@dispatch
|
|
313
|
+
def schema_dtype(schema: dict):
|
|
314
|
+
result = []
|
|
315
|
+
if not schema:
|
|
316
|
+
return None
|
|
317
|
+
|
|
318
|
+
for key, value in schema.items():
|
|
319
|
+
subschema = schema_dtype(value)
|
|
320
|
+
subresult = (key, subschema)
|
|
321
|
+
if isinstance(subschema, Array):
|
|
322
|
+
subshape = subschema._shape
|
|
323
|
+
subresult = subresult + (subshape,)
|
|
324
|
+
|
|
325
|
+
result.append(subresult)
|
|
326
|
+
|
|
327
|
+
if all([isinstance(key, int) for key in schema.keys()]):
|
|
328
|
+
shape = max(schema.keys())
|
|
329
|
+
return Array(_shape=(shape,), _data=result[0][1])
|
|
330
|
+
else:
|
|
331
|
+
return np.dtype(result)
|
|
332
|
+
|
|
333
|
+
@dispatch
|
|
334
|
+
def schema_dtype(schema):
|
|
335
|
+
raise Exception(f'schema dtype not implemented for:\n\n{schema}\n\n')
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
BASE_TYPES = {
|
|
339
|
+
'node': Node,
|
|
340
|
+
'atom': Atom,
|
|
341
|
+
'empty': Empty,
|
|
342
|
+
'union': Union,
|
|
343
|
+
'tuple': Tuple,
|
|
344
|
+
'boolean': Boolean,
|
|
345
|
+
'or': Or,
|
|
346
|
+
'and': And,
|
|
347
|
+
'xor': Xor,
|
|
348
|
+
'number': Number,
|
|
349
|
+
'integer': Integer,
|
|
350
|
+
'float': Float,
|
|
351
|
+
'delta': Delta,
|
|
352
|
+
'nonnegative': Nonnegative,
|
|
353
|
+
'random_state': NPRandom,
|
|
354
|
+
'string': String,
|
|
355
|
+
'enum': Enum,
|
|
356
|
+
'wrap': Wrap,
|
|
357
|
+
'maybe': Maybe,
|
|
358
|
+
'overwrite': Overwrite,
|
|
359
|
+
'list': List,
|
|
360
|
+
'map': Map,
|
|
361
|
+
'tree': Tree,
|
|
362
|
+
'array': Array,
|
|
363
|
+
'path': Path,
|
|
364
|
+
'wires': Wires,
|
|
365
|
+
'protocol': Protocol,
|
|
366
|
+
'local': LocalProtocol,
|
|
367
|
+
'schema': Schema,
|
|
368
|
+
'link': Link}
|
|
369
|
+
|
|
370
|
+
|
bigraph_schema/units.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""
|
|
2
|
+
=====
|
|
3
|
+
Units
|
|
4
|
+
=====
|
|
5
|
+
|
|
6
|
+
Register all of the unit types from the pint unit registry
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from pint import UnitRegistry
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
units = UnitRegistry()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def render_coefficient(original_power):
|
|
16
|
+
power = abs(original_power)
|
|
17
|
+
int_part = int(power)
|
|
18
|
+
root_part = power % 1
|
|
19
|
+
|
|
20
|
+
if root_part != 0.0:
|
|
21
|
+
render = str(root_part)[2:]
|
|
22
|
+
render = f'{int_part}_{render}'
|
|
23
|
+
else:
|
|
24
|
+
render = str(int_part)
|
|
25
|
+
|
|
26
|
+
return render
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def render_units_type(dimensionality):
|
|
30
|
+
unit_keys = list(dimensionality.keys())
|
|
31
|
+
unit_keys.sort()
|
|
32
|
+
|
|
33
|
+
numerator = []
|
|
34
|
+
denominator = []
|
|
35
|
+
|
|
36
|
+
for unit_key in unit_keys:
|
|
37
|
+
inner_key = unit_key.strip('[]')
|
|
38
|
+
power = dimensionality[unit_key]
|
|
39
|
+
negative = False
|
|
40
|
+
|
|
41
|
+
if power < 0:
|
|
42
|
+
negative = True
|
|
43
|
+
power = -power
|
|
44
|
+
|
|
45
|
+
if power == 1:
|
|
46
|
+
render = inner_key
|
|
47
|
+
else:
|
|
48
|
+
render = f'{inner_key}^{render_coefficient(power)}'
|
|
49
|
+
|
|
50
|
+
if negative:
|
|
51
|
+
denominator.append(render)
|
|
52
|
+
else:
|
|
53
|
+
numerator.append(render)
|
|
54
|
+
|
|
55
|
+
render = '*'.join(numerator)
|
|
56
|
+
if len(denominator) > 0:
|
|
57
|
+
render_denominator = '*'.join(denominator)
|
|
58
|
+
render = f'{render}/{render_denominator}'
|
|
59
|
+
|
|
60
|
+
return render
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def parse_coefficient(s):
|
|
64
|
+
if s is None:
|
|
65
|
+
return 1
|
|
66
|
+
elif '_' in s:
|
|
67
|
+
parts = s.split('_')
|
|
68
|
+
if len(parts) > 1:
|
|
69
|
+
base, residue = parts
|
|
70
|
+
return int(base) + (float(residue) / 10.0)
|
|
71
|
+
else:
|
|
72
|
+
return int(parts)
|
|
73
|
+
else:
|
|
74
|
+
return int(s)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def parse_dimensionality(s):
|
|
78
|
+
numerator, denominator = s.split('/')
|
|
79
|
+
numerator_terms = numerator.split('*')
|
|
80
|
+
denominator_terms = denominator.split('*')
|
|
81
|
+
|
|
82
|
+
dimensionality = {}
|
|
83
|
+
|
|
84
|
+
for term in numerator_terms:
|
|
85
|
+
base = term.split('^')
|
|
86
|
+
exponent = None
|
|
87
|
+
if len(base) > 1:
|
|
88
|
+
exponent = base[1]
|
|
89
|
+
dimensionality[f'[{base[0]}]'] = parse_coefficient(exponent)
|
|
90
|
+
|
|
91
|
+
for term in denominator_terms:
|
|
92
|
+
power = term.split('^')
|
|
93
|
+
exponent = None
|
|
94
|
+
if len(power) > 1:
|
|
95
|
+
exponent = power[1]
|
|
96
|
+
dimensionality[f'[{power[0]}]'] = -parse_coefficient(exponent)
|
|
97
|
+
|
|
98
|
+
return dimensionality
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_units_render():
|
|
102
|
+
dimensionality = units.newton.dimensionality
|
|
103
|
+
render = render_units_type(dimensionality)
|
|
104
|
+
recover = parse_dimensionality(render)
|
|
105
|
+
|
|
106
|
+
print(f'original: {dimensionality}')
|
|
107
|
+
print(f'render: {render}')
|
|
108
|
+
print(f'parsed: {recover}')
|
|
109
|
+
|
|
110
|
+
assert render == 'length*mass/time^2'
|
|
111
|
+
assert recover == dimensionality
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_roots_cycle():
|
|
115
|
+
dimensionality = {
|
|
116
|
+
'[length]': 1.5,
|
|
117
|
+
'[time]': 3,
|
|
118
|
+
'[mass]': -2.5,
|
|
119
|
+
}
|
|
120
|
+
render = render_units_type(dimensionality)
|
|
121
|
+
recover = parse_dimensionality(render)
|
|
122
|
+
|
|
123
|
+
print(f'original: {dimensionality}')
|
|
124
|
+
print(f'render: {render}')
|
|
125
|
+
print(f'parsed: {recover}')
|
|
126
|
+
|
|
127
|
+
assert render == 'length^1_5*time^3/mass^2_5'
|
|
128
|
+
assert recover == dimensionality
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
if __name__ == '__main__':
|
|
132
|
+
test_units_render()
|
|
133
|
+
test_roots_cycle()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bigraph-schema
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A serializable type schema for compositional systems biology
|
|
5
|
+
Author: Eran Agmon, Ryan Spangler
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: AUTHORS.md
|
|
10
|
+
Requires-Dist: fire
|
|
11
|
+
Requires-Dist: numpy
|
|
12
|
+
Requires-Dist: orjson
|
|
13
|
+
Requires-Dist: parsimonious
|
|
14
|
+
Requires-Dist: pint
|
|
15
|
+
Requires-Dist: plum-dispatch
|
|
16
|
+
Requires-Dist: pytest
|
|
17
|
+
Requires-Dist: ipdb
|
|
18
|
+
Requires-Dist: requests>=2.31.0
|
|
19
|
+
Requires-Dist: setuptools
|
|
20
|
+
Requires-Dist: twine>=4.0.2
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# Bigraph-Schema
|
|
24
|
+
|
|
25
|
+
[](https://pypi.org/project/bigraph-schema/)
|
|
26
|
+
[](https://vivarium-collective.github.io/bigraph-schema/notebooks/demo.html)
|
|
27
|
+
|
|
28
|
+
`bigraph-schema` provides a serializable type schema for compositional and multiscale modeling.
|
|
29
|
+
It defines a compact, extensible language for describing hierarchical data structures — the foundation of the Vivarium 2.0 simulation framework.
|
|
30
|
+
|
|
31
|
+
The library offers a unified interface for representing, validating, and transforming schemas and data in structured simulations.
|
|
32
|
+
By standardizing schema definitions, it enables interoperability between models, extensibility across frameworks, and reproducibility of computational experiments.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Install directly from PyPI:
|
|
39
|
+
|
|
40
|
+
```console
|
|
41
|
+
pip install bigraph-schema
|
|
42
|
+
```
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Getting Started
|
|
46
|
+
|
|
47
|
+
The following resources provide guided introductions and examples:
|
|
48
|
+
|
|
49
|
+
- [Type System Overview](https://vivarium-collective.github.io/bigraph-schema/notebooks/core.html) – Demonstrates how to use the `Core` API for schema inference, normalization, and serialization.
|
|
50
|
+
|
|
51
|
+
- [Bigraph Schema Basics Tutorial](https://vivarium-collective.github.io/bigraph-viz/notebooks/basics.html) – Explains how to compose and visualize schema graphs using the `bigraph-schema` syntax.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Related Projects
|
|
57
|
+
|
|
58
|
+
- [Vivarium](https://vivarium-collective.github.io/) – a compositional framework for hybrid biological simulations.
|
|
59
|
+
- [Bigraph-Viz](https://vivarium-collective.github.io/bigraph-viz/) – visualization tools for bigraph-schema models.
|
|
60
|
+
- [Process-Bigraph](https://github.com/vivarium-collective/process-bigraph) – process composition and orchestration built on bigraph-schema.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
`bigraph-schema` is open-source software released under the [Apache 2.0 License](https://github.com/vivarium-collective/bigraph-schema/blob/main/LICENSE).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
bigraph_schema/__init__.py,sha256=Sbrb4L_RpeuJVuGMbmHVk1pTNE4ucM7qbKxBrdp3nd4,3394
|
|
2
|
+
bigraph_schema/core.py,sha256=l-0jkPiJzxejIjJHTgLYymx2iNqayXXhzImRNN_9Yyk,25453
|
|
3
|
+
bigraph_schema/edge.py,sha256=oEwOQg0-mzZ08JElwT8x2cYmW_IXc9BNO5nG0YWYMyA,3421
|
|
4
|
+
bigraph_schema/parse.py,sha256=EByTwL6d0wrDSSO0mfevHKLtxmBPL9IrtLVP2n3lUaY,6246
|
|
5
|
+
bigraph_schema/protocols.py,sha256=rfJ1-yhtfHwcB3yUdKwQDiamXPpoUWztnTzU2-LB74k,1280
|
|
6
|
+
bigraph_schema/schema.py,sha256=NYAWmWTywcVfdW5V_MW_Lb2C8khs-5EoMeXmsBNAcUg,8178
|
|
7
|
+
bigraph_schema/units.py,sha256=PaeqYpCot3eFfZdOUoGqhZjobONpgjc8zxFNNSKg0e4,3020
|
|
8
|
+
bigraph_schema/methods/__init__.py,sha256=RA7YIIQ8EZeCDXFz6Krtz0SggLAZAZCfvI79UmqAQew,790
|
|
9
|
+
bigraph_schema/methods/apply.py,sha256=-R53tfGuMJMciyrBMy7yxiFNy2FzcUeMunzzRRB152Y,6353
|
|
10
|
+
bigraph_schema/methods/check.py,sha256=tj9hj4N_SIjAxq7XMhuPw1K4BxFitHhWWRgi4lefOTk,4231
|
|
11
|
+
bigraph_schema/methods/default.py,sha256=devfn9BnyFjJmpD82FwFcS1bbBA1aak1xroHs6zqTQo,4277
|
|
12
|
+
bigraph_schema/methods/generalize.py,sha256=iYMkr2qxeg7KdWmMWMigldEgH3k9HPJDhNAqr8xkWwE,7879
|
|
13
|
+
bigraph_schema/methods/handle_parameters.py,sha256=hietX6HuasA10SIwQNRqbXirJtT7Zry3Gn71OTJrz_4,4476
|
|
14
|
+
bigraph_schema/methods/infer.py,sha256=d04C7wjIpsObRtjl1jvu7sJoFl1DlH1Ho4_T7HRiSJw,5322
|
|
15
|
+
bigraph_schema/methods/jump.py,sha256=woc7QqtBy23zHOhWFK2CR1YPikS3d_lTvNWIkMiiHiE,10455
|
|
16
|
+
bigraph_schema/methods/merge.py,sha256=2eiR098Ye0NATNIKqNyEnTM7xr0euTBvJFrNIn_KbRQ,10160
|
|
17
|
+
bigraph_schema/methods/realize.py,sha256=MD63Rotc_KDMQCXdwkJA-TOYMkFjOdP8ArfaPLRMuHk,15206
|
|
18
|
+
bigraph_schema/methods/resolve.py,sha256=jHtDpO6EOOzEPRD2VkbGAExSwq7foAVmlPT81zwwhCY,19655
|
|
19
|
+
bigraph_schema/methods/serialize.py,sha256=cOs7b1_c2wTYQk0Fvn_3TjuXupCV3E3ZGQ5ZWopsPOY,12649
|
|
20
|
+
bigraph_schema/methods/validate.py,sha256=XS0bFTQ3GHryI4hLCmQgnI2zdP5yro1wI8rZ45SO_EI,7382
|
|
21
|
+
bigraph_schema/package/__init__.py,sha256=bx_9iGPudkTuaLQOBxQlw-H8NQ8VZSbONNM-BGYJJTI,62
|
|
22
|
+
bigraph_schema/package/discover.py,sha256=dCQBGcsYvpM5FXyU6EHqD8_w68LcRZk0eGZ3EVXCGQU,3599
|
|
23
|
+
bigraph_schema-1.0.0.dist-info/licenses/AUTHORS.md,sha256=1ndh21uie4wWDB9qYiNofzTjITFC_ZSrP_HqFImvcdo,142
|
|
24
|
+
bigraph_schema-1.0.0.dist-info/licenses/LICENSE,sha256=sF9SV-O54AFkJTMLiJaQw0Ngd4QC7nAkzLV3QBIYnC0,11358
|
|
25
|
+
bigraph_schema-1.0.0.dist-info/METADATA,sha256=vKJdFUgYvBElE47USnAcsWCXz_9N3DADmCqf1uaHlf0,2558
|
|
26
|
+
bigraph_schema-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
27
|
+
bigraph_schema-1.0.0.dist-info/top_level.txt,sha256=zce6hZ5UdrtyAiwHWgN62ErKNHqbuEEL6eadbSvLu6g,15
|
|
28
|
+
bigraph_schema-1.0.0.dist-info/RECORD,,
|