|
1 | | -import warnings |
2 | | -import re |
3 | | -from typing import Any |
| 1 | +from typing import Any, cast |
4 | 2 |
|
| 3 | +from process_bigraph_lang.dsl.model import Model, StoreDef, ProcessDef, Reference, Store |
5 | 4 | from vivarium import Vivarium |
6 | | -from process_bigraph_lang.dsl.model import Model, StoreDef, ProcessDef, Reference |
| 5 | + |
7 | 6 |
|
8 | 7 | def process_composite(model: Model, assembler: Vivarium): |
9 | 8 | for composite_def in model.compositeDefs: |
10 | | - store_to_store_def_map: dict[str, StoreDef] = {} |
11 | | - for store_ref in composite_def.stores: |
12 | | - # verify we have a reference for desired process |
13 | | - match_obj = re.match("^#(/(\w+)(@(\d+))+)+$", store_ref.store_def.ref) |
14 | | - if not match_obj: |
15 | | - raise ValueError( |
16 | | - f"Unexpected reference for process reference: `{store_ref.store_def.ref_text}` ({store_ref.store_def.ref})") |
17 | | - full, section, _, index = match_obj.groups() |
18 | | - if section != "store_defs": |
19 | | - raise ValueError(f"Unexpected section `{section}` for reference `{store_ref.store_def.ref_text}` ({full})`") |
20 | | - store_to_store_def_map[composite_def.name + "::" + store_ref.name] = model.store_defs[int(index)] |
21 | 9 |
|
22 | | - store_value_mapping: dict[str, Any] = {} |
| 10 | + store_path_to_value_map: dict[str, Any] = {} |
23 | 11 | for process in composite_def.processes: |
24 | | - # verify we have a reference for desired process |
25 | | - match_obj = re.match("^#(/(\w+)(@(\d+))+)+$", process.process_def.ref) |
26 | | - if not match_obj: |
27 | | - raise ValueError(f"Unexpected reference for process reference: `{process.process_def.ref_text}` ({process.process_def.ref})") |
28 | | - full, section, _, index = match_obj.groups() |
29 | | - if section != "processDefs": |
30 | | - raise ValueError(f"Unexpected section `{section}` for reference `{process.process_def.ref_text}` ({full})`") |
| 12 | + process_def = cast(ProcessDef, process.process_def.ref_object) |
| 13 | + assert isinstance(process_def, ProcessDef) |
31 | 14 |
|
32 | | - # Identify ports needing to be bound |
33 | | - process_def_actual: ProcessDef = model.processDefs[int(index)] |
34 | | - input_bindings: dict[str, list[str]] = {elem.ref_text : [] for elem in process_def_actual.inputs} |
35 | | - output_bindings: dict[str, list[str]] = {elem.ref_text : [] for elem in process_def_actual.outputs} |
| 15 | + input_bindings: dict[str, list[str]] = {elem.ref_text : [] for elem in process_def.inputs} |
| 16 | + output_bindings: dict[str, list[str]] = {elem.ref_text : [] for elem in process_def.outputs} |
36 | 17 |
|
37 | | - # create config |
38 | | - # config = {} |
39 | | - # for param in process_def_actual.params: |
40 | | - # config[param.name] = param.default.val if param.default is not None else determine_builtin_default(param.type.ref_text) |
| 18 | + process_config = {} |
| 19 | + for param in process_def.params: |
| 20 | + process_config[param.name] = param.default.val if param.default is not None else determine_builtin_default(param.type.ref_text) |
41 | 21 |
|
42 | | - # store validation |
43 | | - store_ref: Reference |
44 | 22 | for store_ref in process.stores: |
45 | | - match_obj = re.match("^#(/[\w]+(@\d)+)+$", store_ref.ref) |
46 | | - if not match_obj: |
47 | | - raise ValueError(f"Unexpected reference for process reference: `{store_ref.ref_text}` ({store_ref.ref})") |
48 | | - tokenized_reference_path: list[tuple[str, int]] = [(elem.split("@")[0], int(elem.split("@")[1])) for elem in store_ref.ref[1:].split("/") if '@' in elem] |
49 | | - map_key: str = composite_def.name + "::" + store_ref.ref_text |
50 | | - if map_key not in store_to_store_def_map: |
51 | | - raise ValueError(f"Store {store_ref} not found in mapping using key `{map_key}`") |
52 | | - actual_def = store_to_store_def_map[map_key] |
53 | | - for state_def in actual_def.states: |
54 | | - in_path = input_bindings[state_def.name] if state_def.name in input_bindings else [] |
55 | | - out_binding = output_bindings[state_def.name] if state_def.name in output_bindings else [] |
56 | | - if 0 != len(in_path and 0 != len(out_binding)): |
57 | | - continue |
58 | | - if 0 == len(in_path) and 0 == len(out_binding): #nothing has been initialized with this store |
59 | | - store_value_mapping[map_key] = state_def.default.val if state_def.default is not None else determine_builtin_default(state_def.type.ref_text) |
60 | | - if 0 == len(in_path): |
61 | | - for token in map_key.split("::"): |
62 | | - in_path.append(token) |
63 | | - if 0 == len(out_binding): |
64 | | - for token in map_key.split("::"): |
65 | | - out_binding.append(token) |
66 | | - config = {p.name: p.default.val for p in process_def_actual.params} |
| 23 | + store = cast(Store, store_ref.ref_object) |
| 24 | + assert isinstance(store, Store) |
| 25 | + store_def = cast(StoreDef, store.store_def.ref_object) |
| 26 | + assert isinstance(store_def, StoreDef) |
| 27 | + |
| 28 | + store_path_str: str = composite_def.name + "::" + store.name |
| 29 | + store_path = [composite_def.name, store.name] |
| 30 | + |
| 31 | + for state_def in store_def.states: |
| 32 | + store_path_to_value_map[store_path_str] = state_def.default.val if state_def.default is not None else determine_builtin_default(state_def.type.ref_text) |
| 33 | + |
| 34 | + for state_def in store_def.states: |
| 35 | + if state_def.name in input_bindings: |
| 36 | + input_bindings[state_def.name] = store_path |
| 37 | + if state_def.name in output_bindings: |
| 38 | + output_bindings[state_def.name] = store_path |
| 39 | + |
67 | 40 | assembler.add_process( |
68 | 41 | name=process.name, |
69 | | - process_id=".".join(process_def_actual.python_path.path), |
70 | | - config=config, |
| 42 | + process_id=".".join(process_def.python_path.path), |
| 43 | + config=process_config, |
71 | 44 | inputs=input_bindings, |
72 | 45 | outputs=output_bindings, |
73 | 46 | ) |
74 | | - # end scope of composite def for loop |
75 | | - for path_str in store_value_mapping: |
76 | | - path = path_str.split("::") |
77 | | - assembler.set_value(path=path, value=store_value_mapping[path_str]) |
| 47 | + |
| 48 | + for store_path_str in store_path_to_value_map: |
| 49 | + store_path = store_path_str.split("::") |
| 50 | + assembler.set_value(path=store_path, value=store_path_to_value_map[store_path_str]) |
| 51 | + |
78 | 52 | assembler.add_emitter() |
79 | 53 |
|
80 | 54 | def determine_builtin_default(type_to_infer: str): |
|
0 commit comments