compiled-knowledge 4.0.0a17__cp312-cp312-win_amd64.whl → 4.0.0a19__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 +4 -0
  2. ck/circuit/_circuit_cy.cp312-win_amd64.pyd +0 -0
  3. ck/circuit/_circuit_cy.pxd +32 -0
  4. ck/circuit/_circuit_cy.pyx +157 -182
  5. ck/circuit/_circuit_py.py +2 -2
  6. ck/circuit_compiler/cython_vm_compiler/_compiler.cp312-win_amd64.pyd +0 -0
  7. ck/circuit_compiler/cython_vm_compiler/_compiler.pyx +193 -79
  8. ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py +29 -4
  9. ck/circuit_compiler/support/circuit_analyser/__init__.py +13 -0
  10. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cp312-win_amd64.pyd +0 -0
  11. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.pyx +98 -0
  12. ck/circuit_compiler/support/{circuit_analyser.py → circuit_analyser/_circuit_analyser_py.py} +14 -2
  13. ck/pgm_compiler/ace/__init__.py +1 -1
  14. ck/pgm_compiler/support/circuit_table/__init__.py +8 -0
  15. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cp312-win_amd64.pyd +0 -0
  16. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.pyx +44 -37
  17. ck/pgm_compiler/support/circuit_table/_circuit_table_py.py +76 -41
  18. ck/pgm_compiler/support/named_compiler_maker.py +12 -2
  19. ck/utils/iter_extras.py +8 -1
  20. ck_demos/ace/demo_ace.py +5 -0
  21. ck_demos/utils/compare.py +5 -1
  22. {compiled_knowledge-4.0.0a17.dist-info → compiled_knowledge-4.0.0a19.dist-info}/METADATA +1 -1
  23. {compiled_knowledge-4.0.0a17.dist-info → compiled_knowledge-4.0.0a19.dist-info}/RECORD +26 -23
  24. {compiled_knowledge-4.0.0a17.dist-info → compiled_knowledge-4.0.0a19.dist-info}/WHEEL +1 -1
  25. ck/circuit_compiler/cython_vm_compiler/_compiler.c +0 -16946
  26. {compiled_knowledge-4.0.0a17.dist-info → compiled_knowledge-4.0.0a19.dist-info}/licenses/LICENSE.txt +0 -0
  27. {compiled_knowledge-4.0.0a17.dist-info → compiled_knowledge-4.0.0a19.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Sequence, Tuple, Iterable, Iterator
3
+ from typing import Sequence, Tuple, Iterable
4
+
5
+ from ck.circuit import MUL, ADD
6
+
7
+ from ck.circuit._circuit_cy cimport Circuit, CircuitNode
8
+
9
+ cdef int c_ADD = ADD
10
+ cdef int c_MUL = MUL
4
11
 
5
- from ck.circuit import CircuitNode, Circuit, OpNode, MUL
6
12
 
7
13
  TableInstance = Tuple[int, ...]
8
14
 
@@ -22,14 +28,14 @@ cdef class CircuitTable:
22
28
  zero node. These are assumed to be optimised out already.
23
29
  """
24
30
 
25
- cdef public object circuit
31
+ cdef public Circuit circuit
26
32
  cdef public tuple[int, ...] rv_idxs
27
- cdef public dict[tuple[int, ...], CircuitNode] rows
33
+ cdef dict[tuple[int, ...], CircuitNode] rows
28
34
 
29
35
  def __init__(
30
36
  self,
31
37
  circuit: Circuit,
32
- rv_idxs: Sequence[int, ...],
38
+ rv_idxs: Sequence[int],
33
39
  rows: Iterable[Tuple[TableInstance, CircuitNode]] = (),
34
40
  ):
35
41
  """
@@ -53,13 +59,19 @@ cdef class CircuitTable:
53
59
  def get(self, key, default=None):
54
60
  return self.rows.get(key, default)
55
61
 
62
+ def keys(self) -> Iterable[CircuitNode]:
63
+ return self.rows.keys()
64
+
65
+ def values(self) -> Iterable[tuple[int, ...]]:
66
+ return self.rows.values()
67
+
56
68
  def __getitem__(self, key):
57
69
  return self.rows[key]
58
70
 
59
71
  def __setitem__(self, key, value):
60
72
  self.rows[key] = value
61
73
 
62
- cpdef object top(self): # -> CircuitNode:
74
+ cpdef CircuitNode top(self):
63
75
  # Get the circuit top value.
64
76
  #
65
77
  # Raises:
@@ -80,7 +92,7 @@ cdef class CircuitTable:
80
92
  # Circuit Table Operations
81
93
  # ==================================================================================
82
94
 
83
- cpdef object sum_out(object table: CircuitTable, object rv_idxs: Iterable[int]): # -> CircuitTable:
95
+ cpdef CircuitTable sum_out(CircuitTable table, object rv_idxs: Iterable[int]):
84
96
  # Return a circuit table that results from summing out
85
97
  # the given random variables of this circuit table.
86
98
  #
@@ -118,12 +130,12 @@ cpdef object sum_out(object table: CircuitTable, object rv_idxs: Iterable[int]):
118
130
  for rv_index in remaining_rv_idxs:
119
131
  index_map.append(_find(table.rv_idxs, rv_index))
120
132
 
121
- cdef dict[tuple[int, ...], list[object]] groups = {}
133
+ cdef dict[tuple[int, ...], list[CircuitNode]] groups = {}
122
134
  cdef object got
123
135
  cdef list[int] group_instance
124
136
  cdef tuple[int, ...] group_instance_tuple
125
137
  cdef int i
126
- cdef object node
138
+ cdef CircuitNode node
127
139
  cdef tuple[int, ...] instance
128
140
  for instance, node in table.rows.items():
129
141
  group_instance = []
@@ -136,19 +148,19 @@ cpdef object sum_out(object table: CircuitTable, object rv_idxs: Iterable[int]):
136
148
  else:
137
149
  got.append(node)
138
150
 
139
- cdef object circuit = table.circuit
140
- cdef object new_table = CircuitTable(circuit, remaining_rv_idxs)
141
- cdef dict[tuple[int, ...], object] rows = new_table.rows
151
+ cdef Circuit circuit = table.circuit
152
+ cdef CircuitTable new_table = CircuitTable(circuit, remaining_rv_idxs)
153
+ cdef dict[tuple[int, ...], CircuitNode] rows = new_table.rows
142
154
 
143
155
  for group_instance_tuple, to_add in groups.items():
144
- node = circuit.optimised_add(to_add)
156
+ node = circuit.op(c_ADD, tuple(to_add))
145
157
  if not node.is_zero:
146
158
  rows[group_instance_tuple] = node
147
159
 
148
160
  return new_table
149
161
 
150
162
 
151
- cpdef object sum_out_all(object table: CircuitTable): # -> CircuitTable:
163
+ cpdef CircuitTable sum_out_all(CircuitTable table):
152
164
  # Return a circuit table that results from summing out
153
165
  # all random variables of this circuit table.
154
166
  circuit: Circuit = table.circuit
@@ -158,14 +170,14 @@ cpdef object sum_out_all(object table: CircuitTable): # -> CircuitTable:
158
170
  elif num_rows == 1:
159
171
  node = next(iter(table.rows.values()))
160
172
  else:
161
- node: CircuitNode = circuit.optimised_add(table.rows.values())
173
+ node: CircuitNode = circuit.op(c_ADD, tuple(table.rows.values()))
162
174
  if node.is_zero:
163
175
  return CircuitTable(circuit, ())
164
176
 
165
177
  return CircuitTable(circuit, (), [((), node)])
166
178
 
167
179
 
168
- cpdef object project(object table: CircuitTable, object rv_idxs: Iterable[int]): # -> CircuitTable:
180
+ cpdef CircuitTable project(CircuitTable table: CircuitTable, object rv_idxs: Iterable[int]):
169
181
  # Call `sum_out(table, to_sum_out)`, where
170
182
  # `to_sum_out = table.rv_idxs - rv_idxs`.
171
183
  cdef set[int] to_sum_out = set(table.rv_idxs)
@@ -173,13 +185,13 @@ cpdef object project(object table: CircuitTable, object rv_idxs: Iterable[int]):
173
185
  return sum_out(table, to_sum_out)
174
186
 
175
187
 
176
- cpdef object product(x: CircuitTable, y: CircuitTable): # -> CircuitTable:
188
+ cpdef CircuitTable product(CircuitTable x, CircuitTable y):
177
189
  # Return a circuit table that results from the product of the two given tables.
178
190
  #
179
191
  # If x or y equals `one_table`, then the other table is returned. Otherwise,
180
192
  # a new circuit table will be constructed and returned.
181
193
  cdef int i
182
- cdef object circuit = x.circuit
194
+ cdef Circuit circuit = x.circuit
183
195
  if y.circuit is not circuit:
184
196
  raise ValueError('circuit tables must refer to the same circuit')
185
197
 
@@ -229,12 +241,12 @@ cpdef object product(x: CircuitTable, y: CircuitTable): # -> CircuitTable:
229
241
  cdef tuple[int, ...] co_tuple
230
242
  cdef tuple[int, ...] yo_tuple
231
243
 
232
- cdef object table = CircuitTable(circuit, x.rv_idxs + yo_rv_idxs)
233
- cdef dict[tuple[int, ...], object] rows = table.rows
244
+ cdef CircuitTable table = CircuitTable(circuit, x.rv_idxs + yo_rv_idxs)
245
+ cdef dict[tuple[int, ...], CircuitNode] rows = table.rows
234
246
 
235
247
 
236
248
  # Index the y rows by common-only key (y is the smaller of the two tables).
237
- cdef dict[tuple[int, ...], list[tuple[tuple[int, ...], object]]] y_index = {}
249
+ cdef dict[tuple[int, ...], list[tuple[tuple[int, ...], CircuitNode]]] y_index = {}
238
250
  for y_instance, y_node in y.rows.items():
239
251
  co = []
240
252
  yo = []
@@ -271,7 +283,10 @@ cpdef object product(x: CircuitTable, y: CircuitTable): # -> CircuitTable:
271
283
  got = y_index.get(co_tuple)
272
284
  if got is not None:
273
285
  for yo_tuple, y_node in got:
274
- rows[x_instance + yo_tuple] = _optimised_mul(circuit, x_node, y_node)
286
+ if y_node.is_one:
287
+ rows[x_instance + yo_tuple] = x_node
288
+ else:
289
+ rows[x_instance + yo_tuple] = circuit.op(c_MUL, (x_node, y_node))
275
290
 
276
291
  return table
277
292
 
@@ -285,7 +300,7 @@ cdef int _find(tuple[int, ...] xs, int x):
285
300
  raise RuntimeError('not found')
286
301
 
287
302
 
288
- cdef object _product_no_common_rvs(x: CircuitTable, y: CircuitTable): # -> CircuitTable:
303
+ cdef CircuitTable _product_no_common_rvs(CircuitTable x, CircuitTable y):
289
304
  # Return the product of x and y, where x and y have no common random variables.
290
305
  #
291
306
  # This is an optimisation of more general product algorithm as no index needs
@@ -296,8 +311,8 @@ cdef object _product_no_common_rvs(x: CircuitTable, y: CircuitTable): # -> Circ
296
311
  # Assumes:
297
312
  # * There are no common random variables between x and y.
298
313
  # * x and y are for the same circuit.
299
- cdef object circuit = x.circuit
300
- cdef object table = CircuitTable(circuit, x.rv_idxs + y.rv_idxs)
314
+ cdef Circuit circuit = x.circuit
315
+ cdef CircuitTable table = CircuitTable(circuit, x.rv_idxs + y.rv_idxs)
301
316
  cdef tuple[int, ...] instance
302
317
 
303
318
  for x_instance, x_node in x.rows.items():
@@ -308,18 +323,10 @@ cdef object _product_no_common_rvs(x: CircuitTable, y: CircuitTable): # -> Circ
308
323
  else:
309
324
  for y_instance, y_node in y.rows.items():
310
325
  instance = x_instance + y_instance
311
- table.rows[instance] = _optimised_mul(circuit, x_node, y_node)
326
+ if y_node.is_one:
327
+ table.rows[instance] = x_node
328
+ else:
329
+ table.rows[instance] = circuit.op(c_MUL, (x_node, y_node))
312
330
 
313
331
  return table
314
332
 
315
-
316
- cdef object _optimised_mul(object circuit: Circuit, object x: CircuitNode, object y: CircuitNode): # -> CircuitNode
317
- if x.is_zero:
318
- return x
319
- if y.is_zero:
320
- return y
321
- if x.is_one:
322
- return y
323
- if y.is_one:
324
- return x
325
- return circuit.mul(x, y)
@@ -40,21 +40,38 @@ class CircuitTable:
40
40
  * all row instances conform to the indexed random variables.
41
41
  * all row circuit nodes belong to the given circuit.
42
42
  """
43
- self.circuit: Circuit = circuit
44
- self.rv_idxs: Tuple[int, ...] = tuple(rv_idxs)
45
- self.rows: Dict[TableInstance, CircuitNode] = dict(rows)
43
+ self._circuit: Circuit = circuit
44
+ self._rv_idxs: Tuple[int, ...] = tuple(rv_idxs)
45
+ self._rows: Dict[TableInstance, CircuitNode] = dict(rows)
46
+
47
+ @property
48
+ def circuit(self) -> Circuit:
49
+ return self._circuit
50
+
51
+ @property
52
+ def rv_idxs(self) -> Tuple[int, ...]:
53
+ return self._rv_idxs
46
54
 
47
55
  def __len__(self) -> int:
48
- return len(self.rows)
56
+ return len(self._rows)
49
57
 
50
58
  def get(self, key, default=None):
51
- return self.rows.get(key, default)
59
+ return self._rows.get(key, default)
60
+
61
+ def keys(self) -> Iterable[TableInstance]:
62
+ return self._rows.keys()
63
+
64
+ def values(self) -> Iterable[CircuitNode]:
65
+ return self._rows.values()
66
+
67
+ def items(self) -> Iterable[Tuple[TableInstance, CircuitNode]]:
68
+ return self._rows.items()
52
69
 
53
70
  def __getitem__(self, key):
54
- return self.rows[key]
71
+ return self._rows[key]
55
72
 
56
73
  def __setitem__(self, key, value):
57
- self.rows[key] = value
74
+ self._rows[key] = value
58
75
 
59
76
  def top(self) -> CircuitNode:
60
77
  """
@@ -66,10 +83,10 @@ class CircuitTable:
66
83
  Returns:
67
84
  A single circuit node.
68
85
  """
69
- if len(self.rows) == 0:
70
- return self.circuit.zero
71
- elif len(self.rows) == 1:
72
- return next(iter(self.rows.values()))
86
+ if len(self._rows) == 0:
87
+ return self._circuit.zero
88
+ elif len(self._rows) == 1:
89
+ return next(iter(self._rows.values()))
73
90
  else:
74
91
  raise RuntimeError('cannot get top node from a table with more that 1 row')
75
92
 
@@ -119,20 +136,34 @@ def sum_out(table: CircuitTable, rv_idxs: Iterable[int]) -> CircuitTable:
119
136
  for remaining_rv_index in remaining_rv_idxs
120
137
  )
121
138
 
139
+ # This is a one-pass version to sum the groups. The
140
+ # two-pass version (below) seems to have better performance.
141
+ #
142
+ # circuit: Circuit = table.circuit
143
+ # result = CircuitTable(circuit, remaining_rv_idxs)
144
+ # result_rows: Dict[TableInstance, CircuitNode] = result._rows
145
+ # for instance, node in table.items():
146
+ # group_instance = tuple(instance[i] for i in index_map)
147
+ # prev_sum = result_rows.get(group_instance)
148
+ # if prev_sum is None:
149
+ # result_rows[group_instance] = node
150
+ # else:
151
+ # result_rows[group_instance] = circuit.add(prev_sum, node)
152
+ # return result
153
+
122
154
  groups: MapList[TableInstance, CircuitNode] = MapList()
123
- for instance, node in table.rows.items():
155
+ for instance, node in table.items():
124
156
  group_instance = tuple(instance[i] for i in index_map)
125
157
  groups.append(group_instance, node)
126
-
127
158
  circuit: Circuit = table.circuit
128
-
129
- def _result_rows() -> Iterator[Tuple[TableInstance, CircuitNode]]:
130
- for group, to_add in groups.items():
131
- _node: CircuitNode = circuit.optimised_add(to_add)
132
- if not _node.is_zero:
133
- yield group, _node
134
-
135
- return CircuitTable(circuit, remaining_rv_idxs, _result_rows())
159
+ return CircuitTable(
160
+ circuit,
161
+ remaining_rv_idxs,
162
+ (
163
+ (group, circuit.add(to_add))
164
+ for group, to_add in groups.items()
165
+ )
166
+ )
136
167
 
137
168
 
138
169
  def sum_out_all(table: CircuitTable) -> CircuitTable:
@@ -145,9 +176,9 @@ def sum_out_all(table: CircuitTable) -> CircuitTable:
145
176
  if num_rows == 0:
146
177
  return CircuitTable(circuit, ())
147
178
  elif num_rows == 1:
148
- node = next(iter(table.rows.values()))
179
+ node = next(iter(table.values()))
149
180
  else:
150
- node: CircuitNode = circuit.optimised_add(table.rows.values())
181
+ node: CircuitNode = circuit.optimised_add(table.values())
151
182
  if node.is_zero:
152
183
  return CircuitTable(circuit, ())
153
184
 
@@ -168,7 +199,7 @@ def product(x: CircuitTable, y: CircuitTable) -> CircuitTable:
168
199
  """
169
200
  Return a circuit table that results from the product of the two given tables.
170
201
 
171
- If x or y equals `one_table`, then the other table is returned. Otherwise,
202
+ If x or y have a single row with value 1, then the other table is returned. Otherwise,
172
203
  a new circuit table will be constructed and returned.
173
204
  """
174
205
  circuit: Circuit = x.circuit
@@ -193,18 +224,18 @@ def product(x: CircuitTable, y: CircuitTable) -> CircuitTable:
193
224
  # Set operations on rv indexes. After these operations:
194
225
  # * co_rv_idxs is the set of rv indexes common (co) to x and y,
195
226
  # * yo_rv_idxs is the set of rv indexes in y only (yo), and not in x.
196
- yo_rv_idxs: Set[int] = set(y_rv_idxs)
197
- co_rv_idxs: Set[int] = set(x_rv_idxs)
198
- co_rv_idxs.intersection_update(yo_rv_idxs)
199
- yo_rv_idxs.difference_update(co_rv_idxs)
227
+ yo_rv_idxs_set: Set[int] = set(y_rv_idxs)
228
+ co_rv_idxs_set: Set[int] = set(x_rv_idxs)
229
+ co_rv_idxs_set.intersection_update(yo_rv_idxs_set)
230
+ yo_rv_idxs_set.difference_update(co_rv_idxs_set)
200
231
 
201
- if len(co_rv_idxs) == 0:
232
+ if len(co_rv_idxs_set) == 0:
202
233
  # Special case: no common random variables.
203
234
  return _product_no_common_rvs(x, y)
204
235
 
205
236
  # Convert random variable index sets to sequences
206
- yo_rv_idxs: Tuple[int, ...] = tuple(yo_rv_idxs) # y only random variables
207
- co_rv_idxs: Tuple[int, ...] = tuple(co_rv_idxs) # common random variables
237
+ yo_rv_idxs: Tuple[int, ...] = tuple(yo_rv_idxs_set) # y only random variables
238
+ co_rv_idxs: Tuple[int, ...] = tuple(co_rv_idxs_set) # common random variables
208
239
 
209
240
  # Cache mappings from result Instance to index into source Instance (x or y).
210
241
  # This will be used in indexing and product loops to pull our needed values
@@ -215,7 +246,7 @@ def product(x: CircuitTable, y: CircuitTable) -> CircuitTable:
215
246
 
216
247
  # Index the y rows by common-only key (y is the smaller of the two tables).
217
248
  y_index: MapList[TableInstance, Tuple[TableInstance, CircuitNode]] = MapList()
218
- for y_instance, y_node in y.rows.items():
249
+ for y_instance, y_node in y.items():
219
250
  co = tuple(y_instance[i] for i in co_from_y_map)
220
251
  yo = tuple(y_instance[i] for i in yo_from_y_map)
221
252
  y_index.append(co, (yo, y_node))
@@ -223,7 +254,7 @@ def product(x: CircuitTable, y: CircuitTable) -> CircuitTable:
223
254
  def _result_rows() -> Iterator[Tuple[TableInstance, CircuitNode]]:
224
255
  # Iterate over x rows, yielding (instance, value).
225
256
  # Rows with constant node values of one are optimised out.
226
- for _x_instance, _x_node in x.rows.items():
257
+ for _x_instance, _x_node in x.items():
227
258
  _co = tuple(_x_instance[i] for i in co_from_x_map)
228
259
  if _x_node.is_one:
229
260
  # Multiplying by one.
@@ -233,7 +264,10 @@ def product(x: CircuitTable, y: CircuitTable) -> CircuitTable:
233
264
  else:
234
265
  # Iterate over matching y rows.
235
266
  for _yo, _y_node in y_index.get(_co, ()):
236
- yield _x_instance + _yo, circuit.optimised_mul((_x_node, _y_node))
267
+ if _y_node.is_one:
268
+ yield _x_instance + _yo, _x_node
269
+ else:
270
+ yield _x_instance + _yo, circuit.mul(_x_node, _y_node)
237
271
 
238
272
  return CircuitTable(circuit, x_rv_idxs + yo_rv_idxs, _result_rows())
239
273
 
@@ -256,14 +290,15 @@ def _product_no_common_rvs(x: CircuitTable, y: CircuitTable) -> CircuitTable:
256
290
  result_rv_idxs: Tuple[int, ...] = x.rv_idxs + y.rv_idxs
257
291
 
258
292
  def _result_rows() -> Iterator[Tuple[TableInstance, CircuitNode]]:
259
- for x_instance, x_node in x.rows.items():
293
+ for x_instance, x_node in x.items():
260
294
  if x_node.is_one:
261
- for y_instance, y_node in y.rows.items():
262
- instance = x_instance + y_instance
263
- yield instance, y_node
295
+ for y_instance, y_node in y.items():
296
+ yield x_instance + y_instance, y_node
264
297
  else:
265
- for y_instance, y_node in y.rows.items():
266
- instance = x_instance + y_instance
267
- yield instance, circuit.optimised_mul((x_node, y_node))
298
+ for y_instance, y_node in y.items():
299
+ if y_node.is_one:
300
+ yield x_instance + y_instance, y_node
301
+ else:
302
+ yield x_instance + y_instance, circuit.mul(x_node, y_node)
268
303
 
269
304
  return CircuitTable(circuit, result_rv_idxs, _result_rows())
@@ -12,6 +12,7 @@ def get_compiler(module: ModuleType, **kwargs) -> Tuple[PGMCompiler]:
12
12
 
13
13
  Args:
14
14
  module: module containing `compile_pgm` function.
15
+ kwargs: are additional keyword arguments to `compile_pgm`.
15
16
 
16
17
  Returns:
17
18
  a singleton tuple containing PGMCompiler function.
@@ -24,10 +25,19 @@ def get_compiler(module: ModuleType, **kwargs) -> Tuple[PGMCompiler]:
24
25
  return compiler,
25
26
 
26
27
 
27
- def get_compiler_algorithm(module, algorithm: str, **kwargs) -> Tuple[PGMCompiler]:
28
+ def get_compiler_algorithm(module: ModuleType, algorithm: str, **kwargs) -> Tuple[PGMCompiler]:
28
29
  """
29
30
  Helper function to create a named PGM compiler, with a named algorithm argument.
31
+
32
+ Args:
33
+ module: module containing `compile_pgm` function.
34
+ algorithm: name of the algorithm, to pass as keyword argument to `compile_pgm`.
35
+ The algorithm should be declared in the module.
36
+ kwargs: are additional keyword arguments to `compile_pgm`.
37
+
38
+ Returns:
39
+ a singleton tuple containing PGMCompiler function.
30
40
  """
31
- return get_compiler(module, algorithm=getattr(module, algorithm, **kwargs))
41
+ return get_compiler(module, algorithm=getattr(module, algorithm), **kwargs)
32
42
 
33
43
 
ck/utils/iter_extras.py CHANGED
@@ -2,7 +2,7 @@
2
2
  A module with extra iteration functions.
3
3
  """
4
4
  from functools import reduce as _reduce
5
- from itertools import combinations, chain
5
+ from itertools import combinations, chain, islice
6
6
  from operator import mul as _mul
7
7
  from typing import Iterable, Tuple, Sequence, TypeVar
8
8
 
@@ -154,3 +154,10 @@ def first(items: Iterable[_T]) -> _T:
154
154
  Return the first element of the iterable.
155
155
  """
156
156
  return next(iter(items))
157
+
158
+
159
+ def take(iterable: Iterable[_T], n: int) -> Iterable[_T]:
160
+ """
161
+ Take the first n elements of the iterable.
162
+ """
163
+ return islice(iterable, n)
ck_demos/ace/demo_ace.py CHANGED
@@ -6,6 +6,11 @@ from ck.pgm_circuit.wmc_program import WMCProgram
6
6
 
7
7
 
8
8
  def main() -> None:
9
+
10
+ if not ace.ace_available():
11
+ print("ACE is not available")
12
+ exit(1)
13
+
9
14
  pgm: PGM = example.Rain()
10
15
 
11
16
  # `ace.compile_pgm` will look for an Ace installation in
ck_demos/utils/compare.py CHANGED
@@ -1,3 +1,4 @@
1
+ import gc
1
2
  from typing import Sequence
2
3
 
3
4
  from ck.circuit_compiler import NamedCircuitCompiler
@@ -88,6 +89,7 @@ def compare(
88
89
  print(f'{"":{col_cct_ops}}', end=sep)
89
90
  print(f'{"":{col_pgm_compile_time}}', end=sep)
90
91
  else:
92
+ gc.collect()
91
93
  time.start()
92
94
  pgm_cct: PGMCircuit = pgm_compiler(pgm)
93
95
  time.stop()
@@ -97,6 +99,7 @@ def compare(
97
99
  prev_pgm = pgm
98
100
  prev_pgm_compiler = pgm_compiler
99
101
 
102
+ gc.collect()
100
103
  time.start()
101
104
  # `pgm_cct` will always be set but the IDE can't work that out.
102
105
  # noinspection PyUnboundLocalVariable
@@ -104,11 +107,12 @@ def compare(
104
107
  time.stop()
105
108
  print(f'{time.seconds():{col_cct_compile_time}{comma}.3f}', end=sep)
106
109
 
110
+ gc.collect()
107
111
  time.start()
108
112
  for _ in range(1000):
109
113
  wmc.compute()
110
114
  time.stop()
111
- print(f'{time.seconds() * 1000:{col_execute_time}{comma}.3f}', end=sep)
115
+ print(f'{time.seconds() * 1000:{col_execute_time}{comma}.3f}', end='')
112
116
  except Exception as err:
113
117
  print(repr(err), end='')
114
118
  print()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: compiled-knowledge
3
- Version: 4.0.0a17
3
+ Version: 4.0.0a19
4
4
  Summary: A Python package for compiling and querying discrete probabilistic graphical models.
5
5
  Author-email: Barry Drake <barry@compiledknowledge.org>
6
6
  License-Expression: MIT
@@ -1,9 +1,10 @@
1
1
  ck/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  ck/pgm.py,sha256=rbqgP-clfSvgpzUXxVjk_6SdM9neHmpChku6qpyeidk,120700
3
- ck/circuit/__init__.py,sha256=pMe0M2WI0A1Kr8TCty82oRKrHnDeTjL1rr0Wy03shY0,217
4
- ck/circuit/_circuit_cy.cp312-win_amd64.pyd,sha256=Pyd-NonuBw-XvnguxnsZBqf3P4O1W9Tdlt3T4p4OWG4,248320
5
- ck/circuit/_circuit_cy.pyx,sha256=wFu81taNG3M-SLJivhVoJwZVX_50eHyBVduIx5vtHFw,28453
6
- ck/circuit/_circuit_py.py,sha256=9C-5PuKEnU8eTgdCZysTAsbvHDOLTcsSjzcXdIHH-Ow,28339
3
+ ck/circuit/__init__.py,sha256=klUR7OVESf53-8Ho4f32clHFsR2SOz4XgwZzfDlms88,418
4
+ ck/circuit/_circuit_cy.cp312-win_amd64.pyd,sha256=i4-iiLDcHW_9qU6aXtmYLF-eLd48LKP2XY4EUkLqa0Q,240640
5
+ ck/circuit/_circuit_cy.pxd,sha256=F1WU4KuX_knXQX-hwNKoHsoUK3fJLbLOxEnomWMJFpI,1057
6
+ ck/circuit/_circuit_cy.pyx,sha256=RGfHGBj3XibLw4S5CC6FVnXOHjpzU0_aoVowqIY2qzA,27773
7
+ ck/circuit/_circuit_py.py,sha256=vN8lg01RyjA_YUphjx1dr0Uj4ql4seczRcoCaH7ylAw,28341
7
8
  ck/circuit/tmp_const.py,sha256=dG9FuGfoAG5qjYG1rNwekqKiea_KmVfxHMTOgCPbBiQ,2372
8
9
  ck/circuit_compiler/__init__.py,sha256=T0Igyp5jPgnIXv4oRcIYhmsOdcNOb3L4Za6dK6eYk7g,132
9
10
  ck/circuit_compiler/circuit_compiler.py,sha256=8BLB8DUnPbpl5PXZsIopydPbItytdn2rzRfM2U1EC84,1018
@@ -12,14 +13,16 @@ ck/circuit_compiler/llvm_compiler.py,sha256=ejeNPkO5Og2FyjjyA5JAexxUl1f8IJ6mwU5N
12
13
  ck/circuit_compiler/llvm_vm_compiler.py,sha256=I46_XV5FrClDKO06zIjn8T3ME5XQ9RYJ_1aAE8e_YzM,21873
13
14
  ck/circuit_compiler/named_circuit_compilers.py,sha256=snlD3JnhAZC-atKpf5GD0v4CGdvj2_ZhCZ3O-tsxzxc,2284
14
15
  ck/circuit_compiler/cython_vm_compiler/__init__.py,sha256=pEAwTleuZgdYhTAQMea2f9YsFK54eoNbZSbrWkW8aeE,49
15
- ck/circuit_compiler/cython_vm_compiler/_compiler.c,sha256=nL6nPNrlx6RfmGeK7ZFgw38PMrs7n4w0KFBV9ba_zcU,722307
16
- ck/circuit_compiler/cython_vm_compiler/_compiler.cp312-win_amd64.pyd,sha256=JK43LQ7GVu7P_Lx5xO7-qdKi0z9baTTSthYg0Ra8XEQ,81920
17
- ck/circuit_compiler/cython_vm_compiler/_compiler.pyx,sha256=c9NVKWtL2ctY_ja5MZg74hgw8hKKztLi7FB6S1kLTe4,8542
18
- ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py,sha256=yUkBNr5HnoVXyWjJdXHp8lyAXFiIDYapvMvHtzKuhI8,3140
16
+ ck/circuit_compiler/cython_vm_compiler/_compiler.cp312-win_amd64.pyd,sha256=WWvN7NHOri3UnBebI5Qq-lkYZyY_ZUH2lyOWzhlz3Yc,101376
17
+ ck/circuit_compiler/cython_vm_compiler/_compiler.pyx,sha256=QS6FG5z-ay9fnUTCMwtJm89I3QpfY6RqS874zHvZrBA,13225
18
+ ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py,sha256=WywW6uhoyP-U5hWdF1amsE8fhbP9LbDtWTu2wVFkR2k,4066
19
19
  ck/circuit_compiler/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- ck/circuit_compiler/support/circuit_analyser.py,sha256=jM0QW2flucvpc6fqcT8mL00ZA0rPTUhaE-yFfFQMXgE,2722
21
20
  ck/circuit_compiler/support/input_vars.py,sha256=x6krN6sW9A-vZTteY4M4on_0vS4ChaaCcmnXcnQ4y0s,4812
22
21
  ck/circuit_compiler/support/llvm_ir_function.py,sha256=7SoYEQiBS2GHFknw0raH0ouJyBQmYp-ZydJVEXVo0Uw,7779
22
+ ck/circuit_compiler/support/circuit_analyser/__init__.py,sha256=RbyIObAAb-w0Ky4fB198xAfxTh2doquN9ez68SZSZgo,536
23
+ ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cp312-win_amd64.pyd,sha256=HHml4RcdmX8c3XesRgch1KhLs8tVeA18ENOhT6zBpmk,53248
24
+ ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.pyx,sha256=ctDOHOjnUhdsR_XHBrgchFVTImLhsEUjU3cqkP-GdF8,3331
25
+ ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_py.py,sha256=eWjc2B946LeSzcGa9PyI4XQvlx_B1KPEiQuM6OOFjjQ,3086
23
26
  ck/example/__init__.py,sha256=BXVxvTcl3tqgai-xJiGQIaG_ChlpPRdfWg985MQ7dwM,1744
24
27
  ck/example/alarm.py,sha256=QkHoUb6MxZzCOCX4nLE8UJazNEqAPqrFWQ01lslvdsk,25274
25
28
  ck/example/asia.py,sha256=IX8L-9YCk_DxE-PjYTv1VL33V2oxkHrL7rHmDkMj3kY,1295
@@ -77,17 +80,17 @@ ck/pgm_compiler/named_pgm_compilers.py,sha256=kYMomYlsW7xbL0hzTWQb41EckkugaCfuYH
77
80
  ck/pgm_compiler/pgm_compiler.py,sha256=F44PtlwqMG0FS6KzOYKZuyZT6olWAVtBH-QXZPzz4O8,616
78
81
  ck/pgm_compiler/recursive_conditioning.py,sha256=U0NdIns8yLQtYR_MOf1w__CChpOMDlgRCL2nFRhtnzU,7936
79
82
  ck/pgm_compiler/variable_elimination.py,sha256=irAZ5b0vRGL_WGq7UrfQpMXhYBZO5YI2U_jf1-YV92Q,3547
80
- ck/pgm_compiler/ace/__init__.py,sha256=BkZXAF32Pk8QU7jhkuKvHqtsFasPjf8gxiZbyrGDDbQ,82
83
+ ck/pgm_compiler/ace/__init__.py,sha256=Rud883H68yz2Dw-NkiiTPC6rmii6hHKMHbtiU6_liug,97
81
84
  ck/pgm_compiler/ace/ace.py,sha256=iyDacqArXW1cVP6tBabxRmmLWIHabuPkCoq2tWBm2ww,10397
82
85
  ck/pgm_compiler/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
86
  ck/pgm_compiler/support/clusters.py,sha256=7jsZfPqv29vZNxmtiHBCBo3mEfvLQ_ejYh69M_d-nmo,21381
84
87
  ck/pgm_compiler/support/factor_tables.py,sha256=tV9qE2zC8iwEQxTuXE6qiE6lmMpz4-Vc80_w5woo1tk,15556
85
88
  ck/pgm_compiler/support/join_tree.py,sha256=OGAuZVHzT0i4e6TJ03dOM7e3gbpuW9AyjZKvSBvKvJA,12894
86
- ck/pgm_compiler/support/named_compiler_maker.py,sha256=tQ79JOI8MknAziUiFhFGV9n4y6PPKrnbq3-quMmnrwY,974
87
- ck/pgm_compiler/support/circuit_table/__init__.py,sha256=V_hwJxsHqGucmE1k1VYg6QGzB9zJeaFBc2LBUyof3dk,172
88
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cp312-win_amd64.pyd,sha256=m3OToh7KVIuOSxII_D0bbbDlnpUZ4bqjTOu9IoPH-DY,94720
89
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.pyx,sha256=JLC4_nsRPb8xC3alHE0G9Ojie9K4oUULVPrulkQnhds,11886
90
- ck/pgm_compiler/support/circuit_table/_circuit_table_py.py,sha256=Dr6R4BU_UGlDZYYq3jOlEdIwk_OilExaurSznIeajls,10146
89
+ ck/pgm_compiler/support/named_compiler_maker.py,sha256=g2MLnlkWXkISHL6dh23EY53SptTo7-itfuZogSpMdB8,1420
90
+ ck/pgm_compiler/support/circuit_table/__init__.py,sha256=yJ05NvuNE9j0E_QnjDzHYfLqcHn5TdOleEpG3wSRgXQ,579
91
+ ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cp312-win_amd64.pyd,sha256=1hTK-DgCHmIsqsGw4fD-le9zLM5Z93k9plAKlF8KtpE,93696
92
+ ck/pgm_compiler/support/circuit_table/_circuit_table_cy.pyx,sha256=rVO1yxjZmZ6yv5s0zKq4Ji9WYrDuYTZsRG_zeF1_1xE,12015
93
+ ck/pgm_compiler/support/circuit_table/_circuit_table_py.py,sha256=h6xPYGBSy6XHQBFLPD2D1-V7Kiw9utY68nWrcGRMEg4,11287
91
94
  ck/probability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
95
  ck/probability/empirical_probability_space.py,sha256=HoLxmigzlWFWQlcZQwDOYk-mjgf6RW1IPE-l0t8vMPw,1950
93
96
  ck/probability/pgm_probability_space.py,sha256=vK-drx145PWW2aYB8HttQcvhvqPfxVl72bPcFO8jw8M,1034
@@ -107,7 +110,7 @@ ck/sampling/wmc_gibbs_sampler.py,sha256=GMKVW2AVtsWtP6vxE3Y2dy-dKr7GoO_vLEA9eC30
107
110
  ck/sampling/wmc_metropolis_sampler.py,sha256=PRv7wtPZz7BcwN8iArsykVwqgY77v5km7rXcawFAUPQ,6470
108
111
  ck/sampling/wmc_rejection_sampler.py,sha256=cd0VONZf-oa491RRKfwT2LakQs0o_slgPCes8AOvSNc,4897
109
112
  ck/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
- ck/utils/iter_extras.py,sha256=DDml5Jprmun2RovJxkwXx1uJkWacYhZEnX1ARSX2TB4,4310
113
+ ck/utils/iter_extras.py,sha256=QNd3mJxPsKN0Wg12K_Iuefto5A2Vv9leuMvymAdt4uo,4479
111
114
  ck/utils/local_config.py,sha256=-oTKvKCpm29JeHEhV1_qLC5fMS523unDzXr0VYE3M0U,9535
112
115
  ck/utils/map_list.py,sha256=T2OpjI7eDgC4geCtW_FsEr6ryiePOnKZwfDahB63zfA,3847
113
116
  ck/utils/map_set.py,sha256=BLu9BO3FCtzZlZ9MfP9STtIdQ4Me8-QKdwB7o15y7f8,3809
@@ -118,7 +121,7 @@ ck_demos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
121
  ck_demos/all_demos.py,sha256=E1SZDvG0l_j1PfHZLemHocezw10uY5uGl3yE3BX87DE,2556
119
122
  ck_demos/ace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
120
123
  ck_demos/ace/copy_ace_to_ck.py,sha256=TJHPGcUbd1a6OjH3Fw7c3fno8ULPbf5p3V_lBmiNR-k,303
121
- ck_demos/ace/demo_ace.py,sha256=yF35GsYtFZxzTFqXlD_yoEg25BA8wROB5HbuOaxLPUs,1365
124
+ ck_demos/ace/demo_ace.py,sha256=Ve_0Ho-jeOrfpFAV-XBSW_jxcWqFYeCQyo_VQd3Aik4,1458
122
125
  ck_demos/circuit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
126
  ck_demos/circuit/demo_circuit_dump.py,sha256=CQC5cxXaaRuVZ3d8h-SqXs8EJo0Tm5H5l7T9ad6pyEk,458
124
127
  ck_demos/circuit/demo_derivatives.py,sha256=3JoWVAEKLEoLjq6QzWkq4Z-qVq1l0tHvGDn5erVuozc,1186
@@ -160,12 +163,12 @@ ck_demos/sampling/demo_marginal_direct_sampler.py,sha256=RhNunuIUnYI_GXp9m8wzadM
160
163
  ck_demos/sampling/demo_uniform_sampler.py,sha256=Z6tX_OYKGLc_w3-kEPK4KEZlJo7F5HOq_tUVppB_VQE,962
161
164
  ck_demos/sampling/demo_wmc_direct_sampler.py,sha256=c7maxTmZyIijaVdFs2h_KQbK30LvI-oCm2BXSUXVoD8,1113
162
165
  ck_demos/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
163
- ck_demos/utils/compare.py,sha256=MwigxgMqeV7slrzdIJYVJ340QBCCXOeUzUKOJkkd98w,4972
166
+ ck_demos/utils/compare.py,sha256=Bwjpflevl4nusfA0zp96rInaVKFGuhC5Xv7HzA1Fobk,5088
164
167
  ck_demos/utils/convert_network.py,sha256=TSKj8q7L7J5rhrvwjaDkdYZ0Sg8vV5FRL_vCanX1CQw,1363
165
168
  ck_demos/utils/sample_model.py,sha256=in-Nlv-iuNIu6y9fDuMyo7nzgimBuTAnCWcpnVqvqDQ,8839
166
169
  ck_demos/utils/stop_watch.py,sha256=VzXHRWx0V8vPSD-bLgLlEYkCkR2FA0-KmM_pfKx-Pxo,13205
167
- compiled_knowledge-4.0.0a17.dist-info/licenses/LICENSE.txt,sha256=uMYx7tmroEKNASizbCOwPveMQsD5UErLDC1_SANmNn8,1089
168
- compiled_knowledge-4.0.0a17.dist-info/METADATA,sha256=tOzAP4I8J_GgurONBokeDJvcG1Ycdizt7uW3pDqcM7Y,1838
169
- compiled_knowledge-4.0.0a17.dist-info/WHEEL,sha256=b7PoVIxzH_MOHKjftqMzQiGKfdHRlRFepVBVPg0y3vc,101
170
- compiled_knowledge-4.0.0a17.dist-info/top_level.txt,sha256=Cf8DAfd2vcnLiA7HlxoduOzV0Q-8surE3kzX8P9qdks,12
171
- compiled_knowledge-4.0.0a17.dist-info/RECORD,,
170
+ compiled_knowledge-4.0.0a19.dist-info/licenses/LICENSE.txt,sha256=uMYx7tmroEKNASizbCOwPveMQsD5UErLDC1_SANmNn8,1089
171
+ compiled_knowledge-4.0.0a19.dist-info/METADATA,sha256=bLp-yhVx425Su0k6KY8otIbFy91Igxu6gLjMzttddCw,1838
172
+ compiled_knowledge-4.0.0a19.dist-info/WHEEL,sha256=8UP9x9puWI0P1V_d7K2oMTBqfeLNm21CTzZ_Ptr0NXU,101
173
+ compiled_knowledge-4.0.0a19.dist-info/top_level.txt,sha256=Cf8DAfd2vcnLiA7HlxoduOzV0Q-8surE3kzX8P9qdks,12
174
+ compiled_knowledge-4.0.0a19.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-win_amd64
5
5