compiled-knowledge 4.0.0a18__cp312-cp312-win_amd64.whl → 4.0.0a20__cp312-cp312-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.

Potentially problematic release.


This version of compiled-knowledge might be problematic. Click here for more details.

Files changed (27) hide show
  1. ck/circuit/__init__.py +0 -3
  2. ck/circuit/_circuit_cy.c +37523 -0
  3. ck/circuit/_circuit_cy.cp312-win_amd64.pyd +0 -0
  4. ck/circuit/_circuit_cy.pxd +3 -4
  5. ck/circuit/_circuit_cy.pyx +80 -79
  6. ck/circuit_compiler/cython_vm_compiler/_compiler.c +19824 -0
  7. ck/circuit_compiler/cython_vm_compiler/_compiler.cp312-win_amd64.pyd +0 -0
  8. ck/circuit_compiler/cython_vm_compiler/_compiler.pyx +188 -75
  9. ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py +29 -4
  10. ck/circuit_compiler/support/circuit_analyser/__init__.py +13 -0
  11. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.c +10618 -0
  12. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cp312-win_amd64.pyd +0 -0
  13. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.pyx +98 -0
  14. ck/circuit_compiler/support/{circuit_analyser.py → circuit_analyser/_circuit_analyser_py.py} +14 -2
  15. ck/pgm_compiler/ace/__init__.py +1 -1
  16. ck/pgm_compiler/support/circuit_table/__init__.py +1 -0
  17. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.c +16396 -0
  18. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cp312-win_amd64.pyd +0 -0
  19. ck_demos/ace/demo_ace.py +5 -0
  20. {compiled_knowledge-4.0.0a18.dist-info → compiled_knowledge-4.0.0a20.dist-info}/METADATA +1 -1
  21. {compiled_knowledge-4.0.0a18.dist-info → compiled_knowledge-4.0.0a20.dist-info}/RECORD +24 -20
  22. ck/pgm_compiler/support/circuit_table/_circuit_table_cy_cpp_verion.pyx +0 -601
  23. ck/pgm_compiler/support/circuit_table/_circuit_table_cy_minimal_version.pyx +0 -311
  24. ck/pgm_compiler/support/circuit_table/_circuit_table_cy_v4.0.0a17.pyx +0 -325
  25. {compiled_knowledge-4.0.0a18.dist-info → compiled_knowledge-4.0.0a20.dist-info}/WHEEL +0 -0
  26. {compiled_knowledge-4.0.0a18.dist-info → compiled_knowledge-4.0.0a20.dist-info}/licenses/LICENSE.txt +0 -0
  27. {compiled_knowledge-4.0.0a18.dist-info → compiled_knowledge-4.0.0a20.dist-info}/top_level.txt +0 -0
Binary file
@@ -1,18 +1,17 @@
1
1
  cdef class Circuit:
2
2
  cdef public list[VarNode] vars
3
3
  cdef public list[OpNode] ops
4
- cdef public object zero
5
- cdef public object one
4
+ cdef public ConstNode zero
5
+ cdef public ConstNode one
6
6
  cdef dict[object, ConstNode] _const_map
7
7
  cdef object __derivatives
8
8
 
9
9
  cdef OpNode op(self, int symbol, tuple[CircuitNode, ...] nodes)
10
+ cdef list[OpNode] find_reachable_op_nodes(self, list[CircuitNode] nodes)
10
11
  cdef void _remove_unreachable_op_nodes(self, list[CircuitNode] nodes)
11
- cdef list[OpNode] _reachable_op_nodes(self, list[CircuitNode] nodes)
12
12
  cdef list[CircuitNode] _check_nodes(self, object nodes)
13
13
  cdef void __check_nodes(self, object nodes, list[CircuitNode] result)
14
14
  cdef object _derivatives(self, CircuitNode f)
15
- cdef object _derivatives(self, CircuitNode f)
16
15
 
17
16
  cdef class CircuitNode:
18
17
  cdef public Circuit circuit
@@ -4,7 +4,7 @@ For more documentation on this module, refer to the Jupyter notebook docs/6_circ
4
4
  from __future__ import annotations
5
5
 
6
6
  from itertools import chain
7
- from typing import Dict, Tuple, Optional, Iterable, Sequence, List, overload
7
+ from typing import Dict, Optional, Iterable, Sequence, List, overload
8
8
 
9
9
  # Type for values of ConstNode objects
10
10
  ConstValue = float | int | bool
@@ -41,13 +41,11 @@ cdef class Circuit:
41
41
  """
42
42
  self.vars: List[VarNode] = []
43
43
  self.ops: List[OpNode] = []
44
- self._const_map: Dict[ConstValue, ConstNode] = {}
45
- self.__derivatives: Optional[_DerivativeHelper] = None # cache for partial derivatives calculations.
46
44
  self.zero: ConstNode = ConstNode(self, zero, is_zero=True)
47
45
  self.one: ConstNode = ConstNode(self, one, is_one=True)
48
46
 
49
- self._const_map[zero] = self.zero
50
- self._const_map[one] = self.one
47
+ self._const_map: Dict[ConstValue, ConstNode] = {zero: self.zero, one: self.one}
48
+ self.__derivatives: Optional[_DerivativeHelper] = None # cache for partial derivatives calculations.
51
49
 
52
50
  @property
53
51
  def number_of_vars(self) -> int:
@@ -145,7 +143,7 @@ cdef class Circuit:
145
143
  * singleton addition is avoided: add(x) = x,
146
144
  * empty addition is avoided: add() = 0,
147
145
  """
148
- cdef tuple[CircuitNode] to_add = tuple(n for n in self._check_nodes(args) if not n.is_zero)
146
+ cdef tuple[CircuitNode, ...] to_add = tuple(n for n in self._check_nodes(args) if not n.is_zero)
149
147
  cdef size_t num_to_add = len(to_add)
150
148
  if num_to_add == 0:
151
149
  return self.zero
@@ -163,10 +161,10 @@ cdef class Circuit:
163
161
  * singleton multiplication is avoided: mul(x) = x,
164
162
  * empty multiplication is avoided: mul() = 1,
165
163
  """
166
- cdef tuple[CircuitNode] to_mul = tuple(n for n in self._check_nodes(args) if not n.is_one)
164
+ cdef tuple[CircuitNode, ...] to_mul = tuple(n for n in self._check_nodes(args) if not n.is_one)
167
165
  if any(n.is_zero for n in to_mul):
168
166
  return self.zero
169
- cdef size_t num_to_mul = len(to_mul)
167
+ cdef Py_ssize_t num_to_mul = len(to_mul)
170
168
 
171
169
  if num_to_mul == 0:
172
170
  return self.one
@@ -186,12 +184,12 @@ cdef class Circuit:
186
184
  a list of 'mul' nodes, one for each combination of xs and ys. The results are in the order
187
185
  given by `[mul(x, y) for x in xs for y in ys]`.
188
186
  """
189
- xs: List[CircuitNode] = self._check_nodes(xs)
190
- ys: List[CircuitNode] = self._check_nodes(ys)
187
+ cdef list[CircuitNode] xs_list = self._check_nodes(xs)
188
+ cdef list[CircuitNode] ys_list = self._check_nodes(ys)
191
189
  return [
192
190
  self.optimised_mul(x, y)
193
- for x in xs
194
- for y in ys
191
+ for x in xs_list
192
+ for y in ys_list
195
193
  ]
196
194
 
197
195
  @overload
@@ -242,10 +240,10 @@ cdef class Circuit:
242
240
  If `args` is a single CircuitNode, then a single CircuitNode will be returned, otherwise
243
241
  a list of CircuitNode is returned.
244
242
  """
245
- single_result: bool = isinstance(args, CircuitNode)
243
+ cdef bint single_result = isinstance(args, CircuitNode)
246
244
 
247
- args: List[CircuitNode] = self._check_nodes([args])
248
- if len(args) == 0:
245
+ cdef list[CircuitNode] args_list = self._check_nodes([args])
246
+ if len(args_list) == 0:
249
247
  # Trivial case
250
248
  return []
251
249
 
@@ -254,12 +252,12 @@ cdef class Circuit:
254
252
  if self_multiply:
255
253
  result = [
256
254
  derivatives.derivative_self_mul(arg)
257
- for arg in args
255
+ for arg in args_list
258
256
  ]
259
257
  else:
260
258
  result = [
261
259
  derivatives.derivative(arg)
262
- for arg in args
260
+ for arg in args_list
263
261
  ]
264
262
 
265
263
  if single_result:
@@ -283,8 +281,8 @@ cdef class Circuit:
283
281
  Args:
284
282
  *nodes: may be either a node or a list of nodes.
285
283
  """
286
- nodes = self._check_nodes(nodes)
287
- self._remove_unreachable_op_nodes(nodes)
284
+ cdef list[CircuitNode] node_list = self._check_nodes(nodes)
285
+ self._remove_unreachable_op_nodes(node_list)
288
286
 
289
287
  def reachable_op_nodes(self, *nodes: Args) -> List[OpNode]:
290
288
  """
@@ -300,8 +298,8 @@ cdef class Circuit:
300
298
  Returned nodes are not repeated.
301
299
  The result is ordered such that if result[i] is referenced by result[j] then i < j.
302
300
  """
303
- nodes = self._check_nodes(nodes)
304
- return self._reachable_op_nodes(nodes)
301
+ cdef list[CircuitNode] node_list = self._check_nodes(nodes)
302
+ return self.find_reachable_op_nodes(node_list)
305
303
 
306
304
  def dump(
307
305
  self,
@@ -371,7 +369,7 @@ cdef class Circuit:
371
369
  self.ops.append(node)
372
370
  return node
373
371
 
374
- cdef list[OpNode] _reachable_op_nodes(self, list[CircuitNode] nodes):
372
+ cdef list[OpNode] find_reachable_op_nodes(self, list[CircuitNode] nodes):
375
373
  # Set of object ids for all reachable op nodes
376
374
  cdef set[int] seen = set()
377
375
 
@@ -379,7 +377,7 @@ cdef class Circuit:
379
377
 
380
378
  cdef CircuitNode node
381
379
  for node in nodes:
382
- _reachable_op_nodes_r(node, seen, result)
380
+ find_reachable_op_nodes_r(node, seen, result)
383
381
  return result
384
382
 
385
383
  cdef void _remove_unreachable_op_nodes(self, list[CircuitNode] nodes):
@@ -388,7 +386,7 @@ cdef class Circuit:
388
386
 
389
387
  cdef CircuitNode node
390
388
  for node in nodes:
391
- _reachable_op_nodes_seen_r(node, seen)
389
+ find_reachable_op_nodes_seen_r(node, seen)
392
390
 
393
391
  if len(seen) < len(self.ops):
394
392
  # Invalidate unreadable op nodes
@@ -401,7 +399,7 @@ cdef class Circuit:
401
399
  self.ops = [op_node for op_node in self.ops if id(op_node) in seen]
402
400
 
403
401
  cdef list[CircuitNode] _check_nodes(self, object nodes: Iterable[Args]): # -> Sequence[CircuitNode]:
404
- # Convert the given circuit nodes to a tuple, flattening nested iterables as needed.
402
+ # Convert the given circuit nodes to a list, flattening nested iterables as needed.
405
403
  #
406
404
  # Args:
407
405
  # nodes: some circuit nodes of constant values.
@@ -413,7 +411,7 @@ cdef class Circuit:
413
411
  return result
414
412
 
415
413
  cdef void __check_nodes(self, object nodes: Iterable[Args], list[CircuitNode] result):
416
- # Convert the given circuit nodes to a tuple, flattening nested iterables as needed.
414
+ # Convert the given circuit nodes to a list, flattening nested iterables as needed.
417
415
  #
418
416
  # Args:
419
417
  # nodes: some circuit nodes of constant values.
@@ -530,7 +528,7 @@ cdef class OpNode(CircuitNode):
530
528
  A node in a circuit representing an arithmetic operation.
531
529
  """
532
530
 
533
- def __init__(self, object circuit, symbol: int, tuple[object, ...] args: Tuple[CircuitNode]):
531
+ def __init__(self, Circuit circuit, int symbol, tuple[CircuitNode, ...] args):
534
532
  super().__init__(circuit, False, False)
535
533
  self.args = tuple(args)
536
534
  self.symbol = <int> symbol
@@ -554,11 +552,11 @@ cdef class _DNode:
554
552
  A data structure supporting derivative calculations.
555
553
  A DNode holds all information needed to calculate the partial derivative at `node`.
556
554
  """
557
- cdef public object node
558
- cdef public object derivative
559
- cdef public object derivative_self_mul
560
- cdef public list sum_prod
561
- cdef public bint processed
555
+ cdef CircuitNode node
556
+ cdef object derivative
557
+ cdef object derivative_self_mul
558
+ cdef list[_DNodeProduct] sum_prod
559
+ cdef bint processed
562
560
 
563
561
  def __init__(
564
562
  self,
@@ -590,8 +588,8 @@ cdef class _DNodeProduct:
590
588
 
591
589
  The represents a product of `parent` and `prod`.
592
590
  """
593
- cdef public object parent
594
- cdef public list prod
591
+ cdef _DNode parent
592
+ cdef list[CircuitNode] prod
595
593
 
596
594
  def __init__(self, parent: _DNode, prod: List[CircuitNode]):
597
595
  self.parent = parent
@@ -604,33 +602,40 @@ cdef class _DNodeProduct:
604
602
  return 'DNodeProduct(' + str(self.parent) + ', ' + str(self.prod) + ')'
605
603
 
606
604
 
607
- class _DerivativeHelper:
605
+ cdef class _DerivativeHelper:
608
606
  """
609
607
  A data structure to support efficient calculation of partial derivatives
610
608
  with respect to some function node `f`.
611
609
  """
612
610
 
611
+ cdef CircuitNode f
612
+ cdef CircuitNode zero
613
+ cdef CircuitNode one
614
+ cdef Circuit circuit
615
+ cdef dict[int, _DNode] d_nodes
616
+
613
617
  def __init__(self, f: CircuitNode):
614
618
  """
615
619
  Prepare to calculate partial derivatives with respect to `f`.
616
620
  """
617
- self.f: CircuitNode = f
618
- self.circuit: Circuit = f.circuit
619
- self.d_nodes: Dict[int, _DNode] = {} # map id(CircuitNode) to its DNode
621
+ self.f = f
622
+ self.circuit = f.circuit
623
+ self.d_nodes = {} # map id(CircuitNode) to its DNode
620
624
  self.zero = self.circuit.zero
621
625
  self.one = self.circuit.one
622
- top_d_node: _DNode = _DNode(f, self.one)
626
+
627
+ cdef _DNode top_d_node = _DNode(f, self.one)
623
628
  self.d_nodes[id(f)] = top_d_node
624
629
  self._mk_derivative_r(top_d_node)
625
630
 
626
- def derivative(self, node: CircuitNode) -> CircuitNode:
631
+ cdef CircuitNode derivative(self, CircuitNode node):
627
632
  d_node: Optional[_DNode] = self.d_nodes.get(id(node))
628
633
  if d_node is None:
629
634
  return self.zero
630
635
  else:
631
636
  return self._derivative(d_node)
632
637
 
633
- def derivative_self_mul(self, node: CircuitNode) -> CircuitNode:
638
+ cdef CircuitNode derivative_self_mul(self, CircuitNode node):
634
639
  d_node: Optional[_DNode] = self.d_nodes.get(id(node))
635
640
  if d_node is None:
636
641
  return self.zero
@@ -646,7 +651,7 @@ class _DerivativeHelper:
646
651
 
647
652
  return d_node.derivative_self_mul
648
653
 
649
- def _derivative(self, d_node: _DNode) -> CircuitNode:
654
+ cdef CircuitNode _derivative(self, _DNode d_node):
650
655
  if d_node.derivative is not None:
651
656
  return d_node.derivative
652
657
 
@@ -664,10 +669,9 @@ class _DerivativeHelper:
664
669
 
665
670
  return d_node.derivative
666
671
 
667
- def _derivative_prod(self, prods: _DNodeProduct) -> CircuitNode:
668
- """
669
- Support `_derivative` by constructing the derivative product for the given _DNodeProduct.
670
- """
672
+ cdef CircuitNode _derivative_prod(self, _DNodeProduct prods):
673
+ # Support `_derivative` by constructing the derivative product for the given _DNodeProduct.
674
+
671
675
  # Get the derivative of the parent node.
672
676
  parent: CircuitNode = self._derivative(prods.parent)
673
677
 
@@ -683,10 +687,9 @@ class _DerivativeHelper:
683
687
  # Construct the multiplication operation
684
688
  return self.circuit.optimised_mul(*to_mul)
685
689
 
686
- def _mk_derivative_r(self, d_node: _DNode) -> None:
687
- """
688
- Construct a DNode for each argument of the given DNode.
689
- """
690
+ cdef void _mk_derivative_r(self, _DNode d_node):
691
+ # Construct a DNode for each argument of the given DNode.
692
+
690
693
  if d_node.processed:
691
694
  return
692
695
  d_node.processed = True
@@ -703,37 +706,35 @@ class _DerivativeHelper:
703
706
  child_d_node = self._add(arg, d_node, prod)
704
707
  self._mk_derivative_r(child_d_node)
705
708
 
706
- def _add(self, node: CircuitNode, parent: _DNode, prod: List[CircuitNode]) -> _DNode:
707
- """
708
- Support for `_mk_derivative_r`.
709
-
710
- Add a _DNodeProduct(parent, negate, prod) to the DNode for the given circuit node.
711
-
712
- If the DNode for `node` does not yet exist, one will be created.
713
-
714
- The given circuit node may have multiple parents (i.e., a shared sub-expression). Therefore,
715
- this method may be called multiple times for a given node. Each time a new _DNodeProduct will be added.
716
-
717
- Args:
718
- node: the CircuitNode that the returned DNode is for.
719
- parent: the DNode of the parent node, i.e., `node` is an argument to the parent node.
720
- prod: other circuit nodes that need to be multiplied with the parent derivative when
721
- constructing a derivative for `node`.
709
+ cdef _DNode _add(self, CircuitNode node, _DNode parent, list[CircuitNode] prod):
710
+ # Support for `_mk_derivative_r`.
711
+ #
712
+ # Add a _DNodeProduct(parent, negate, prod) to the DNode for the given circuit node.
713
+ #
714
+ # If the DNode for `node` does not yet exist, one will be created.
715
+ #
716
+ # The given circuit node may have multiple parents (i.e., a shared sub-expression). Therefore,
717
+ # this method may be called multiple times for a given node. Each time a new _DNodeProduct will be added.
718
+ #
719
+ # Args:
720
+ # node: the CircuitNode that the returned DNode is for.
721
+ # parent: the DNode of the parent node, i.e., `node` is an argument to the parent node.
722
+ # prod: other circuit nodes that need to be multiplied with the parent derivative when
723
+ # constructing a derivative for `node`.
724
+ #
725
+ # Returns:
726
+ # the DNode for `node`.
722
727
 
723
- Returns:
724
- the DNode for `node`.
725
- """
726
728
  child_d_node: _DNode = self._get(node)
727
729
  child_d_node.sum_prod.append(_DNodeProduct(parent, prod))
728
730
  return child_d_node
729
731
 
730
- def _get(self, node: CircuitNode) -> _DNode:
731
- """
732
- Helper for derivatives.
732
+ cdef _DNode _get(self, CircuitNode node):
733
+ # Helper for derivatives.
734
+ #
735
+ # Get the DNode for the given circuit node.
736
+ # If no DNode exist for it yet, then one will be constructed.
733
737
 
734
- Get the DNode for the given circuit node.
735
- If no DNode exist for it yet, then one will be constructed.
736
- """
737
738
  node_id: int = id(node)
738
739
  d_node: Optional[_DNode] = self.d_nodes.get(node_id)
739
740
  if d_node is None:
@@ -742,7 +743,7 @@ class _DerivativeHelper:
742
743
  return d_node
743
744
 
744
745
 
745
- cdef void _reachable_op_nodes_r(CircuitNode node, set[int] seen, list[OpNode] result):
746
+ cdef void find_reachable_op_nodes_r(CircuitNode node, set[int] seen, list[OpNode] result):
746
747
  # Recursive helper for `reachable_op_nodes`. Performs a depth-first search.
747
748
  #
748
749
  # Args:
@@ -752,10 +753,10 @@ cdef void _reachable_op_nodes_r(CircuitNode node, set[int] seen, list[OpNode] re
752
753
  if isinstance(node, OpNode) and id(node) not in seen:
753
754
  seen.add(id(node))
754
755
  for arg in node.args:
755
- _reachable_op_nodes_r(arg, seen, result)
756
+ find_reachable_op_nodes_r(arg, seen, result)
756
757
  result.append(node)
757
758
 
758
- cdef void _reachable_op_nodes_seen_r(CircuitNode node, set[int] seen):
759
+ cdef void find_reachable_op_nodes_seen_r(CircuitNode node, set[int] seen):
759
760
  # Recursive helper for `remove_unreachable_op_nodes`. Performs a depth-first search.
760
761
  #
761
762
  # Args:
@@ -764,4 +765,4 @@ cdef void _reachable_op_nodes_seen_r(CircuitNode node, set[int] seen):
764
765
  if isinstance(node, OpNode) and id(node) not in seen:
765
766
  seen.add(id(node))
766
767
  for arg in node.args:
767
- _reachable_op_nodes_seen_r(arg, seen)
768
+ find_reachable_op_nodes_seen_r(arg, seen)