compiled-knowledge 4.0.0a20__cp313-cp313-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 (178) hide show
  1. ck/__init__.py +0 -0
  2. ck/circuit/__init__.py +17 -0
  3. ck/circuit/_circuit_cy.c +37523 -0
  4. ck/circuit/_circuit_cy.cp313-win_amd64.pyd +0 -0
  5. ck/circuit/_circuit_cy.pxd +32 -0
  6. ck/circuit/_circuit_cy.pyx +768 -0
  7. ck/circuit/_circuit_py.py +836 -0
  8. ck/circuit/tmp_const.py +74 -0
  9. ck/circuit_compiler/__init__.py +2 -0
  10. ck/circuit_compiler/circuit_compiler.py +26 -0
  11. ck/circuit_compiler/cython_vm_compiler/__init__.py +1 -0
  12. ck/circuit_compiler/cython_vm_compiler/_compiler.c +19824 -0
  13. ck/circuit_compiler/cython_vm_compiler/_compiler.cp313-win_amd64.pyd +0 -0
  14. ck/circuit_compiler/cython_vm_compiler/_compiler.pyx +380 -0
  15. ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py +121 -0
  16. ck/circuit_compiler/interpret_compiler.py +223 -0
  17. ck/circuit_compiler/llvm_compiler.py +388 -0
  18. ck/circuit_compiler/llvm_vm_compiler.py +546 -0
  19. ck/circuit_compiler/named_circuit_compilers.py +57 -0
  20. ck/circuit_compiler/support/__init__.py +0 -0
  21. ck/circuit_compiler/support/circuit_analyser/__init__.py +13 -0
  22. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.c +10618 -0
  23. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cp313-win_amd64.pyd +0 -0
  24. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.pyx +98 -0
  25. ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_py.py +93 -0
  26. ck/circuit_compiler/support/input_vars.py +148 -0
  27. ck/circuit_compiler/support/llvm_ir_function.py +234 -0
  28. ck/example/__init__.py +53 -0
  29. ck/example/alarm.py +366 -0
  30. ck/example/asia.py +28 -0
  31. ck/example/binary_clique.py +32 -0
  32. ck/example/bow_tie.py +33 -0
  33. ck/example/cancer.py +37 -0
  34. ck/example/chain.py +38 -0
  35. ck/example/child.py +199 -0
  36. ck/example/clique.py +33 -0
  37. ck/example/cnf_pgm.py +39 -0
  38. ck/example/diamond_square.py +68 -0
  39. ck/example/earthquake.py +36 -0
  40. ck/example/empty.py +10 -0
  41. ck/example/hailfinder.py +539 -0
  42. ck/example/hepar2.py +628 -0
  43. ck/example/insurance.py +504 -0
  44. ck/example/loop.py +40 -0
  45. ck/example/mildew.py +38161 -0
  46. ck/example/munin.py +22982 -0
  47. ck/example/pathfinder.py +53747 -0
  48. ck/example/rain.py +39 -0
  49. ck/example/rectangle.py +161 -0
  50. ck/example/run.py +30 -0
  51. ck/example/sachs.py +129 -0
  52. ck/example/sprinkler.py +30 -0
  53. ck/example/star.py +44 -0
  54. ck/example/stress.py +64 -0
  55. ck/example/student.py +43 -0
  56. ck/example/survey.py +46 -0
  57. ck/example/triangle_square.py +54 -0
  58. ck/example/truss.py +49 -0
  59. ck/in_out/__init__.py +3 -0
  60. ck/in_out/parse_ace_lmap.py +216 -0
  61. ck/in_out/parse_ace_nnf.py +322 -0
  62. ck/in_out/parse_net.py +480 -0
  63. ck/in_out/parser_utils.py +185 -0
  64. ck/in_out/pgm_pickle.py +42 -0
  65. ck/in_out/pgm_python.py +268 -0
  66. ck/in_out/render_bugs.py +111 -0
  67. ck/in_out/render_net.py +177 -0
  68. ck/in_out/render_pomegranate.py +184 -0
  69. ck/pgm.py +3475 -0
  70. ck/pgm_circuit/__init__.py +1 -0
  71. ck/pgm_circuit/marginals_program.py +352 -0
  72. ck/pgm_circuit/mpe_program.py +237 -0
  73. ck/pgm_circuit/pgm_circuit.py +79 -0
  74. ck/pgm_circuit/program_with_slotmap.py +236 -0
  75. ck/pgm_circuit/slot_map.py +35 -0
  76. ck/pgm_circuit/support/__init__.py +0 -0
  77. ck/pgm_circuit/support/compile_circuit.py +83 -0
  78. ck/pgm_circuit/target_marginals_program.py +103 -0
  79. ck/pgm_circuit/wmc_program.py +323 -0
  80. ck/pgm_compiler/__init__.py +2 -0
  81. ck/pgm_compiler/ace/__init__.py +1 -0
  82. ck/pgm_compiler/ace/ace.py +299 -0
  83. ck/pgm_compiler/factor_elimination.py +395 -0
  84. ck/pgm_compiler/named_pgm_compilers.py +63 -0
  85. ck/pgm_compiler/pgm_compiler.py +19 -0
  86. ck/pgm_compiler/recursive_conditioning.py +231 -0
  87. ck/pgm_compiler/support/__init__.py +0 -0
  88. ck/pgm_compiler/support/circuit_table/__init__.py +17 -0
  89. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.c +16396 -0
  90. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cp313-win_amd64.pyd +0 -0
  91. ck/pgm_compiler/support/circuit_table/_circuit_table_cy.pyx +332 -0
  92. ck/pgm_compiler/support/circuit_table/_circuit_table_py.py +304 -0
  93. ck/pgm_compiler/support/clusters.py +568 -0
  94. ck/pgm_compiler/support/factor_tables.py +406 -0
  95. ck/pgm_compiler/support/join_tree.py +332 -0
  96. ck/pgm_compiler/support/named_compiler_maker.py +43 -0
  97. ck/pgm_compiler/variable_elimination.py +91 -0
  98. ck/probability/__init__.py +0 -0
  99. ck/probability/empirical_probability_space.py +50 -0
  100. ck/probability/pgm_probability_space.py +32 -0
  101. ck/probability/probability_space.py +622 -0
  102. ck/program/__init__.py +3 -0
  103. ck/program/program.py +137 -0
  104. ck/program/program_buffer.py +180 -0
  105. ck/program/raw_program.py +67 -0
  106. ck/sampling/__init__.py +0 -0
  107. ck/sampling/forward_sampler.py +211 -0
  108. ck/sampling/marginals_direct_sampler.py +113 -0
  109. ck/sampling/sampler.py +62 -0
  110. ck/sampling/sampler_support.py +232 -0
  111. ck/sampling/uniform_sampler.py +72 -0
  112. ck/sampling/wmc_direct_sampler.py +171 -0
  113. ck/sampling/wmc_gibbs_sampler.py +153 -0
  114. ck/sampling/wmc_metropolis_sampler.py +165 -0
  115. ck/sampling/wmc_rejection_sampler.py +115 -0
  116. ck/utils/__init__.py +0 -0
  117. ck/utils/iter_extras.py +163 -0
  118. ck/utils/local_config.py +270 -0
  119. ck/utils/map_list.py +128 -0
  120. ck/utils/map_set.py +128 -0
  121. ck/utils/np_extras.py +51 -0
  122. ck/utils/random_extras.py +64 -0
  123. ck/utils/tmp_dir.py +94 -0
  124. ck_demos/__init__.py +0 -0
  125. ck_demos/ace/__init__.py +0 -0
  126. ck_demos/ace/copy_ace_to_ck.py +15 -0
  127. ck_demos/ace/demo_ace.py +49 -0
  128. ck_demos/all_demos.py +88 -0
  129. ck_demos/circuit/__init__.py +0 -0
  130. ck_demos/circuit/demo_circuit_dump.py +22 -0
  131. ck_demos/circuit/demo_derivatives.py +43 -0
  132. ck_demos/circuit_compiler/__init__.py +0 -0
  133. ck_demos/circuit_compiler/compare_circuit_compilers.py +32 -0
  134. ck_demos/circuit_compiler/show_llvm_program.py +26 -0
  135. ck_demos/pgm/__init__.py +0 -0
  136. ck_demos/pgm/demo_pgm_dump.py +18 -0
  137. ck_demos/pgm/demo_pgm_dump_stress.py +18 -0
  138. ck_demos/pgm/demo_pgm_string_rendering.py +15 -0
  139. ck_demos/pgm/show_examples.py +25 -0
  140. ck_demos/pgm_compiler/__init__.py +0 -0
  141. ck_demos/pgm_compiler/compare_pgm_compilers.py +63 -0
  142. ck_demos/pgm_compiler/demo_compiler_dump.py +60 -0
  143. ck_demos/pgm_compiler/demo_factor_elimination.py +47 -0
  144. ck_demos/pgm_compiler/demo_join_tree.py +25 -0
  145. ck_demos/pgm_compiler/demo_marginals_program.py +53 -0
  146. ck_demos/pgm_compiler/demo_mpe_program.py +55 -0
  147. ck_demos/pgm_compiler/demo_pgm_compiler.py +38 -0
  148. ck_demos/pgm_compiler/demo_recursive_conditioning.py +33 -0
  149. ck_demos/pgm_compiler/demo_variable_elimination.py +33 -0
  150. ck_demos/pgm_compiler/demo_wmc_program.py +29 -0
  151. ck_demos/pgm_compiler/time_fe_compiler.py +93 -0
  152. ck_demos/pgm_inference/__init__.py +0 -0
  153. ck_demos/pgm_inference/demo_inferencing_basic.py +188 -0
  154. ck_demos/pgm_inference/demo_inferencing_mpe_cancer.py +45 -0
  155. ck_demos/pgm_inference/demo_inferencing_wmc_and_mpe_sprinkler.py +154 -0
  156. ck_demos/pgm_inference/demo_inferencing_wmc_student.py +110 -0
  157. ck_demos/programs/__init__.py +0 -0
  158. ck_demos/programs/demo_program_buffer.py +24 -0
  159. ck_demos/programs/demo_program_multi.py +24 -0
  160. ck_demos/programs/demo_program_none.py +19 -0
  161. ck_demos/programs/demo_program_single.py +23 -0
  162. ck_demos/programs/demo_raw_program_interpreted.py +21 -0
  163. ck_demos/programs/demo_raw_program_llvm.py +21 -0
  164. ck_demos/sampling/__init__.py +0 -0
  165. ck_demos/sampling/check_sampler.py +71 -0
  166. ck_demos/sampling/demo_marginal_direct_sampler.py +40 -0
  167. ck_demos/sampling/demo_uniform_sampler.py +38 -0
  168. ck_demos/sampling/demo_wmc_direct_sampler.py +40 -0
  169. ck_demos/utils/__init__.py +0 -0
  170. ck_demos/utils/compare.py +120 -0
  171. ck_demos/utils/convert_network.py +45 -0
  172. ck_demos/utils/sample_model.py +216 -0
  173. ck_demos/utils/stop_watch.py +384 -0
  174. compiled_knowledge-4.0.0a20.dist-info/METADATA +50 -0
  175. compiled_knowledge-4.0.0a20.dist-info/RECORD +178 -0
  176. compiled_knowledge-4.0.0a20.dist-info/WHEEL +5 -0
  177. compiled_knowledge-4.0.0a20.dist-info/licenses/LICENSE.txt +21 -0
  178. compiled_knowledge-4.0.0a20.dist-info/top_level.txt +2 -0
@@ -0,0 +1,231 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABC, abstractmethod
4
+ from dataclasses import dataclass
5
+ from typing import Iterable, Dict, Optional, List, Sequence, Tuple, Set
6
+
7
+ from ck.circuit import Circuit, CircuitNode
8
+ from ck.pgm import PGM
9
+ from ck.pgm_circuit import PGMCircuit
10
+ from ck.pgm_compiler.support import clusters
11
+ from ck.pgm_compiler.support.circuit_table import CircuitTable
12
+ from ck.pgm_compiler.support.clusters import ClusterAlgorithm
13
+ from ck.pgm_compiler.support.factor_tables import make_factor_tables, FactorTables
14
+ from ck.utils.iter_extras import combos
15
+
16
+ # Standard cluster algorithms.
17
+ MIN_DEGREE: ClusterAlgorithm = clusters.min_degree
18
+ MIN_FILL: ClusterAlgorithm = clusters.min_fill
19
+ MIN_DEGREE_THEN_FILL: ClusterAlgorithm = clusters.min_degree_then_fill
20
+ MIN_FILL_THEN_DEGREE: ClusterAlgorithm = clusters.min_fill_then_degree
21
+ MIN_WEIGHTED_DEGREE: ClusterAlgorithm = clusters.min_weighted_degree
22
+ MIN_WEIGHTED_FILL: ClusterAlgorithm = clusters.min_weighted_fill
23
+ MIN_TRADITIONAL_WEIGHTED_FILL: ClusterAlgorithm = clusters.min_traditional_weighted_fill
24
+
25
+
26
+ def compile_pgm(
27
+ pgm: PGM,
28
+ const_parameters: bool = True,
29
+ *,
30
+ algorithm: ClusterAlgorithm = MIN_FILL_THEN_DEGREE,
31
+ pre_prune_factor_tables: bool = False,
32
+ ) -> PGMCircuit:
33
+ """
34
+ Compile the PGM to an arithmetic circuit, using recursive conditioning.
35
+
36
+ Conforms to the `PGMCompiler` protocol.
37
+
38
+ Args:
39
+ pgm: The PGM to compile.
40
+ const_parameters: If true, the potential function parameters will be circuit
41
+ constants, otherwise they will be circuit variables.
42
+ algorithm: algorithm to get an elimination order.
43
+ pre_prune_factor_tables: if true, then heuristics will be used to remove any provably zero row.
44
+
45
+ Returns:
46
+ a PGMCircuit object.
47
+ """
48
+ elimination_order: Sequence[int] = algorithm(pgm).eliminated
49
+ factor_tables: FactorTables = make_factor_tables(
50
+ pgm=pgm,
51
+ const_parameters=const_parameters,
52
+ multiply_indicators=True,
53
+ pre_prune_factor_tables=pre_prune_factor_tables,
54
+ )
55
+
56
+ if pgm.number_of_factors == 0:
57
+ # Deal with special case: no factors
58
+ top: CircuitNode = factor_tables.circuit.const(1)
59
+ else:
60
+ dtree: _DTree = _make_dtree(elimination_order, factor_tables)
61
+ states: List[Sequence[int]] = [tuple(range(len(rv))) for rv in pgm.rvs]
62
+ top: CircuitNode = dtree.make_circuit(states, factor_tables.circuit)
63
+
64
+ top.circuit.remove_unreachable_op_nodes(top)
65
+
66
+ return PGMCircuit(
67
+ rvs=tuple(pgm.rvs),
68
+ conditions=(),
69
+ circuit_top=top,
70
+ number_of_indicators=factor_tables.number_of_indicators,
71
+ number_of_parameters=factor_tables.number_of_parameters,
72
+ slot_map=factor_tables.slot_map,
73
+ parameter_values=factor_tables.parameter_values,
74
+ )
75
+
76
+
77
+ def _make_dtree(elimination_order: Sequence[int], factor_tables: FactorTables) -> _DTree:
78
+ if len(factor_tables.tables) == 0:
79
+ return _DTreeLeaf(CircuitTable(factor_tables.circuit, (), ()))
80
+
81
+ # Populate `trees` with all the leaves
82
+ trees: List[_DTree] = [_DTreeLeaf(table) for table in factor_tables.tables]
83
+
84
+ # join trees by elimination random variable
85
+ for rv_index in elimination_order:
86
+ next_trees: List[_DTree] = []
87
+ to_join: List[_DTree] = []
88
+ for tree in trees:
89
+ if rv_index in tree.vars:
90
+ to_join.append(tree)
91
+ else:
92
+ next_trees.append(tree)
93
+ if len(to_join) >= 2:
94
+ while len(to_join) > 1:
95
+ # join the two shallowest trees
96
+ to_join.sort(key=lambda t: -t.depth())
97
+ x = to_join.pop()
98
+ y = to_join.pop()
99
+ to_join.append(_DTreeInterior(x, y))
100
+ next_trees.append(to_join[0])
101
+ trees = next_trees
102
+
103
+ # Make sure there is only one tree
104
+ while len(trees) > 1:
105
+ x = trees.pop(0)
106
+ y = trees.pop(0)
107
+ trees.append(_DTreeInterior(x, y))
108
+
109
+ root = trees[0]
110
+ root.update_cutset()
111
+ return root
112
+
113
+
114
+ class _DTree(ABC):
115
+ """
116
+ A node in a binary decomposition tree.
117
+
118
+ A node is either a _DTreeLeaf, holding a single CircuitTable,
119
+ or is a _DTreeInterior, which has exactly two children.
120
+ """
121
+
122
+ def __init__(self, vars_idxs: Set[int]):
123
+ self.vars: Set[int] = vars_idxs
124
+ self.cutset: Sequence[int] = ()
125
+ self.context: Sequence[int] = ()
126
+
127
+ @abstractmethod
128
+ def update_cutset(self, acutset: Iterable[int] = ()) -> None:
129
+ """
130
+ After the d-tree is defined, call `update_cutset` on the root
131
+ to ensure all fields are properly set.
132
+ """
133
+ ...
134
+
135
+ @abstractmethod
136
+ def make_circuit(self, states: List[Sequence[int]], circuit: Circuit) -> CircuitNode:
137
+ """
138
+ After the d-tree is defined and cutsets are updated,
139
+ construct a circuit using recursive conditioning.
140
+ """
141
+ ...
142
+
143
+ @abstractmethod
144
+ def depth(self) -> int:
145
+ """
146
+ Tree depth.
147
+ """
148
+
149
+
150
+ @dataclass
151
+ class _DTreeLeaf(_DTree):
152
+
153
+ def __init__(self, table: CircuitTable):
154
+ super().__init__(set(table.rv_idxs))
155
+ self.table: CircuitTable = table
156
+
157
+ def update_cutset(self, acutset: Iterable[int] = ()) -> None:
158
+ pass
159
+
160
+ def make_circuit(self, states: List[Sequence[int]], circuit: Circuit) -> CircuitNode:
161
+ table = self.table
162
+
163
+ key_states: List[Sequence[int]] = [
164
+ states[rv_idx]
165
+ for rv_idx in table.rv_idxs
166
+ ]
167
+ to_sum: List[CircuitNode] = list(
168
+ filter(
169
+ (lambda n: n is not None),
170
+ (table.get(key) for key in combos(key_states))
171
+ )
172
+ )
173
+ return circuit.optimised_add(to_sum)
174
+
175
+ def depth(self) -> int:
176
+ return 1
177
+
178
+
179
+ @dataclass
180
+ class _DTreeInterior(_DTree):
181
+
182
+ def __init__(self, x: _DTree, y: _DTree):
183
+ super().__init__(x.vars.union(y.vars))
184
+ self.x: _DTree = x
185
+ self.y: _DTree = y
186
+ self.cache: Dict[Tuple[int, ...], CircuitNode] = {}
187
+
188
+ def update_cutset(self, acutset: Iterable[int] = ()) -> None:
189
+ cutset: Set[int] = self.x.vars.intersection(self.y.vars).difference(acutset)
190
+ self.cutset = tuple(cutset)
191
+ self.context = tuple(self.vars.intersection(acutset))
192
+
193
+ next_acutset = cutset.union(acutset)
194
+ self.x.update_cutset(next_acutset)
195
+ self.y.update_cutset(next_acutset)
196
+
197
+ def make_circuit(self, states: List[Sequence[int]], circuit: Circuit) -> CircuitNode:
198
+
199
+ assert all(len(states[rv_idx]) == 1 for rv_idx in self.context), 'consistency check'
200
+ context_key: Tuple[int, ...] = tuple(
201
+ states[rv_idx][0]
202
+ for rv_idx in self.context
203
+ )
204
+
205
+ cache: Optional[CircuitNode] = self.cache.get(context_key)
206
+ if cache is not None:
207
+ return cache
208
+
209
+ cutset = self.cutset
210
+ key_states: List[Sequence[int]] = [
211
+ states[rv_idx]
212
+ for rv_idx in cutset
213
+ ]
214
+ to_sum: List[CircuitNode] = []
215
+ for key in combos(key_states):
216
+ # Update the evidence with the keys
217
+ next_states = states.copy()
218
+ for s, i in zip(key, cutset):
219
+ next_states[i] = (s,)
220
+
221
+ # Recursively call
222
+ x_node = self.x.make_circuit(next_states, circuit)
223
+ y_node = self.y.make_circuit(next_states, circuit)
224
+ to_sum.append(circuit.optimised_mul((x_node, y_node)))
225
+
226
+ result = circuit.optimised_add(to_sum)
227
+ self.cache[context_key] = result
228
+ return result
229
+
230
+ def depth(self) -> int:
231
+ return max(self.x.depth(), self.y.depth())
File without changes
@@ -0,0 +1,17 @@
1
+ # There are two implementations of the `circuit_table` module are provided
2
+ # for developer R&D purposes. One is pure Python and the other is Cython.
3
+ # Which implementation is used can be selected here.
4
+ #
5
+ # A similar selection can be made for the `circuit` module.
6
+ # Note that if the Cython implementation is chosen for `circuit_table` then
7
+ # the Cython implementation must be chosen for `circuit`.
8
+
9
+ # from ._circuit_table_py import (
10
+ from ._circuit_table_cy import (
11
+ CircuitTable,
12
+ TableInstance,
13
+ sum_out,
14
+ sum_out_all,
15
+ project,
16
+ product,
17
+ )