mpbn 3.4__py3-none-any.whl → 3.5__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.
Potentially problematic release.
This version of mpbn might be problematic. Click here for more details.
- mpbn/converters.py +87 -0
- {mpbn-3.4.dist-info → mpbn-3.5.dist-info}/METADATA +1 -1
- {mpbn-3.4.dist-info → mpbn-3.5.dist-info}/RECORD +6 -5
- {mpbn-3.4.dist-info → mpbn-3.5.dist-info}/WHEEL +0 -0
- {mpbn-3.4.dist-info → mpbn-3.5.dist-info}/entry_points.txt +0 -0
- {mpbn-3.4.dist-info → mpbn-3.5.dist-info}/top_level.txt +0 -0
mpbn/converters.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import networkx as nx
|
|
2
|
+
from pyeda.boolalg.minimization import *
|
|
3
|
+
import pyeda.boolalg.expr
|
|
4
|
+
from pyeda.inter import expr
|
|
5
|
+
|
|
6
|
+
from colomoto import minibn
|
|
7
|
+
|
|
8
|
+
def expr2str(ex):
|
|
9
|
+
"""
|
|
10
|
+
converts a pyeda Boolean expression to string representation
|
|
11
|
+
"""
|
|
12
|
+
def _protect(e):
|
|
13
|
+
if isinstance(e, (pyeda.boolalg.expr.OrOp, pyeda.boolalg.expr.AndOp)):
|
|
14
|
+
return f"({expr2str(e)})"
|
|
15
|
+
return expr2str(e)
|
|
16
|
+
if isinstance(ex, pyeda.boolalg.expr.Variable):
|
|
17
|
+
return str(ex)
|
|
18
|
+
elif isinstance(ex, pyeda.boolalg.expr._One):
|
|
19
|
+
return "1"
|
|
20
|
+
elif isinstance(ex, pyeda.boolalg.expr._Zero):
|
|
21
|
+
return "0"
|
|
22
|
+
elif isinstance(ex, pyeda.boolalg.expr.Complement):
|
|
23
|
+
return f"!{_protect(ex.__invert__())}"
|
|
24
|
+
elif isinstance(ex, pyeda.boolalg.expr.NotOp):
|
|
25
|
+
return f"!{_protect(ex.x)}"
|
|
26
|
+
elif isinstance(ex, pyeda.boolalg.expr.OrOp):
|
|
27
|
+
return " | ".join(map(_protect, ex.xs))
|
|
28
|
+
elif isinstance(ex, pyeda.boolalg.expr.AndOp):
|
|
29
|
+
return " & ".join(map(_protect, ex.xs))
|
|
30
|
+
raise NotImplementedError(str(ex), type(ex))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def bn_of_asynchronous_transition_graph(adyn, names,
|
|
34
|
+
parse_node=(lambda n: tuple(map(int, n))),
|
|
35
|
+
bn_class=minibn.BooleanNetwork,
|
|
36
|
+
simplify=True):
|
|
37
|
+
"""
|
|
38
|
+
Convert the transition graph of a (fully) asynchronous Boolean network to
|
|
39
|
+
a propositional logic representation.
|
|
40
|
+
|
|
41
|
+
The object `adyn` must be an instance of `networkx.DiGraph`.
|
|
42
|
+
The `parse_node` function must return a tuple of 0 and 1 from an `adyn`
|
|
43
|
+
node. By default, it is assumed that nodes are strings of binary values.
|
|
44
|
+
Returned object will be of `bn_class`, instantiated with a dictionnary
|
|
45
|
+
mapping component names to a string representation of their Boolean expression.
|
|
46
|
+
"""
|
|
47
|
+
relabel = {label: parse_node(label) for label in adyn.nodes()}
|
|
48
|
+
adyn = nx.relabel_nodes(adyn, relabel)
|
|
49
|
+
n = len(next(iter(adyn.nodes)))
|
|
50
|
+
assert n == len(names), "list of component names and dimension of configuraitons seem different"
|
|
51
|
+
assert adyn.number_of_nodes() == 2**n, "unexpected number of nodes in the transition graph"
|
|
52
|
+
|
|
53
|
+
def expr_of_cfg(x):
|
|
54
|
+
e = "&".join(f"{'~' if not v else ''}{names[i]}" for i, v in enumerate(x))
|
|
55
|
+
return f"({e})"
|
|
56
|
+
|
|
57
|
+
f = []
|
|
58
|
+
for i in range(n):
|
|
59
|
+
pos = []
|
|
60
|
+
for x in adyn.nodes():
|
|
61
|
+
dx = list(x)
|
|
62
|
+
dx[i] = 1-x[i]
|
|
63
|
+
y = dx if tuple(dx) in adyn[x] else x
|
|
64
|
+
target = y[i]
|
|
65
|
+
if target:
|
|
66
|
+
pos.append(x)
|
|
67
|
+
if not pos:
|
|
68
|
+
f.append(expr("0"))
|
|
69
|
+
else:
|
|
70
|
+
e = expr("|".join(map(expr_of_cfg,pos)))
|
|
71
|
+
e, = espresso_exprs(e.to_dnf())
|
|
72
|
+
f.append(e)
|
|
73
|
+
f = map(expr2str, f)
|
|
74
|
+
f = bn_class(dict(zip(names, f)))
|
|
75
|
+
if simplify:
|
|
76
|
+
f = f.simplify()
|
|
77
|
+
return f
|
|
78
|
+
|
|
79
|
+
if __name__ == "__main__":
|
|
80
|
+
import mpbn
|
|
81
|
+
|
|
82
|
+
f = mpbn.MPBooleanNetwork({
|
|
83
|
+
"x1": "x2",
|
|
84
|
+
"x2": "x3",
|
|
85
|
+
"x3": "x1"})
|
|
86
|
+
g = f.dynamics("asynchronous")
|
|
87
|
+
print(bn_of_asynchronous_transition_graph(g, list(f)))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
mpbn/__init__.py,sha256=oPey2_tk0ymBGwiL9dcG88Hk-vUuWH-gpmP7ZDwXyu4,20578
|
|
2
|
+
mpbn/converters.py,sha256=33mhsGnFkJL4PlqYMIKu3zNb5oCNT6ZLaK6xoj9WsI4,3034
|
|
2
3
|
mpbn/simulation.py,sha256=3lk6yu7k2POrSytmtnsGIh596B-qcAgBtl16iZ0vzM4,10594
|
|
3
4
|
mpbn/asplib/eval_circuit.asp,sha256=5rIbkVmvobaQwE_gHr0_USccPuI0QUPuzfw_1011hSE,989
|
|
4
5
|
mpbn/asplib/eval_mixed.asp,sha256=n23pbjtxuWSCerL36Gb6O32bx8_1ukc52l1hQMMs8OE,787
|
|
@@ -14,8 +15,8 @@ tests/test_fixpoints.py,sha256=bdDttzimiby48nVkVL-HXZ2rBldICBRbIZrVVbTGfso,786
|
|
|
14
15
|
tests/test_input.py,sha256=mwMKd5UwAIY4Z1uZjYr09Ue8DLxD52CiPSoE-iXytfo,337
|
|
15
16
|
tests/test_reachability.py,sha256=X7anTwFSIYcV2rltJBOW8TcAJnrt3SjYLqttB0eIL_Q,588
|
|
16
17
|
tests/test_reachable_attractors.py,sha256=h78kvgmx9rTJWi3r2DZe_abYDxr02MLJ2iLDJUdLESY,540
|
|
17
|
-
mpbn-3.
|
|
18
|
-
mpbn-3.
|
|
19
|
-
mpbn-3.
|
|
20
|
-
mpbn-3.
|
|
21
|
-
mpbn-3.
|
|
18
|
+
mpbn-3.5.dist-info/METADATA,sha256=I6viVUknNQ532Vya9eUX-6u_QuwxrQx-w59njI7srYQ,2129
|
|
19
|
+
mpbn-3.5.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
20
|
+
mpbn-3.5.dist-info/entry_points.txt,sha256=CpzAc9SkB-mH_dojzt1N3YgDxy8hniDrIGzSHcPDo8g,68
|
|
21
|
+
mpbn-3.5.dist-info/top_level.txt,sha256=oe3jlFHbQ6oIXyE1q7yAAnf1m49oP_jBPUU05d71n74,11
|
|
22
|
+
mpbn-3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|