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.
Files changed (148) hide show
  1. decision_graph/__infra__.pxd +1 -0
  2. decision_graph/__init__.pxd +1 -0
  3. decision_graph/__init__.py +39 -0
  4. decision_graph/decision_tree/__init__.pxd +2 -0
  5. decision_graph/decision_tree/__init__.py +85 -0
  6. decision_graph/decision_tree/bake/__infra__.pxd +502 -0
  7. decision_graph/decision_tree/bake/__init__.pxd +502 -0
  8. decision_graph/decision_tree/bake/__init__.py +29 -0
  9. decision_graph/decision_tree/bake/c_action.cp315-win_amd64.pyd +0 -0
  10. decision_graph/decision_tree/bake/c_action.h +324 -0
  11. decision_graph/decision_tree/bake/c_action.pxd +54 -0
  12. decision_graph/decision_tree/bake/c_action.pyi +126 -0
  13. decision_graph/decision_tree/bake/c_action.pyx +65 -0
  14. decision_graph/decision_tree/bake/c_allocator_protocol.cp315-win_amd64.pyd +0 -0
  15. decision_graph/decision_tree/bake/c_allocator_protocol.pxd +24 -0
  16. decision_graph/decision_tree/bake/c_allocator_protocol.pyi +61 -0
  17. decision_graph/decision_tree/bake/c_allocator_protocol.pyx +109 -0
  18. decision_graph/decision_tree/bake/c_bake.cp315-win_amd64.pyd +0 -0
  19. decision_graph/decision_tree/bake/c_bake.h +629 -0
  20. decision_graph/decision_tree/bake/c_bake.pxd +52 -0
  21. decision_graph/decision_tree/bake/c_bake.pyi +151 -0
  22. decision_graph/decision_tree/bake/c_bake.pyx +142 -0
  23. decision_graph/decision_tree/bake/c_collections.cp315-win_amd64.pyd +0 -0
  24. decision_graph/decision_tree/bake/c_collections.h +692 -0
  25. decision_graph/decision_tree/bake/c_collections.pxd +52 -0
  26. decision_graph/decision_tree/bake/c_collections.pyi +193 -0
  27. decision_graph/decision_tree/bake/c_collections.pyx +161 -0
  28. decision_graph/decision_tree/bake/c_const.cp315-win_amd64.pyd +0 -0
  29. decision_graph/decision_tree/bake/c_const.h +395 -0
  30. decision_graph/decision_tree/bake/c_const.pxd +56 -0
  31. decision_graph/decision_tree/bake/c_const.pyi +305 -0
  32. decision_graph/decision_tree/bake/c_const.pyx +278 -0
  33. decision_graph/decision_tree/bake/c_edge.cp315-win_amd64.pyd +0 -0
  34. decision_graph/decision_tree/bake/c_edge.h +511 -0
  35. decision_graph/decision_tree/bake/c_edge.pxd +117 -0
  36. decision_graph/decision_tree/bake/c_edge.pyi +192 -0
  37. decision_graph/decision_tree/bake/c_edge.pyx +270 -0
  38. decision_graph/decision_tree/bake/c_eval.h +848 -0
  39. decision_graph/decision_tree/bake/c_eval.pxd +40 -0
  40. decision_graph/decision_tree/bake/c_expr.cp315-win_amd64.pyd +0 -0
  41. decision_graph/decision_tree/bake/c_expr.h +1900 -0
  42. decision_graph/decision_tree/bake/c_expr.pxd +129 -0
  43. decision_graph/decision_tree/bake/c_expr.pyi +280 -0
  44. decision_graph/decision_tree/bake/c_expr.pyx +272 -0
  45. decision_graph/decision_tree/bake/c_hierarchy.cp315-win_amd64.pyd +0 -0
  46. decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
  47. decision_graph/decision_tree/bake/c_hierarchy.pxd +71 -0
  48. decision_graph/decision_tree/bake/c_hierarchy.pyi +409 -0
  49. decision_graph/decision_tree/bake/c_hierarchy.pyx +277 -0
  50. decision_graph/decision_tree/bake/c_logic_group.cp315-win_amd64.pyd +0 -0
  51. decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
  52. decision_graph/decision_tree/bake/c_logic_group.pxd +162 -0
  53. decision_graph/decision_tree/bake/c_logic_group.pyi +264 -0
  54. decision_graph/decision_tree/bake/c_logic_group.pyx +308 -0
  55. decision_graph/decision_tree/bake/c_node.cp315-win_amd64.pyd +0 -0
  56. decision_graph/decision_tree/bake/c_node.h +2660 -0
  57. decision_graph/decision_tree/bake/c_node.pxd +381 -0
  58. decision_graph/decision_tree/bake/c_node.pyi +438 -0
  59. decision_graph/decision_tree/bake/c_node.pyx +639 -0
  60. decision_graph/decision_tree/bake/c_reconstruct.cp315-win_amd64.pyd +0 -0
  61. decision_graph/decision_tree/bake/c_reconstruct.pxd +63 -0
  62. decision_graph/decision_tree/bake/c_reconstruct.pyi +60 -0
  63. decision_graph/decision_tree/bake/c_reconstruct.pyx +252 -0
  64. decision_graph/decision_tree/bake/c_var.cp315-win_amd64.pyd +0 -0
  65. decision_graph/decision_tree/bake/c_var.h +2054 -0
  66. decision_graph/decision_tree/bake/c_var.pxd +205 -0
  67. decision_graph/decision_tree/bake/c_var.pyi +271 -0
  68. decision_graph/decision_tree/bake/c_var.pyx +228 -0
  69. decision_graph/decision_tree/capi/__infra__.pxd +33 -0
  70. decision_graph/decision_tree/capi/__init__.pxd +33 -0
  71. decision_graph/decision_tree/capi/__init__.py +57 -0
  72. decision_graph/decision_tree/capi/c_abc.cp315-win_amd64.pyd +0 -0
  73. decision_graph/decision_tree/capi/c_abc.pxd +246 -0
  74. decision_graph/decision_tree/capi/c_abc.pyi +770 -0
  75. decision_graph/decision_tree/capi/c_abc.pyx +1532 -0
  76. decision_graph/decision_tree/capi/c_collection.cp315-win_amd64.pyd +0 -0
  77. decision_graph/decision_tree/capi/c_collection.pxd +22 -0
  78. decision_graph/decision_tree/capi/c_collection.pyi +245 -0
  79. decision_graph/decision_tree/capi/c_collection.pyx +138 -0
  80. decision_graph/decision_tree/capi/c_node.cp315-win_amd64.pyd +0 -0
  81. decision_graph/decision_tree/capi/c_node.pxd +95 -0
  82. decision_graph/decision_tree/capi/c_node.pyi +492 -0
  83. decision_graph/decision_tree/capi/c_node.pyx +551 -0
  84. decision_graph/decision_tree/exc.py +189 -0
  85. decision_graph/decision_tree/native/__init__.py +57 -0
  86. decision_graph/decision_tree/native/abc.py +1167 -0
  87. decision_graph/decision_tree/native/collection.py +134 -0
  88. decision_graph/decision_tree/native/node.py +521 -0
  89. decision_graph/includes/decision_graph/decision_tree/bake/c_action.c +16320 -0
  90. decision_graph/includes/decision_graph/decision_tree/bake/c_action.h +324 -0
  91. decision_graph/includes/decision_graph/decision_tree/bake/c_allocator_protocol.c +12473 -0
  92. decision_graph/includes/decision_graph/decision_tree/bake/c_bake.c +16485 -0
  93. decision_graph/includes/decision_graph/decision_tree/bake/c_bake.h +629 -0
  94. decision_graph/includes/decision_graph/decision_tree/bake/c_collections.c +17381 -0
  95. decision_graph/includes/decision_graph/decision_tree/bake/c_collections.h +692 -0
  96. decision_graph/includes/decision_graph/decision_tree/bake/c_const.c +20815 -0
  97. decision_graph/includes/decision_graph/decision_tree/bake/c_const.h +395 -0
  98. decision_graph/includes/decision_graph/decision_tree/bake/c_edge.c +20696 -0
  99. decision_graph/includes/decision_graph/decision_tree/bake/c_edge.h +511 -0
  100. decision_graph/includes/decision_graph/decision_tree/bake/c_eval.h +848 -0
  101. decision_graph/includes/decision_graph/decision_tree/bake/c_expr.c +22065 -0
  102. decision_graph/includes/decision_graph/decision_tree/bake/c_expr.h +1900 -0
  103. decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.c +23267 -0
  104. decision_graph/includes/decision_graph/decision_tree/bake/c_hierarchy.h +731 -0
  105. decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.c +22434 -0
  106. decision_graph/includes/decision_graph/decision_tree/bake/c_logic_group.h +1226 -0
  107. decision_graph/includes/decision_graph/decision_tree/bake/c_node.c +28385 -0
  108. decision_graph/includes/decision_graph/decision_tree/bake/c_node.h +2660 -0
  109. decision_graph/includes/decision_graph/decision_tree/bake/c_reconstruct.c +15955 -0
  110. decision_graph/includes/decision_graph/decision_tree/bake/c_var.c +16881 -0
  111. decision_graph/includes/decision_graph/decision_tree/bake/c_var.h +2054 -0
  112. decision_graph/includes/decision_graph/decision_tree/capi/c_abc.c +59196 -0
  113. decision_graph/includes/decision_graph/decision_tree/capi/c_collection.c +19967 -0
  114. decision_graph/includes/decision_graph/decision_tree/capi/c_node.c +39229 -0
  115. decision_graph/logic_group/__init__.py +25 -0
  116. decision_graph/logic_group/base.py +100 -0
  117. decision_graph/logic_group/pending_request.py +384 -0
  118. decision_graph/webui/__init__.py +24 -0
  119. decision_graph/webui/bake/__init__.py +65 -0
  120. decision_graph/webui/bake/app.py +488 -0
  121. decision_graph/webui/bake/static/d3.v7.min.js +2 -0
  122. decision_graph/webui/bake/static/script.js +1440 -0
  123. decision_graph/webui/bake/static/style.css +920 -0
  124. decision_graph/webui/bake/templates/index.html +183 -0
  125. decision_graph/webui/bake/templates/offline.html +184 -0
  126. decision_graph/webui/capi/__init__.py +54 -0
  127. decision_graph/webui/capi/app.py +366 -0
  128. decision_graph/webui/capi/main.py +53 -0
  129. decision_graph/webui/capi/static/d3.v7.min.js +2 -0
  130. decision_graph/webui/capi/static/script.js +1026 -0
  131. decision_graph/webui/capi/static/style.css +656 -0
  132. decision_graph/webui/capi/templates/index.html +93 -0
  133. decision_graph/webui/capi/templates/offline.html +94 -0
  134. decision_graph/webui/native/__init__.py +54 -0
  135. decision_graph/webui/native/app.py +366 -0
  136. decision_graph/webui/native/main.py +53 -0
  137. decision_graph/webui/native/static/d3.v7.min.js +2 -0
  138. decision_graph/webui/native/static/script.js +1026 -0
  139. decision_graph/webui/native/static/style.css +656 -0
  140. decision_graph/webui/native/templates/index.html +93 -0
  141. decision_graph/webui/native/templates/offline.html +94 -0
  142. pydecisiongraph-0.3.2.post1.dist-info/METADATA +136 -0
  143. pydecisiongraph-0.3.2.post1.dist-info/RECORD +148 -0
  144. pydecisiongraph-0.3.2.post1.dist-info/WHEEL +5 -0
  145. pydecisiongraph-0.3.2.post1.dist-info/licenses/LICENSE +373 -0
  146. pydecisiongraph-0.3.2.post1.dist-info/top_level.txt +2 -0
  147. tests/bake_c_evaluator.cp315-win_amd64.pyd +0 -0
  148. tests/bake_eval_probe.cp315-win_amd64.pyd +0 -0
@@ -0,0 +1,151 @@
1
+ """The bake protocol: the pass that makes a built graph ready to be walked.
2
+
3
+ A build says what a graph IS and an evaluation says what it DOES. Between the two
4
+ sits this: the last thing done to a graph before it is walked, and the pass every
5
+ evaluation is written assuming has run. It is asked of a ROOT and of nothing else,
6
+ because a graph is entered from one place.
7
+
8
+ Three things, in the order they can be done in. The graph is VERIFIED - what an
9
+ evaluation assumes is established here and nowhere else, because the hot path
10
+ carries no check for a malformed node: every operand an operator takes has a
11
+ component behind it, every operator belongs to its node's arity and every operand
12
+ array is as long as that arity, and no node in the graph is one that has no
13
+ evaluation at all (a call). It is then LOCKED - every node the walk reached is
14
+ frozen, so the graph's structure is what it was, and every store the graph reads
15
+ is sealed, so no entry can appear in it afterwards. A frozen store cannot grow,
16
+ which is what keeps a resolved read's reference into its block good. What locking
17
+ does NOT stop is a value: a store is sealed in SHAPE, and a caller goes on
18
+ writing what it already holds - a graph is baked once and fed many times. It is
19
+ then PREPARED - the record a walk fills has its room made in advance, so an
20
+ evaluation allocates nothing.
21
+
22
+ A bake is all or nothing: a graph that fails the verification is not locked and
23
+ not prepared, so a caller that ignores the report is left with a graph that does
24
+ not work rather than one that half works. A bake that succeeds is idempotent -
25
+ asked again it locks nothing, seals nothing and prepares nothing.
26
+
27
+ The door is ``c_dcg_bake_root``, reached from ``RootLogicNode.bake``; what it
28
+ answers with is a ``BakeReport``.
29
+ """
30
+
31
+ from .c_hierarchy import RootLogicNode
32
+ from .c_node import LogicNode
33
+
34
+
35
+ class BakeReport:
36
+ """What a bake found, and what it affected.
37
+
38
+ A wrapper over one ``dcg_bake_report`` block, which it either OWNS - a report
39
+ of its own, the one a bake is asked to fill - or merely reads through, when a
40
+ caller made the block itself. A report owns nothing behind its block: the node
41
+ it may name belongs to the graph, so the block going is the whole of its
42
+ release.
43
+
44
+ Its fields read where the pass wrote them, so asking twice answers the same
45
+ thing; and a report of its own that no bake has filled yet is a report of a
46
+ bake that never ran - ``DCG_OK``, no node, no counts.
47
+
48
+ Attributes:
49
+ code: The ``DCG_ERR_*`` code the pass ended with - ``DCG_OK`` when the
50
+ graph is baked.
51
+ code_name: That code's stable name (``'OK'``, ``'TYPE'``, ``'UNBOUND'``).
52
+ node: The wrapper of the node the first problem was found on, or None
53
+ when the failure was the pass's own (a machine that ran out of room).
54
+ errors: How many problems were found.
55
+ nodes: How many nodes the pass walked - the branches, and the operands
56
+ they read.
57
+ depth: The deepest level the walk reached.
58
+ locked: How many nodes this pass locked; zero on a re-bake, and zero for
59
+ a validate-only bake.
60
+ sealed: How many stores this pass sealed.
61
+ capacity: The entries the root's record was prepared with; zero when the
62
+ pass did not prepare one.
63
+ """
64
+
65
+ def __init__(self, address: int = 0, owner: bool = False) -> None:
66
+ """A report of its own, or a window onto one that is somebody else's.
67
+
68
+ Args:
69
+ address: Address of a ``dcg_bake_report`` to read through, for the
70
+ caller that made the block itself; 0, the default, makes a report
71
+ of its own instead.
72
+ owner: Whether THIS wrapper releases the block at that address. It is
73
+ ignored when an address is not given - a report made here is the
74
+ wrapper's own and is released with it.
75
+
76
+ Raises:
77
+ MemoryError: When a report of its own cannot be allocated.
78
+ """
79
+ ...
80
+
81
+ @property
82
+ def address(self) -> int:
83
+ """The block's address - what every read here reads through."""
84
+ ...
85
+
86
+ @property
87
+ def code(self) -> int:
88
+ """The ``DCG_ERR_*`` code the pass ended with."""
89
+ ...
90
+
91
+ @property
92
+ def code_name(self) -> str:
93
+ """That code's stable name."""
94
+ ...
95
+
96
+ @property
97
+ def node(self) -> LogicNode | None:
98
+ """The node the first problem was found on, or None when it was the pass's own."""
99
+ ...
100
+
101
+ @property
102
+ def errors(self) -> int:
103
+ """How many problems the pass found."""
104
+ ...
105
+
106
+ @property
107
+ def nodes(self) -> int:
108
+ """How many nodes the pass walked."""
109
+ ...
110
+
111
+ @property
112
+ def depth(self) -> int:
113
+ """The deepest level the walk reached."""
114
+ ...
115
+
116
+ @property
117
+ def locked(self) -> int:
118
+ """How many nodes this pass locked."""
119
+ ...
120
+
121
+ @property
122
+ def sealed(self) -> int:
123
+ """How many stores this pass sealed."""
124
+ ...
125
+
126
+ @property
127
+ def capacity(self) -> int:
128
+ """The entries the root's record was prepared with."""
129
+ ...
130
+
131
+
132
+ def c_dcg_bake_root(root: RootLogicNode, validate_only: bool = False) -> BakeReport:
133
+ """Bake the graph a root stands at the top of, and report what it did.
134
+
135
+ Args:
136
+ root: The root of the graph. A root is the only entry, so this is the
137
+ only door: a graph is entered from one place.
138
+ validate_only: Whether to verify the graph and report without locking or
139
+ preparing it - the question "would this bake?" asked without the
140
+ commitment.
141
+
142
+ Returns:
143
+ The report: what the pass found, and what it affected.
144
+
145
+ Raises:
146
+ RuntimeError: When the root has no block (a wrapper that was never
147
+ built).
148
+ BakeFailureError: When the graph cannot be baked. Nothing was locked and
149
+ nothing was prepared, and the failure carries the report.
150
+ """
151
+ ...
@@ -0,0 +1,142 @@
1
+ from cpython.unicode cimport PyUnicode_FromString
2
+ from libc.stdint cimport uintptr_t
3
+
4
+ from .c_allocator_protocol cimport DCG_DEFAULT_ALLOCATOR
5
+ from .c_node cimport NODE_REGISTRY
6
+ from .c_var cimport c_dcg_ret_code_name
7
+
8
+ from ..exc import BakeFailureError
9
+
10
+
11
+ __all__ = ['BakeReport', 'c_dcg_bake_root']
12
+
13
+
14
+ cdef class BakeReport:
15
+ def __cinit__(self, *args, **kwargs):
16
+ self.header = NULL
17
+ self.owner = False
18
+
19
+ def __init__(self, uintptr_t address=0, bint owner=False):
20
+ if address:
21
+ self.header = <dcg_bake_report*> address
22
+ self.owner = owner
23
+ return
24
+
25
+ # No address: a report of its own, to be filled by the pass it is handed
26
+ # to. That is what the door hands back, and what a caller who wants to
27
+ # read a bake afterwards keeps.
28
+ self.header = c_dcg_bake_report_new(DCG_DEFAULT_ALLOCATOR)
29
+ if not self.header:
30
+ raise MemoryError('Failed to allocate the BakeReport.')
31
+ self.owner = True
32
+
33
+ def __dealloc__(self):
34
+ if self.owner and self.header:
35
+ c_dcg_bake_report_free(self.header)
36
+ self.header = NULL
37
+
38
+ @staticmethod
39
+ cdef BakeReport c_from_header(dcg_bake_report* header, bint owner=False):
40
+ cdef BakeReport instance = BakeReport.__new__(BakeReport)
41
+ instance.header = header
42
+ instance.owner = owner
43
+ return instance
44
+
45
+ def __repr__(self):
46
+ if not self.header:
47
+ return f'<{self.__class__.__name__} (Uninitialized)>'
48
+ return (
49
+ f'<{self.__class__.__name__}('
50
+ f'code={self.code_name}, node={self.node!r}, errors={self.header.errors}, '
51
+ f'nodes={self.header.nodes}, depth={self.header.depth}, locked={self.header.locked}, '
52
+ f'sealed={self.header.sealed}, capacity={self.header.capacity})>'
53
+ )
54
+
55
+ # === Python Properties ===
56
+
57
+ property address:
58
+ def __get__(self):
59
+ if not self.header:
60
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
61
+ return <uintptr_t> self.header
62
+
63
+ property code:
64
+ def __get__(self):
65
+ if not self.header:
66
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
67
+ return <int> self.header.code
68
+
69
+ property code_name:
70
+ def __get__(self):
71
+ if not self.header:
72
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
73
+ return PyUnicode_FromString(c_dcg_ret_code_name(self.header.code))
74
+
75
+ property node:
76
+ def __get__(self):
77
+ if not self.header:
78
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
79
+ cdef dcg_node* node = self.header.node
80
+ return None if not node else NODE_REGISTRY[<uintptr_t> node]
81
+
82
+ property errors:
83
+ def __get__(self):
84
+ if not self.header:
85
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
86
+ return self.header.errors
87
+
88
+ property nodes:
89
+ def __get__(self):
90
+ if not self.header:
91
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
92
+ return self.header.nodes
93
+
94
+ property depth:
95
+ def __get__(self):
96
+ if not self.header:
97
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
98
+ return self.header.depth
99
+
100
+ property locked:
101
+ def __get__(self):
102
+ if not self.header:
103
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
104
+ return self.header.locked
105
+
106
+ property sealed:
107
+ def __get__(self):
108
+ if not self.header:
109
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
110
+ return self.header.sealed
111
+
112
+ property capacity:
113
+ def __get__(self):
114
+ if not self.header:
115
+ raise RuntimeError(f'<{self.__class__.__name__}> not initialized!')
116
+ return self.header.capacity
117
+
118
+
119
+ cdef inline str c_bake_failure_message(BakeReport report):
120
+ """What to say about a bake the graph did not survive - the node, or the pass itself."""
121
+ cdef str where = 'the pass itself' if report.node is None else f'{report.node!r}'
122
+ return f'bake stopped at {where} with {report.code_name}: {report.errors} problem(s) found, nothing was locked'
123
+
124
+
125
+ cpdef BakeReport c_dcg_bake_root(RootLogicNode root, bint validate_only=False):
126
+ if not root.header:
127
+ raise RuntimeError(f'<{root.__class__.__name__}> not initialized!')
128
+
129
+ # The report is the answer, so it is the wrapper's own block: the pass fills
130
+ # it in place, and the failure below travels with it.
131
+ cdef BakeReport answer = BakeReport()
132
+
133
+ cdef dcg_bake_input input
134
+ c_dcg_bake_input_init(&input)
135
+ if validate_only:
136
+ input.flags = DCG_BAKE_FLAG_VALIDATE_ONLY
137
+
138
+ cdef int ret_code = c_dcg_root_node_bake(<dcg_root_node*> root.header, &input, answer.header)
139
+
140
+ if ret_code != dcg_ret_code.DCG_OK:
141
+ raise BakeFailureError(c_bake_failure_message(answer), report=answer)
142
+ return answer