PyDecisionGraph 0.3.2.post1__cp315-cp315-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.
- decision_graph/__infra__.pxd +1 -0
- decision_graph/__init__.pxd +1 -0
- decision_graph/__init__.py +39 -0
- decision_graph/decision_tree/__init__.pxd +2 -0
- decision_graph/decision_tree/__init__.py +85 -0
- decision_graph/decision_tree/bake/__infra__.pxd +502 -0
- decision_graph/decision_tree/bake/__init__.pxd +502 -0
- decision_graph/decision_tree/bake/__init__.py +29 -0
- decision_graph/decision_tree/bake/c_action.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_action.h +324 -0
- decision_graph/decision_tree/bake/c_action.pxd +54 -0
- decision_graph/decision_tree/bake/c_action.pyi +126 -0
- decision_graph/decision_tree/bake/c_action.pyx +65 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.pxd +24 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.pyi +61 -0
- decision_graph/decision_tree/bake/c_allocator_protocol.pyx +109 -0
- decision_graph/decision_tree/bake/c_bake.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_bake.h +629 -0
- decision_graph/decision_tree/bake/c_bake.pxd +52 -0
- decision_graph/decision_tree/bake/c_bake.pyi +151 -0
- decision_graph/decision_tree/bake/c_bake.pyx +142 -0
- decision_graph/decision_tree/bake/c_collections.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_collections.h +692 -0
- decision_graph/decision_tree/bake/c_collections.pxd +52 -0
- decision_graph/decision_tree/bake/c_collections.pyi +193 -0
- decision_graph/decision_tree/bake/c_collections.pyx +161 -0
- decision_graph/decision_tree/bake/c_const.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_const.h +395 -0
- decision_graph/decision_tree/bake/c_const.pxd +56 -0
- decision_graph/decision_tree/bake/c_const.pyi +305 -0
- decision_graph/decision_tree/bake/c_const.pyx +278 -0
- decision_graph/decision_tree/bake/c_edge.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_edge.h +511 -0
- decision_graph/decision_tree/bake/c_edge.pxd +117 -0
- decision_graph/decision_tree/bake/c_edge.pyi +192 -0
- decision_graph/decision_tree/bake/c_edge.pyx +270 -0
- decision_graph/decision_tree/bake/c_eval.h +848 -0
- decision_graph/decision_tree/bake/c_eval.pxd +40 -0
- decision_graph/decision_tree/bake/c_expr.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_expr.h +1900 -0
- decision_graph/decision_tree/bake/c_expr.pxd +129 -0
- decision_graph/decision_tree/bake/c_expr.pyi +280 -0
- decision_graph/decision_tree/bake/c_expr.pyx +272 -0
- decision_graph/decision_tree/bake/c_hierarchy.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
- decision_graph/decision_tree/bake/c_hierarchy.pxd +71 -0
- decision_graph/decision_tree/bake/c_hierarchy.pyi +409 -0
- decision_graph/decision_tree/bake/c_hierarchy.pyx +277 -0
- decision_graph/decision_tree/bake/c_logic_group.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
- decision_graph/decision_tree/bake/c_logic_group.pxd +162 -0
- decision_graph/decision_tree/bake/c_logic_group.pyi +264 -0
- decision_graph/decision_tree/bake/c_logic_group.pyx +308 -0
- decision_graph/decision_tree/bake/c_node.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_node.h +2660 -0
- decision_graph/decision_tree/bake/c_node.pxd +381 -0
- decision_graph/decision_tree/bake/c_node.pyi +438 -0
- decision_graph/decision_tree/bake/c_node.pyx +639 -0
- decision_graph/decision_tree/bake/c_reconstruct.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_reconstruct.pxd +63 -0
- decision_graph/decision_tree/bake/c_reconstruct.pyi +60 -0
- decision_graph/decision_tree/bake/c_reconstruct.pyx +252 -0
- decision_graph/decision_tree/bake/c_var.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/bake/c_var.h +2054 -0
- decision_graph/decision_tree/bake/c_var.pxd +205 -0
- decision_graph/decision_tree/bake/c_var.pyi +271 -0
- decision_graph/decision_tree/bake/c_var.pyx +228 -0
- decision_graph/decision_tree/capi/__infra__.pxd +33 -0
- decision_graph/decision_tree/capi/__init__.pxd +33 -0
- decision_graph/decision_tree/capi/__init__.py +57 -0
- decision_graph/decision_tree/capi/c_abc.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/capi/c_abc.pxd +246 -0
- decision_graph/decision_tree/capi/c_abc.pyi +770 -0
- decision_graph/decision_tree/capi/c_abc.pyx +1532 -0
- decision_graph/decision_tree/capi/c_collection.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/capi/c_collection.pxd +22 -0
- decision_graph/decision_tree/capi/c_collection.pyi +245 -0
- decision_graph/decision_tree/capi/c_collection.pyx +138 -0
- decision_graph/decision_tree/capi/c_node.cp315-win_amd64.pyd +0 -0
- decision_graph/decision_tree/capi/c_node.pxd +95 -0
- decision_graph/decision_tree/capi/c_node.pyi +492 -0
- decision_graph/decision_tree/capi/c_node.pyx +551 -0
- decision_graph/decision_tree/exc.py +189 -0
- decision_graph/decision_tree/native/__init__.py +57 -0
- decision_graph/decision_tree/native/abc.py +1167 -0
- decision_graph/decision_tree/native/collection.py +134 -0
- decision_graph/decision_tree/native/node.py +521 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_action.c +16320 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_action.h +324 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_allocator_protocol.c +12473 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_bake.c +16485 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_bake.h +629 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_collections.c +17381 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_collections.h +692 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_const.c +20815 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_const.h +395 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_edge.c +20696 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_edge.h +511 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_eval.h +848 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_expr.c +22065 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_expr.h +1900 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.c +23267 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.c +22434 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_node.c +28385 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_node.h +2660 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_reconstruct.c +15955 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_var.c +16881 -0
- decision_graph/includes/decision_graph/decision_tree/bake/c_var.h +2054 -0
- decision_graph/includes/decision_graph/decision_tree/capi/c_abc.c +59196 -0
- decision_graph/includes/decision_graph/decision_tree/capi/c_collection.c +19967 -0
- decision_graph/includes/decision_graph/decision_tree/capi/c_node.c +39229 -0
- decision_graph/logic_group/__init__.py +25 -0
- decision_graph/logic_group/base.py +100 -0
- decision_graph/logic_group/pending_request.py +384 -0
- decision_graph/webui/__init__.py +24 -0
- decision_graph/webui/bake/__init__.py +65 -0
- decision_graph/webui/bake/app.py +488 -0
- decision_graph/webui/bake/static/d3.v7.min.js +2 -0
- decision_graph/webui/bake/static/script.js +1440 -0
- decision_graph/webui/bake/static/style.css +920 -0
- decision_graph/webui/bake/templates/index.html +183 -0
- decision_graph/webui/bake/templates/offline.html +184 -0
- decision_graph/webui/capi/__init__.py +54 -0
- decision_graph/webui/capi/app.py +366 -0
- decision_graph/webui/capi/main.py +53 -0
- decision_graph/webui/capi/static/d3.v7.min.js +2 -0
- decision_graph/webui/capi/static/script.js +1026 -0
- decision_graph/webui/capi/static/style.css +656 -0
- decision_graph/webui/capi/templates/index.html +93 -0
- decision_graph/webui/capi/templates/offline.html +94 -0
- decision_graph/webui/native/__init__.py +54 -0
- decision_graph/webui/native/app.py +366 -0
- decision_graph/webui/native/main.py +53 -0
- decision_graph/webui/native/static/d3.v7.min.js +2 -0
- decision_graph/webui/native/static/script.js +1026 -0
- decision_graph/webui/native/static/style.css +656 -0
- decision_graph/webui/native/templates/index.html +93 -0
- decision_graph/webui/native/templates/offline.html +94 -0
- pydecisiongraph-0.3.2.post1.dist-info/METADATA +136 -0
- pydecisiongraph-0.3.2.post1.dist-info/RECORD +148 -0
- pydecisiongraph-0.3.2.post1.dist-info/WHEEL +5 -0
- pydecisiongraph-0.3.2.post1.dist-info/licenses/LICENSE +373 -0
- pydecisiongraph-0.3.2.post1.dist-info/top_level.txt +2 -0
- tests/bake_c_evaluator.cp315-win_amd64.pyd +0 -0
- tests/bake_eval_probe.cp315-win_amd64.pyd +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""The edge layer: the condition a child carries about its parent.
|
|
2
|
+
|
|
3
|
+
An edge is a condition, and a condition is a tagged value with a type of its
|
|
4
|
+
own: five built-ins - unconditional, else, auto, true, false - and any other
|
|
5
|
+
condition is a caller's, holding the value its parent's evaluated result is
|
|
6
|
+
compared against.
|
|
7
|
+
|
|
8
|
+
Identity is the condition's ``type`` field, which is what the predicates here
|
|
9
|
+
read, and what the registry below is keyed by address for: a node's ``children``
|
|
10
|
+
is a dict keyed by these, so two wrappers of one condition have to compare as
|
|
11
|
+
one edge.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from cbase.bytemap import BoundByteMap
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class NodeEdgeCondition:
|
|
20
|
+
"""A condition an edge carries, as a tagged value.
|
|
21
|
+
|
|
22
|
+
An instance of this class is a **user condition**: it holds a value, and a
|
|
23
|
+
parent takes the edge when its evaluated result matches that value. The five
|
|
24
|
+
built-ins are instances of the subclasses below and are module constants.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
_header: The C condition block the wrapper stands for.
|
|
28
|
+
_owner: Whether this wrapper may free that block.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, py_value: Any = ..., repr: str | None = None) -> None:
|
|
32
|
+
"""Wrap a Python value as an edge condition.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
py_value: The value the parent's result is compared against.
|
|
36
|
+
repr: Display text for the condition.
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
ValueError: When no value is given - a user condition needs one.
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
def __hash__(self) -> int:
|
|
44
|
+
"""Hash by the C block's address, or by the type for a built-in."""
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
def __eq__(self, other: NodeEdgeCondition) -> bool:
|
|
48
|
+
"""Compare as edges: the tag first, then the payload.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
other: Condition to compare against.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
True when both conditions are the same edge.
|
|
55
|
+
"""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
def __ne__(self, other: NodeEdgeCondition) -> bool:
|
|
59
|
+
"""The negation of ``__eq__``."""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
def __repr__(self) -> str:
|
|
63
|
+
"""The condition's display text, class name included."""
|
|
64
|
+
...
|
|
65
|
+
|
|
66
|
+
def __str__(self) -> str:
|
|
67
|
+
"""The condition's display text."""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def address(self) -> int:
|
|
72
|
+
"""The block this condition is, as the edge registry keys it."""
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def is_none(self) -> bool:
|
|
77
|
+
"""Whether this is the unconditional edge."""
|
|
78
|
+
...
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def is_else(self) -> bool:
|
|
82
|
+
"""Whether this is the fallback edge."""
|
|
83
|
+
...
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def is_auto(self) -> bool:
|
|
87
|
+
"""Whether this edge's arm is for the parent to infer."""
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def is_binary(self) -> bool:
|
|
92
|
+
"""Whether this is a two-way edge: the true or the false arm."""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def value(self) -> Any:
|
|
97
|
+
"""The value this edge is taken by: what the parent's result must match.
|
|
98
|
+
|
|
99
|
+
A caller's condition carries the value it was built with, and it is read
|
|
100
|
+
here as the Python object it was. The three edges that stand for "no
|
|
101
|
+
particular value" - the unconditional, the else and the auto - hold none,
|
|
102
|
+
so reading one raises rather than answering with a value that says
|
|
103
|
+
nothing. The two arms of a branch are the exception the other way: they
|
|
104
|
+
DO answer, with the ``True`` and the ``False`` they are, which is what
|
|
105
|
+
makes a built-in edge usable without unpacking the C tag first.
|
|
106
|
+
|
|
107
|
+
Raises:
|
|
108
|
+
ValueError: When the condition holds no value.
|
|
109
|
+
RuntimeError: When the wrapper is uninitialised.
|
|
110
|
+
"""
|
|
111
|
+
...
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ConditionAny(NodeEdgeCondition):
|
|
115
|
+
"""The unconditional edge: a parent's single arm."""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ConditionElse(NodeEdgeCondition):
|
|
119
|
+
"""The fallback edge: taken when nothing else matched, always last."""
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ConditionAuto(NodeEdgeCondition):
|
|
123
|
+
"""An unresolved edge: the parent infers the arm it belongs to."""
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class BinaryCondition(NodeEdgeCondition):
|
|
127
|
+
"""A two-way edge: the true arm or the false arm of a branch."""
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class ConditionTrue(BinaryCondition):
|
|
131
|
+
"""The true arm of a two-way branch."""
|
|
132
|
+
|
|
133
|
+
def __bool__(self) -> bool:
|
|
134
|
+
"""True, as the arm it is."""
|
|
135
|
+
...
|
|
136
|
+
|
|
137
|
+
def __int__(self) -> int:
|
|
138
|
+
"""1, as the arm it is."""
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def value(self) -> bool:
|
|
143
|
+
"""True - the arm answers with the value it stands for."""
|
|
144
|
+
...
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ConditionFalse(BinaryCondition):
|
|
148
|
+
"""The false arm of a two-way branch."""
|
|
149
|
+
|
|
150
|
+
def __bool__(self) -> bool:
|
|
151
|
+
"""False, as the arm it is."""
|
|
152
|
+
...
|
|
153
|
+
|
|
154
|
+
def __int__(self) -> int:
|
|
155
|
+
"""0, as the arm it is."""
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def value(self) -> bool:
|
|
160
|
+
"""False - the arm answers with the value it stands for."""
|
|
161
|
+
...
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class EdgeConditionRegistry(BoundByteMap):
|
|
165
|
+
"""The wrapper every edge is looked up by, keyed by its block's address.
|
|
166
|
+
|
|
167
|
+
A lookup that finds the address answers with the instance held for it; one
|
|
168
|
+
that misses builds the condition its own **type** names - the derived class
|
|
169
|
+
for a built-in, the base for a caller's - over the address that was asked
|
|
170
|
+
for. Two conditions of one type are still two edges, so nothing here hands
|
|
171
|
+
out a shared instance for a different address.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
def __getitem__(self, key: int) -> NodeEdgeCondition:
|
|
175
|
+
"""The condition at an address, rebuilding it when it is not held.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
key: Address of the C condition block.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
The condition wrapper for that address.
|
|
182
|
+
"""
|
|
183
|
+
...
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# The five built-ins, and the registry that holds them.
|
|
187
|
+
NO_CONDITION: ConditionAny
|
|
188
|
+
ELSE_CONDITION: ConditionElse
|
|
189
|
+
AUTO_CONDITION: ConditionAuto
|
|
190
|
+
TRUE_CONDITION: ConditionTrue
|
|
191
|
+
FALSE_CONDITION: ConditionFalse
|
|
192
|
+
EDGE_REGISTRY: EdgeConditionRegistry
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
from cpython.dict cimport PyDict_Contains
|
|
2
|
+
from cpython.unicode cimport PyUnicode_AsUTF8, PyUnicode_FromString
|
|
3
|
+
from libc.stdint cimport uintptr_t
|
|
4
|
+
|
|
5
|
+
from cbase.bytemap cimport c_bytemap_gen_seq_id
|
|
6
|
+
|
|
7
|
+
from .c_allocator_protocol cimport DCG_DEFAULT_ALLOCATOR
|
|
8
|
+
from .c_var cimport c_dcg_var_is_null, c_dcg_var_pypack, c_dcg_var_pyunpack
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
cdef class NodeEdgeCondition:
|
|
12
|
+
def __init__(self, object py_value=None, str repr=None):
|
|
13
|
+
if py_value is None:
|
|
14
|
+
raise ValueError('A user condition needs a value; the five built-ins are module constants.')
|
|
15
|
+
|
|
16
|
+
cdef dcg_var_t val
|
|
17
|
+
c_dcg_var_pypack(&val, py_value)
|
|
18
|
+
|
|
19
|
+
self.header = c_dcg_edge_new(val, PyUnicode_AsUTF8(repr) if repr is not None else NULL, DCG_DEFAULT_ALLOCATOR)
|
|
20
|
+
if not self.header:
|
|
21
|
+
raise MemoryError('Failed to allocate an edge condition.')
|
|
22
|
+
|
|
23
|
+
self.owner = True
|
|
24
|
+
|
|
25
|
+
def __dealloc__(self):
|
|
26
|
+
if not self.owner:
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
if self.header:
|
|
30
|
+
c_dcg_condition_free(self.header)
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
cdef NodeEdgeCondition c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
34
|
+
cdef NodeEdgeCondition instance = NodeEdgeCondition.__new__(NodeEdgeCondition)
|
|
35
|
+
instance.header = header
|
|
36
|
+
instance.owner = owner
|
|
37
|
+
return instance
|
|
38
|
+
|
|
39
|
+
# === Python Dunders ===
|
|
40
|
+
|
|
41
|
+
def __hash__(self):
|
|
42
|
+
if self.header == NULL:
|
|
43
|
+
return 0
|
|
44
|
+
if c_dcg_condition_is_sentinel(self.header):
|
|
45
|
+
return <uintptr_t> self.header.type
|
|
46
|
+
return <uintptr_t> self.header
|
|
47
|
+
|
|
48
|
+
def __eq__(self, NodeEdgeCondition other):
|
|
49
|
+
if not isinstance(other, NodeEdgeCondition):
|
|
50
|
+
return NotImplemented
|
|
51
|
+
return c_dcg_condition_equals(self.header, other.header)
|
|
52
|
+
|
|
53
|
+
def __ne__(self, NodeEdgeCondition other):
|
|
54
|
+
if not isinstance(other, NodeEdgeCondition):
|
|
55
|
+
return NotImplemented
|
|
56
|
+
return not c_dcg_condition_equals(self.header, other.header)
|
|
57
|
+
|
|
58
|
+
def __repr__(self):
|
|
59
|
+
if not self.header:
|
|
60
|
+
return f'<{self.__class__.__name__} (Uninitialized)>'
|
|
61
|
+
cdef char buf[DCG_NODE_STRING_MAXLEN]
|
|
62
|
+
c_dcg_condition_format(self.header, NULL, buf, sizeof(buf))
|
|
63
|
+
return f'<{self.__class__.__name__}>({PyUnicode_FromString(buf)})'
|
|
64
|
+
|
|
65
|
+
def __str__(self):
|
|
66
|
+
if not self.header:
|
|
67
|
+
return f'<{self.__class__.__name__} (Uninitialized)>'
|
|
68
|
+
cdef char buf[DCG_NODE_STRING_MAXLEN]
|
|
69
|
+
c_dcg_condition_format(self.header, NULL, buf, sizeof(buf))
|
|
70
|
+
return PyUnicode_FromString(buf)
|
|
71
|
+
|
|
72
|
+
property address:
|
|
73
|
+
def __get__(self):
|
|
74
|
+
if not self.header:
|
|
75
|
+
raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
|
|
76
|
+
return <uintptr_t> self.header
|
|
77
|
+
|
|
78
|
+
property is_none:
|
|
79
|
+
def __get__(self):
|
|
80
|
+
if not self.header:
|
|
81
|
+
raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
|
|
82
|
+
return c_dcg_condition_is_none(self.header)
|
|
83
|
+
|
|
84
|
+
property is_else:
|
|
85
|
+
def __get__(self):
|
|
86
|
+
if not self.header:
|
|
87
|
+
raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
|
|
88
|
+
return c_dcg_condition_is_else(self.header)
|
|
89
|
+
|
|
90
|
+
property is_auto:
|
|
91
|
+
def __get__(self):
|
|
92
|
+
if not self.header:
|
|
93
|
+
raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
|
|
94
|
+
return c_dcg_condition_is_auto(self.header)
|
|
95
|
+
|
|
96
|
+
property is_binary:
|
|
97
|
+
def __get__(self):
|
|
98
|
+
if not self.header:
|
|
99
|
+
raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
|
|
100
|
+
return c_dcg_condition_is_binary(self.header)
|
|
101
|
+
|
|
102
|
+
property value:
|
|
103
|
+
def __get__(self):
|
|
104
|
+
if not self.header:
|
|
105
|
+
raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
|
|
106
|
+
if c_dcg_var_is_null(&self.header.value):
|
|
107
|
+
raise ValueError('Condition has no value assigned.')
|
|
108
|
+
return c_dcg_var_pyunpack(&self.header.value)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
cdef class ConditionAny(NodeEdgeCondition):
|
|
112
|
+
@staticmethod
|
|
113
|
+
cdef ConditionAny c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
114
|
+
cdef ConditionAny instance = ConditionAny.__new__(ConditionAny)
|
|
115
|
+
instance.header = header
|
|
116
|
+
instance.owner = owner
|
|
117
|
+
return instance
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
cdef class ConditionElse(NodeEdgeCondition):
|
|
121
|
+
@staticmethod
|
|
122
|
+
cdef ConditionElse c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
123
|
+
cdef ConditionElse instance = ConditionElse.__new__(ConditionElse)
|
|
124
|
+
instance.header = header
|
|
125
|
+
instance.owner = owner
|
|
126
|
+
return instance
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
cdef class ConditionAuto(NodeEdgeCondition):
|
|
130
|
+
@staticmethod
|
|
131
|
+
cdef ConditionAuto c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
132
|
+
cdef ConditionAuto instance = ConditionAuto.__new__(ConditionAuto)
|
|
133
|
+
instance.header = header
|
|
134
|
+
instance.owner = owner
|
|
135
|
+
return instance
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
cdef class BinaryCondition(NodeEdgeCondition):
|
|
139
|
+
@staticmethod
|
|
140
|
+
cdef BinaryCondition c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
141
|
+
cdef BinaryCondition instance = BinaryCondition.__new__(BinaryCondition)
|
|
142
|
+
instance.header = header
|
|
143
|
+
instance.owner = owner
|
|
144
|
+
return instance
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
cdef class ConditionTrue(BinaryCondition):
|
|
148
|
+
@staticmethod
|
|
149
|
+
cdef ConditionTrue c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
150
|
+
cdef ConditionTrue instance = ConditionTrue.__new__(ConditionTrue)
|
|
151
|
+
instance.header = header
|
|
152
|
+
instance.owner = owner
|
|
153
|
+
return instance
|
|
154
|
+
|
|
155
|
+
def __bool__(self):
|
|
156
|
+
return True
|
|
157
|
+
|
|
158
|
+
def __int__(self):
|
|
159
|
+
return 1
|
|
160
|
+
|
|
161
|
+
property value:
|
|
162
|
+
def __get__(self):
|
|
163
|
+
return True
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
cdef class ConditionFalse(BinaryCondition):
|
|
167
|
+
@staticmethod
|
|
168
|
+
cdef ConditionFalse c_from_header(dcg_node_edge_condition* header, bint owner=False):
|
|
169
|
+
cdef ConditionFalse instance = ConditionFalse.__new__(ConditionFalse)
|
|
170
|
+
instance.header = header
|
|
171
|
+
instance.owner = owner
|
|
172
|
+
return instance
|
|
173
|
+
|
|
174
|
+
def __bool__(self):
|
|
175
|
+
return False
|
|
176
|
+
|
|
177
|
+
def __int__(self):
|
|
178
|
+
return 0
|
|
179
|
+
|
|
180
|
+
property value:
|
|
181
|
+
def __get__(self):
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
cdef inline NodeEdgeCondition c_dcg_condition_reconstruct(dcg_node_edge_condition* edge):
|
|
186
|
+
if not edge:
|
|
187
|
+
return NO_CONDITION
|
|
188
|
+
|
|
189
|
+
cdef dcg_node_edge_type edge_type = edge.type
|
|
190
|
+
|
|
191
|
+
if edge_type == dcg_node_edge_type.DCG_NODE_EDGE_NONE:
|
|
192
|
+
return ConditionAny.c_from_header(edge, False)
|
|
193
|
+
if edge_type == dcg_node_edge_type.DCG_NODE_EDGE_ELSE:
|
|
194
|
+
return ConditionElse.c_from_header(edge, False)
|
|
195
|
+
if edge_type == dcg_node_edge_type.DCG_NODE_EDGE_AUTO:
|
|
196
|
+
return ConditionAuto.c_from_header(edge, False)
|
|
197
|
+
if edge_type == dcg_node_edge_type.DCG_NODE_EDGE_TRUE:
|
|
198
|
+
return ConditionTrue.c_from_header(edge, False)
|
|
199
|
+
if edge_type == dcg_node_edge_type.DCG_NODE_EDGE_FALSE:
|
|
200
|
+
return ConditionFalse.c_from_header(edge, False)
|
|
201
|
+
return NodeEdgeCondition.c_from_header(edge, False)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
cdef class EdgeConditionRegistry(BoundByteMap):
|
|
205
|
+
@staticmethod
|
|
206
|
+
cdef EdgeConditionRegistry c_from_header(bytemap* header, bint owner=False):
|
|
207
|
+
cdef EdgeConditionRegistry instance = EdgeConditionRegistry.__new__(EdgeConditionRegistry)
|
|
208
|
+
instance.owner = owner
|
|
209
|
+
instance.seq_id = c_bytemap_gen_seq_id(<void*> instance)
|
|
210
|
+
instance.c_bind(header)
|
|
211
|
+
return instance
|
|
212
|
+
|
|
213
|
+
cdef const char* c_serialize_key(self, object obj, size_t* key_len):
|
|
214
|
+
# A header address is provided in format of int (uintptr_t)
|
|
215
|
+
if isinstance(obj, int):
|
|
216
|
+
self._ws_key_buf = <void*> <uintptr_t> obj
|
|
217
|
+
if key_len:
|
|
218
|
+
key_len[0] = sizeof(void*)
|
|
219
|
+
return <const char*> &self._ws_key_buf
|
|
220
|
+
return BoundByteMap.c_serialize_key(self, obj, key_len)
|
|
221
|
+
|
|
222
|
+
cdef object c_deserialize_key(self, const char* key, size_t key_len):
|
|
223
|
+
return <uintptr_t> <void*> key
|
|
224
|
+
|
|
225
|
+
cdef const char* c_serialize_value(self, object obj, size_t* value_len):
|
|
226
|
+
cdef NodeEdgeCondition edge = <NodeEdgeCondition> obj
|
|
227
|
+
self._ws_ptr = <void*> edge.header
|
|
228
|
+
if value_len:
|
|
229
|
+
value_len[0] = sizeof(void*)
|
|
230
|
+
return <const char*> &self._ws_ptr
|
|
231
|
+
|
|
232
|
+
cdef object c_deserialize_value(self, const char* value, size_t value_len):
|
|
233
|
+
cdef void** vp = <void**> value
|
|
234
|
+
return c_dcg_condition_reconstruct(<dcg_node_edge_condition*> vp[0])
|
|
235
|
+
|
|
236
|
+
def __getitem__(self, object key):
|
|
237
|
+
cdef int ret_code = PyDict_Contains(<dict> self, key)
|
|
238
|
+
if ret_code == 0:
|
|
239
|
+
return c_dcg_condition_reconstruct(<dcg_node_edge_condition*> <uintptr_t> key)
|
|
240
|
+
return super().__getitem__(key)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
c_dcg_condition_init_globals()
|
|
244
|
+
|
|
245
|
+
cdef dcg_node_edge_condition* C_NO_CONDITION = &__DCG_NO_CONDITION
|
|
246
|
+
cdef dcg_node_edge_condition* C_ELSE_CONDITION = &__DCG_ELSE_CONDITION
|
|
247
|
+
cdef dcg_node_edge_condition* C_AUTO_CONDITION = &__DCG_AUTO_CONDITION
|
|
248
|
+
cdef dcg_node_edge_condition* C_TRUE_CONDITION = &__DCG_TRUE_CONDITION
|
|
249
|
+
cdef dcg_node_edge_condition* C_FALSE_CONDITION = &__DCG_FALSE_CONDITION
|
|
250
|
+
|
|
251
|
+
cdef ConditionAny NO_CONDITION = ConditionAny.c_from_header(C_NO_CONDITION, False)
|
|
252
|
+
cdef ConditionElse ELSE_CONDITION = ConditionElse.c_from_header(C_ELSE_CONDITION, False)
|
|
253
|
+
cdef ConditionAuto AUTO_CONDITION = ConditionAuto.c_from_header(C_AUTO_CONDITION, False)
|
|
254
|
+
cdef ConditionTrue TRUE_CONDITION = ConditionTrue.c_from_header(C_TRUE_CONDITION, False)
|
|
255
|
+
cdef ConditionFalse FALSE_CONDITION = ConditionFalse.c_from_header(C_FALSE_CONDITION, False)
|
|
256
|
+
|
|
257
|
+
globals()['NO_CONDITION'] = NO_CONDITION
|
|
258
|
+
globals()['ELSE_CONDITION'] = ELSE_CONDITION
|
|
259
|
+
globals()['AUTO_CONDITION'] = AUTO_CONDITION
|
|
260
|
+
globals()['TRUE_CONDITION'] = TRUE_CONDITION
|
|
261
|
+
globals()['FALSE_CONDITION'] = FALSE_CONDITION
|
|
262
|
+
|
|
263
|
+
cdef EdgeConditionRegistry EDGE_REGISTRY = EdgeConditionRegistry()
|
|
264
|
+
EDGE_REGISTRY[<uintptr_t> C_NO_CONDITION] = NO_CONDITION
|
|
265
|
+
EDGE_REGISTRY[<uintptr_t> C_ELSE_CONDITION] = ELSE_CONDITION
|
|
266
|
+
EDGE_REGISTRY[<uintptr_t> C_AUTO_CONDITION] = AUTO_CONDITION
|
|
267
|
+
EDGE_REGISTRY[<uintptr_t> C_TRUE_CONDITION] = TRUE_CONDITION
|
|
268
|
+
EDGE_REGISTRY[<uintptr_t> C_FALSE_CONDITION] = FALSE_CONDITION
|
|
269
|
+
|
|
270
|
+
globals()['EDGE_REGISTRY'] = EDGE_REGISTRY
|