creating-intelligence 0.1.0a7__py3-none-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.
Binary file
@@ -0,0 +1,170 @@
1
+ """
2
+ Copyright (c) 2026 Peter Overmann
3
+
4
+ SPDX-License-Identifier: MIT
5
+
6
+ This file is part of the "Creating Intelligence" project. It is licensed
7
+ under the MIT License. You may obtain a copy of the License in the LICENSE
8
+ file in the root directory of this repository.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
13
+ """
14
+
15
+ import ctypes
16
+ import os
17
+ import sys
18
+ import importlib.machinery
19
+ from pathlib import Path
20
+
21
+ def _candidate_paths():
22
+ """Yield possible locations of the compiled C library, most preferred first."""
23
+ # 1. Explicit override, e.g. MEMORY_LIB_PATH=/path/to/libmemory.so
24
+ override = os.environ.get("MEMORY_LIB_PATH")
25
+ if override:
26
+ yield Path(override)
27
+
28
+ # 2. Extension built by pip/setuptools, under any suffix this interpreter
29
+ # accepts (.cpython-312-x86_64-linux-gnu.so, .abi3.so, .cp312-win_amd64.pyd, ...)
30
+ pkg_dir = Path(__file__).resolve().parent
31
+ for suffix in importlib.machinery.EXTENSION_SUFFIXES:
32
+ yield pkg_dir / f"libmemory{suffix}"
33
+
34
+ # 3. Local development build from the C Makefile (<repo>/c/lib/)
35
+ if sys.platform == "darwin":
36
+ lib_name = "libmemory.dylib"
37
+ elif sys.platform == "win32":
38
+ lib_name = "libmemory.dll"
39
+ else:
40
+ lib_name = "libmemory.so"
41
+ yield pkg_dir.parent.parent / "c" / "lib" / lib_name
42
+
43
+
44
+ def _load_library():
45
+ tried = []
46
+ for path in _candidate_paths():
47
+ if not path.is_file():
48
+ tried.append(f" {path} (not found)")
49
+ continue
50
+ try:
51
+ return ctypes.CDLL(str(path))
52
+ except OSError as e:
53
+ tried.append(f" {path} ({e})")
54
+ raise OSError("Could not load the C memory library. Tried:\n" + "\n".join(tried))
55
+
56
+
57
+ lib = _load_library()
58
+
59
+ # Define the C 'Set' struct in Python.
60
+ class CSet(ctypes.Structure):
61
+ _fields_ = [
62
+ ("a", ctypes.POINTER(ctypes.c_int)),
63
+ ("n", ctypes.c_int),
64
+ ("p", ctypes.c_int)
65
+ ]
66
+
67
+ # Define FFI signatures mapped from the C implementations.
68
+ lib.Memory_new.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
69
+ lib.Memory_new.restype = ctypes.c_void_p
70
+
71
+ lib.Memory_set_threshold.argtypes = [ctypes.c_void_p, ctypes.c_int]
72
+ lib.Memory_set_threshold.restype = None
73
+
74
+ lib.Memory_get_threshold.argtypes = [ctypes.c_void_p]
75
+ lib.Memory_get_threshold.restype = ctypes.c_int
76
+
77
+ lib.Memory_set_fraction.argtypes = [ctypes.c_void_p, ctypes.c_double]
78
+ lib.Memory_set_fraction.restype = None
79
+
80
+ lib.Memory_get_fraction.argtypes = [ctypes.c_void_p]
81
+ lib.Memory_get_fraction.restype = ctypes.c_double
82
+
83
+ lib.Memory_count.argtypes = [ctypes.c_void_p]
84
+ lib.Memory_count.restype = ctypes.c_int64
85
+
86
+ lib.Memory_free.argtypes = [ctypes.c_void_p]
87
+ lib.Memory_free.restype = None
88
+
89
+ lib.Memory_write.argtypes = [ctypes.c_void_p, ctypes.POINTER(CSet), ctypes.POINTER(CSet)]
90
+ lib.Memory_write.restype = None
91
+
92
+ lib.Memory_read.argtypes = [ctypes.c_void_p, ctypes.POINTER(CSet), ctypes.POINTER(CSet)]
93
+ lib.Memory_read.restype = ctypes.POINTER(CSet)
94
+
95
+ def Memory(config: dict) -> dict:
96
+ NA, PA = config["A_parameters"]
97
+ NB, PB = config["B_parameters"]
98
+
99
+ # Construct the underlying C memory object.
100
+ M = lib.Memory_new(NA, PA, NB, PB)
101
+
102
+ # Push user-defined threshold scaling if provided.
103
+ if config.get("threshold") is not None:
104
+ scaled_threshold = round(config.get("threshold") * PA)
105
+ lib.Memory_set_threshold(M, scaled_threshold)
106
+
107
+ # Push optional relative threshold (fraction of the query population).
108
+ if config.get("fraction") is not None:
109
+ lib.Memory_set_fraction(M, float(config.get("fraction")))
110
+
111
+ # Retrieve final absolute threshold from C backend.
112
+ T = lib.Memory_get_threshold(M)
113
+
114
+ # Retrieve fraction parameter from C backend
115
+ fraction = lib.Memory_get_fraction(M)
116
+
117
+ def _make_cset(data_list, dimension):
118
+ """Creates a CSet and holds the underlying array reference to prevent garbage collection."""
119
+ length = len(data_list)
120
+ shifted_data = [x - 1 for x in data_list]
121
+ arr = (ctypes.c_int * length)(*shifted_data)
122
+ cset = CSet(a=ctypes.cast(arr, ctypes.POINTER(ctypes.c_int)), n=dimension, p=length)
123
+ return cset, arr
124
+
125
+ def store(A, B=None):
126
+ # Store auto-association A -> A in memory if B is omitted.
127
+ if B is None:
128
+ B = A
129
+
130
+ if len(A) > 0 and len(B) > 0:
131
+ cset_A, _ref_A = _make_cset(A, NA)
132
+ cset_B, _ref_B = _make_cset(B, NB)
133
+ lib.Memory_write(M, ctypes.byref(cset_A), ctypes.byref(cset_B))
134
+
135
+ def retrieve(A):
136
+ if len(A) == 0:
137
+ return []
138
+
139
+ cset_A, _ref_A = _make_cset(A, NA)
140
+
141
+ # Allocate space for retrieved values up to max dimension NB.
142
+ Y_arr = (ctypes.c_int * NB)()
143
+ cset_Y = CSet(a=ctypes.cast(Y_arr, ctypes.POINTER(ctypes.c_int)), n=NB, p=0)
144
+
145
+ # Memory_read returns a pointer to the populated result Set.
146
+ res_ptr = lib.Memory_read(M, ctypes.byref(cset_A), ctypes.byref(cset_Y))
147
+
148
+ if not res_ptr:
149
+ return []
150
+
151
+ res_set = res_ptr.contents
152
+ return [res_set.a[i] + 1 for i in range(res_set.p)]
153
+
154
+ def memorycount():
155
+ return lib.Memory_count(M)
156
+
157
+ def clear():
158
+ lib.Memory_free(M)
159
+
160
+ return {
161
+ "A_parameters": (NA, PA),
162
+ "B_parameters": (NB, PB),
163
+ "T": T,
164
+ "fraction": fraction,
165
+ "store": store,
166
+ "retrieve": retrieve,
167
+ "clear": clear,
168
+ "memorycount": memorycount,
169
+ "backend": "c_ffi"
170
+ }
@@ -0,0 +1,143 @@
1
+ """
2
+ Copyright (c) 2026 Peter Overmann
3
+
4
+ SPDX-License-Identifier: MIT
5
+
6
+ This file is part of the "Creating Intelligence" project. It is licensed
7
+ under the MIT License. You may obtain a copy of the License in the LICENSE
8
+ file in the root directory of this repository.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
13
+ """
14
+
15
+ import math
16
+ import numpy as np
17
+ from itertools import combinations
18
+
19
+ def Memory(config: dict) -> dict:
20
+ # Extract hyperparameters
21
+ NA, PA = config["A_parameters"]
22
+ NB, PB = config["B_parameters"]
23
+
24
+ # Memory capacity, needed for default threshold calculation
25
+ if NA == NB and PA == PB:
26
+ capacity = round((math.log(2.0) * NA * (NA - 1) * (NA - 2)) /
27
+ (PA * (PA - 1) * (PA - 2)))
28
+ else:
29
+ capacity = round((math.log(2.0) * NA * (NA - 1) * NB) /
30
+ (PA * (PA - 1) * PB))
31
+
32
+ # Default pattern matching threshold
33
+ T = 1
34
+ while (T < PA and
35
+ (capacity**2 * math.comb(PA, T) *
36
+ math.comb(NA - PA, PA - T) /
37
+ math.comb(NA, PA)) >= 1):
38
+ T += 1
39
+
40
+ # User-defined (scaled) threshold via get()
41
+ if config.get("threshold") is not None:
42
+ T = round(config["threshold"] * PA)
43
+
44
+ T = max(2, T)
45
+
46
+ # Optional relative threshold: fraction of the query population that must
47
+ # match (1.0 = all input bits). Absent or 0 keeps the fixed threshold T.
48
+ fraction = config.get("fraction") or 0.0
49
+
50
+ # Initialize enclosed memory dictionary and zero array
51
+ mem = {}
52
+ zero = np.zeros(NB + 1, dtype=np.int8)
53
+
54
+ def store(A, B=None):
55
+ if B is None:
56
+ B = A
57
+
58
+ # Empty patterns store nothing
59
+ if not A or not B:
60
+ return
61
+
62
+ v = zero.copy()
63
+ v[B] = 1
64
+
65
+ for pair in combinations(A, 2):
66
+ key = tuple(sorted(pair))
67
+
68
+ if key not in mem:
69
+ mem[key] = v.copy()
70
+ else:
71
+ mem[key] = np.bitwise_or(mem[key], v)
72
+
73
+ def retrieve(A):
74
+
75
+ X = A
76
+
77
+ # Per-query threshold, at least the fixed threshold T
78
+ Tq = max(T, math.ceil(fraction * len(X) - 1e-9))
79
+
80
+ while True:
81
+ P = len(X)
82
+ if P < Tq:
83
+ return []
84
+
85
+ Ri = np.zeros((P, NB + 1), dtype=np.int32)
86
+
87
+ for i, j in combinations(range(P), 2):
88
+ key = tuple(sorted([X[i], X[j]]))
89
+ v = mem.get(key, zero)
90
+ Ri[i] += v
91
+ Ri[j] += v
92
+
93
+ R = np.sum(Ri, axis=0) // 2
94
+
95
+ R_valid = R[1:]
96
+ sorted_R = np.sort(R_valid)
97
+
98
+ t_val = sorted_R[-PB] if PB <= len(sorted_R) else sorted_R[0]
99
+ t = max(1, t_val)
100
+
101
+ if t < (Tq * (Tq - 1)) / 2:
102
+ return []
103
+
104
+ Y = [i for i in range(1, NB + 1) if R[i] >= t]
105
+ w = np.sum(Ri[:, Y], axis=1)
106
+
107
+ ws = np.sort(w)
108
+ h = P
109
+
110
+ while h > 0 and ws[-h] < len(Y) * (h - 1):
111
+ h -= 1
112
+
113
+ if h < Tq:
114
+ return []
115
+
116
+ cutoff = ws[-h]
117
+ new_X = [X[i] for i in range(P) if w[i] >= cutoff]
118
+
119
+ if h == Tq and h < len(new_X):
120
+ return []
121
+
122
+ if len(new_X) == P:
123
+ return Y
124
+
125
+ X = new_X
126
+
127
+ def memorycount():
128
+ return sum(np.sum(v) for v in mem.values())
129
+
130
+ def clear():
131
+ mem.clear()
132
+
133
+ return {
134
+ "A_parameters": (NA, PA),
135
+ "B_parameters": (NB, PB),
136
+ "T": T,
137
+ "fraction": fraction,
138
+ "store": store,
139
+ "retrieve": retrieve,
140
+ "clear": clear,
141
+ "memorycount": memorycount,
142
+ "backend": "python"
143
+ }
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.4
2
+ Name: creating-intelligence
3
+ Version: 0.1.0a7
4
+ Summary: A computational foundation for AGI, based on hyperdimensional sparse data and framed in set theory.
5
+ Author-email: Peter Overmann <mail@creatingintelligence.org>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://creatingintelligence.org
8
+ Project-URL: Documentation, https://creatingintelligence.org/docs
9
+ Project-URL: Repository, https://github.com/PeterOvermann/CreatingIntelligence
10
+ Keywords: artificial intelligence,computational theory of mind,hyperdimensional computing,sparse distributed representations,topological associative memory,subset matching algorithm,spiking neural networks,neuromorphic computing,theoretical neuroscience
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: C
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: matplotlib>=3.5.0
17
+ Requires-Dist: networkx>=2.8.0
18
+ Requires-Dist: numpy>=1.21.0
19
+ Requires-Dist: scipy>=1.8.0
20
+ Provides-Extra: viz
21
+ Requires-Dist: pydot>=1.4.2; extra == "viz"
22
+ Provides-Extra: all
23
+ Requires-Dist: creating-intelligence[viz]; extra == "all"
24
+
25
+ # Creating Intelligence
26
+
27
+ A computational foundation for AGI, based on hyperdimensional sparse data and framed in set theory.
28
+
29
+ The mind performs computations on sparse binary data using Sparse Distributed Representations (SDRs) for perceptual information and Sparse Holographic Representations (SHRs) for symbols. The centerpiece of this project is Topological Associative Memory — a newly discovered associative memory for sparse data, serving as the computational kernel that models the brain's core algorithm.
30
+
31
+ ### Links
32
+
33
+ * **Website:** https://creatingintelligence.org
34
+ * **Documentation:** https://creatingintelligence.org/docs
35
+ * **GitHub Repository:** https://github.com/PeterOvermann/CreatingIntelligence
36
+ * **Preprint:** [arXiv:2606.31819](https://arxiv.org/abs/2606.31819)
37
+
38
+ ### Installation
39
+
40
+ ```bash
41
+ pip install creating-intelligence
42
+ ```
43
+
44
+
45
+ #### Optional installations
46
+
47
+ | Extra | Installs | Purpose |
48
+ | ----- | -------- | ------- |
49
+ | `viz` | `pydot` | Left-to-right layouts when drawing circuit diagrams |
50
+ | `all` | every extra above | Everything optional in one step |
51
+
52
+ ```bash
53
+ pip install "creating-intelligence[viz]"
54
+ pip install "creating-intelligence[all]"
55
+ ```
@@ -0,0 +1,9 @@
1
+ creating_intelligence/__init__.py,sha256=-PCADoMkzPtoP2yBYxCKs2wUVL38IqLR8KIG0PtEpOE,1309
2
+ creating_intelligence/circuits.py,sha256=WgQvS0cWxwKfo-tHQzHttWqfTTglQ3Zv8czhJyu0G9c,59299
3
+ creating_intelligence/libmemory.pyd,sha256=VkPrWUIrrs2ieqYH8tuEHs9xhxKDVGZwUKYmpS5gmOk,19968
4
+ creating_intelligence/memory_c_ffi.py,sha256=PLPssHaIE2CFJ48XavCFe18be2QWKF45cAP-F_34bco,5910
5
+ creating_intelligence/memory_python.py,sha256=sWayWH0_h15XiJyb5OjNO94-hf9JqWYmoU_s4GfG2e0,4096
6
+ creating_intelligence-0.1.0a7.dist-info/METADATA,sha256=6BZCMsUIVWornAN0OLI7IbTyFYTOi7Y0XHFbWzTdcns,2404
7
+ creating_intelligence-0.1.0a7.dist-info/WHEEL,sha256=Zx98gwb_dQKckJK3HEOVKnxxD52EfU_PXDG_usMJ2ng,98
8
+ creating_intelligence-0.1.0a7.dist-info/top_level.txt,sha256=H5O7jHPu13cfTnlha8xX5GjLNEwY_9NAXlO401214ds,22
9
+ creating_intelligence-0.1.0a7.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-win_amd64
5
+
@@ -0,0 +1 @@
1
+ creating_intelligence