plumial 0.1.0__py3-none-any.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.
plumial/__init__.py ADDED
@@ -0,0 +1,83 @@
1
+ """
2
+ Plumial: A Python package for Collatz conjecture analysis and computation.
3
+
4
+ This package provides comprehensive tools and mathematical frameworks for analyzing
5
+ the Collatz conjecture through polynomial representations, d-polynomials,
6
+ and binary path analysis.
7
+
8
+ Key Features:
9
+ - Path Polynomials (P class): Represent Collatz sequence paths as mathematical polynomials
10
+ - D Objects (D class): Analyze d-polynomials d_p(g,h) = h^e - g^o fundamental to Collatz analysis
11
+ - Binary Operations: Comprehensive bit-level analysis and cycle navigation
12
+ - Symbolic Mathematics: Full SymPy integration for symbolic computation
13
+ - High Performance: LRU caching and optimized algorithms
14
+ - Type Safety: Comprehensive type hints and modern Python practices
15
+
16
+ Core Classes:
17
+ P: path object class for sequence analysis
18
+ - uv polynomial representations
19
+ - Mathematical relationships (x*d = a*k)
20
+ - Cycle navigation and analysis
21
+
22
+ D: d-polynomial class for algebraic analysis
23
+ - Symbolic form h^e - g^o
24
+ - GCD computation and factorization
25
+ - Polynomial evaluation and manipulation
26
+
27
+ Mathematical Background:
28
+ The Collatz conjecture studies sequences defined by:
29
+ - If n is even: n → n/2
30
+ - If n is odd: n → 3n+1
31
+
32
+ This package encodes these operations using polynomial representations where:
33
+ - h represents halving operations (typically h=2)
34
+ - g represents the 3x+1 operation (typically g=3)
35
+ - Path polynomials encode the sequence of operations
36
+ - Difference polynomials h^e - g^o capture cycle behavior
37
+
38
+ Examples:
39
+ >>> from plumial import P, D
40
+ >>>
41
+ >>> # Create a path polynomial for p-value 133
42
+ >>> p = P(133)
43
+ >>> print(f"Path bits: n={p.n()}, odd={p.o()}, even={p.e()}")
44
+ >>>
45
+ >>> # Get uv polynomial representation
46
+ >>> uv_poly = p.uv()
47
+ >>> print(f"uv polynomial: {uv_poly}")
48
+ >>>
49
+ >>> # Evaluate k polynomial using modern encoding approach
50
+ >>> collatz_p = p.encode(g=3, h=2)
51
+ >>> k_value = collatz_p.k()
52
+ >>> print(f"k(3,2) = {k_value}")
53
+ >>>
54
+ >>> # Create d-polynomial
55
+ >>> d = D(2, 5)
56
+ >>> print(f"Difference polynomial: {d.d()}") # h^5 - g^2
57
+ >>> collatz_d = d.encode(g=3, h=2)
58
+ >>> print(f"Evaluated at g=3, h=2: {collatz_d.d()}") # 23
59
+
60
+ Installation:
61
+ pip install plumial
62
+
63
+ Dependencies:
64
+ - sympy: Symbolic mathematics
65
+ - numpy: Numerical computing
66
+ - typing: Type hints (Python 3.8+)
67
+
68
+ Author: Jon Seymour <jon@wildducktheories.com>
69
+ License: MIT
70
+ Version: 0.1.0
71
+ """
72
+
73
+ __version__ = "0.1.0"
74
+ __author__ = "Jon Seymour"
75
+ __email__ = "jon@wildducktheories.com"
76
+
77
+ from .core import D, P
78
+
79
+ __all__ = [
80
+ "__version__",
81
+ "P",
82
+ "D",
83
+ ]
plumial/core/D.py ADDED
@@ -0,0 +1,563 @@
1
+ """
2
+ D objects for Collatz conjecture analysis.
3
+
4
+ This module implements the D class representing d-polynomials of the form
5
+ d_p(g,h) = h^e - g^o, which are fundamental to the algebraic analysis of Collatz sequences.
6
+
7
+ The d-polynomial d_p(g,h) = h^e - g^o encodes the core mathematical structure of
8
+ Collatz sequences, where:
9
+ - h represents the "halving" operation (typically h=2)
10
+ - g represents the "3x+1" operation (typically g=3)
11
+ - e is the number of even steps (halving operations)
12
+ - o is the number of odd steps (3x+1 operations)
13
+
14
+ Key Features:
15
+ - Symbolic representation and evaluation of d-polynomials
16
+ - GCD computation for polynomial analysis
17
+ - Factorization and algebraic manipulation
18
+ - LRU caching for performance optimization
19
+ - Support for both symbolic and numerical computations
20
+
21
+ Mathematical Background:
22
+ The d-polynomial d_p(g,h) = h^e - g^o represents the net effect of a Collatz
23
+ sequence segment.
24
+
25
+ Examples:
26
+ >>> from plumial.core.D import D
27
+ >>> from plumial.core.basis import B
28
+ >>> d = D(2, 5) # Create from o=2, e=5 (h^5 - g^2)
29
+ >>> print(d.o(), d.e(), d.n()) # 2, 5, 7
30
+ >>> poly = d.d() # Get symbolic form: h^5 - g^2
31
+ >>> collatz_d = d.encode(B.Collatz) # Encode for Collatz evaluation
32
+ >>> result = collatz_d.d() # Evaluate: 2^5 - 3^2 = 32 - 9 = 23
33
+ """
34
+
35
+ import math
36
+ from functools import lru_cache
37
+ from typing import Any, List, Optional, Union
38
+
39
+ import numpy as np
40
+ import sympy as sy
41
+
42
+ # Import type aliases for better type safety
43
+ from ..types import (
44
+ CacheInfo,
45
+ FactorResult,
46
+ GCDResult,
47
+ NumericOrSymbolic,
48
+ NumericType,
49
+ OptionalNumeric,
50
+ )
51
+ from ..utils.symbolic import g as g_sym
52
+ from ..utils.symbolic import h as h_sym
53
+ from .basis import Basis, B, resolve_basis
54
+
55
+
56
+ class _D:
57
+ """
58
+ Internal class representing a d-polynomial d_p(g,h) = h^e - g^o.
59
+
60
+ This class encapsulates the mathematical structure of a d-polynomial
61
+ used in Collatz sequence analysis. It provides methods for symbolic manipulation
62
+ and numerical evaluation.
63
+
64
+ The class maintains the fundamental parameters n, o, e for the polynomial form h^e - g^o.
65
+
66
+ This class should not be instantiated directly. Use the D() factory function instead.
67
+
68
+ Mathematical Structure:
69
+ - n: total number of bits (path length)
70
+ - o: number of odd bits (3x+1 operations)
71
+ - e: number of even bits (halving operations), where e = n - o
72
+ - The polynomial form: h^e - g^o
73
+
74
+ Attributes:
75
+ _o: Number of odd bits
76
+ _e: Number of even bits
77
+ _n: Total number of bits (computed as o + e)
78
+ _expr: Cached symbolic expression
79
+ """
80
+
81
+ def __init__(self, o: int, e: int, basis: Optional[Basis] = None) -> None:
82
+ """
83
+ Initialize d-polynomial from odd and even bit counts.
84
+
85
+ Args:
86
+ o: Number of odd bits (must be >= 0)
87
+ e: Number of even bits (must be >= 0)
88
+ basis: The mathematical basis for this encoding (default: symbolic basis)
89
+
90
+ Raises:
91
+ ValueError: If o < 0 or e < 0
92
+
93
+ Note:
94
+ This constructor is internal. Use D() factory function instead.
95
+ """
96
+ if o < 0:
97
+ raise ValueError(f"Number of odd bits must be >= 0, got o={o}")
98
+ if e < 0:
99
+ raise ValueError(f"Number of even bits must be >= 0, got e={e}")
100
+
101
+ self._o = o
102
+ self._e = e
103
+ self._n = o + e
104
+ self._basis = basis if basis is not None else B.Symbolic
105
+
106
+ # Cached symbolic expression
107
+ self._expr = None
108
+
109
+ def n(self) -> int:
110
+ """Return total number of bits (computed as o + e)."""
111
+ return self._n
112
+
113
+ def o(self) -> int:
114
+ """Return number of odd bits."""
115
+ return self._o
116
+
117
+ def e(self) -> int:
118
+ """Return number of even bits."""
119
+ return self._e
120
+
121
+
122
+ def basis(self) -> Basis:
123
+ """Return the basis of this encoding."""
124
+ return self._basis
125
+
126
+ def c(self) -> NumericOrSymbolic:
127
+ """
128
+ Calculate the ceiling of log_h(g).
129
+
130
+ This method computes ceil(log_h(g)) where log_h(g) is the logarithm
131
+ of g with base h. The result represents an important mathematical bound
132
+ related to the d-polynomial structure.
133
+
134
+ Returns:
135
+ Ceiling value, either symbolic or evaluated based on the basis
136
+
137
+ Mathematical Formula:
138
+ c = ceil(log_h(g)) = ceil(log(g) / log(h))
139
+
140
+ Examples:
141
+ >>> d = D(2, 5)
142
+ >>> d.c() # Symbolic form
143
+ >>> collatz_d = D(2, 5).encode(B.Collatz)
144
+ >>> collatz_d.c() # Numerical evaluation for g=3, h=2
145
+ """
146
+ # Get basis parameters
147
+ basis_dict = self._basis.dict()
148
+ g_val = basis_dict.get('g')
149
+ h_val = basis_dict.get('h')
150
+
151
+ if self._basis == B.Symbolic or g_val is None or h_val is None:
152
+ # Return symbolic form
153
+ return sy.ceiling(sy.log(g_sym, h_sym))
154
+ else:
155
+ # Return numerical evaluation
156
+ if g_val <= 0 or h_val <= 0 or h_val == 1:
157
+ raise ValueError(f"Invalid basis values for logarithm: g={g_val}, h={h_val}")
158
+
159
+ log_val = math.log(g_val) / math.log(h_val)
160
+ return math.ceil(log_val)
161
+
162
+ def r(self) -> NumericOrSymbolic:
163
+ """
164
+ Calculate the remainder: c() * o() - e().
165
+
166
+ This method computes the remainder value defined as the ceiling of log_h(g)
167
+ times the number of odd bits minus the number of even bits.
168
+
169
+ Returns:
170
+ Remainder value, either symbolic or evaluated based on the basis
171
+
172
+ Mathematical Formula:
173
+ r = c * o - e = ceil(log_h(g)) * o - e
174
+
175
+ Examples:
176
+ >>> d = D(2, 5)
177
+ >>> d.r() # Symbolic form
178
+ >>> collatz_d = D(2, 5).encode(B.Collatz)
179
+ >>> collatz_d.r() # Numerical evaluation: 2 * 2 - 5 = -1
180
+ """
181
+ c_val = self.c()
182
+
183
+ if self._basis == B.Symbolic:
184
+ # Return symbolic form
185
+ return c_val * self._o - self._e
186
+ else:
187
+ # Return numerical evaluation
188
+ return c_val * self._o - self._e
189
+
190
+ def encode(
191
+ self,
192
+ basis: Optional[Basis] = None,
193
+ g: OptionalNumeric = None,
194
+ h: OptionalNumeric = None
195
+ ) -> "_D":
196
+ """
197
+ Create a new D object encoded in a different basis.
198
+
199
+ This method enables the transitive encoding property where D objects
200
+ can be transformed between different coordinate systems while preserving
201
+ the underlying mathematical structure.
202
+
203
+ Args:
204
+ basis: Target basis for encoding
205
+ g: g parameter for custom basis (alternative to basis parameter)
206
+ h: h parameter for custom basis (alternative to basis parameter)
207
+
208
+ Returns:
209
+ New D object with same n,o values but different basis
210
+
211
+ Examples:
212
+ >>> d = D(2, 5) # Symbolic basis
213
+ >>> collatz_d = d.encode(B.Collatz) # Collatz basis
214
+ >>> custom_d = d.encode(g=5, h=2) # Custom basis
215
+ >>> back_d = collatz_d.encode() # Back to symbolic basis
216
+ >>> assert back_d == d # Round-trip equality
217
+ """
218
+ # Handle empty encode() - return to symbolic basis
219
+ if basis is None and g is None and h is None:
220
+ return D(self._o, self._e, basis=B.Symbolic)
221
+
222
+ # Resolve target basis
223
+ target_basis = resolve_basis(basis=basis, g=g, h=h)
224
+
225
+ # Return new D object with same o,e but different basis
226
+ return D(self._o, self._e, basis=target_basis)
227
+
228
+ def _as_expr(self) -> sy.Expr:
229
+ """
230
+ Return the symbolic expression h^e - g^o.
231
+
232
+ Private method for internal use. External code should use d() method
233
+ or SymPy integration methods (__add__, __mul__, etc.).
234
+
235
+ Returns:
236
+ SymPy expression representing the d-polynomial
237
+ """
238
+ if self._expr is None:
239
+ self._expr = h_sym**self._e - g_sym**self._o
240
+ return self._expr
241
+
242
+ def d(self) -> NumericOrSymbolic:
243
+ """
244
+ Evaluate the d-polynomial.
245
+
246
+ Returns:
247
+ Evaluated expression or symbolic form
248
+
249
+ Examples:
250
+ >>> d = D(2, 5)
251
+ >>> d.d() # Symbolic form
252
+ h**5 - g**2
253
+ >>> collatz_d = D(2, 5).encode(B.Collatz)
254
+ >>> collatz_d.d() # Uses basis automatically
255
+ 23
256
+ """
257
+ result = self._as_expr()
258
+
259
+ # Use basis if it's not symbolic
260
+ if self._basis != B.Symbolic:
261
+ basis_dict = self._basis.dict()
262
+ if basis_dict['g'] is not None:
263
+ result = result.subs(g_sym, basis_dict['g'])
264
+ if basis_dict['h'] is not None:
265
+ result = result.subs(h_sym, basis_dict['h'])
266
+
267
+ return result
268
+
269
+
270
+
271
+
272
+
273
+ def G(self) -> sy.Matrix:
274
+ """
275
+ Create column vector of g powers from g^(o-1) down to g^0.
276
+
277
+ This method generates a column vector containing powers of g in descending order,
278
+ used for matrix operations with polynomial coefficients. The vector has o elements
279
+ corresponding to the number of odd bits.
280
+
281
+ Returns:
282
+ SymPy Matrix column vector with g powers [g^(o-1), g^(o-2), ..., g^1, g^0]
283
+
284
+ Mathematical Structure:
285
+ For o odd bits, creates: [g^(o-1), g^(o-2), ..., g^1, g^0]^T
286
+
287
+ Examples:
288
+ >>> d = D(2, 5) # o=2, e=5
289
+ >>> g_vector = d.G()
290
+ >>> # Returns Matrix([[g], [1]]) for powers g^1, g^0
291
+
292
+ Matrix Operations:
293
+ >>> d = D(3, 4) # o=3, e=4
294
+ >>> G_vec = d.G()
295
+ >>> # Returns Matrix([[g**2], [g], [1]]) for use in polynomial operations
296
+ """
297
+ if self._o == 0:
298
+ # Special case: no odd bits means empty matrix
299
+ return sy.Matrix([])
300
+
301
+ # Create column vector with g powers from g^(o-1) down to g^0
302
+ powers = [g_sym**i for i in range(self._o - 1, -1, -1)]
303
+ return sy.Matrix(powers)
304
+
305
+ def __str__(self) -> str:
306
+ """String representation showing the polynomial."""
307
+ return str(self._as_expr())
308
+
309
+ def __repr__(self) -> str:
310
+ """String representation showing the polynomial."""
311
+ return repr(self._as_expr())
312
+
313
+ # SymPy integration methods
314
+ def _sympy_(self) -> sy.Expr:
315
+ """
316
+ SymPy conversion method - allows D objects to participate in SymPy expressions.
317
+
318
+ This method is called automatically by SymPy when a D object is used
319
+ in mathematical expressions, enabling seamless integration with symbolic math.
320
+
321
+ Returns:
322
+ SymPy expression representing the d-polynomial h^e - g^o
323
+
324
+ Examples:
325
+ >>> d = D(2, 5)
326
+ >>> expr = d + sy.Symbol('x') # Automatically calls _sympy_()
327
+ >>> result = sy.expand(expr * 2) # Works with all SymPy operations
328
+ """
329
+ return self._as_expr()
330
+
331
+ def __add__(self, other) -> sy.Expr:
332
+ """
333
+ Addition with other expressions.
334
+
335
+ Enables expressions like: D(2, 5) + x or D(1, 2) + D(3, 4)
336
+
337
+ Args:
338
+ other: Another D object, SymPy expression, or numeric value
339
+
340
+ Returns:
341
+ SymPy expression representing the sum
342
+ """
343
+ if isinstance(other, _D):
344
+ return self._as_expr() + other._as_expr()
345
+ return self._as_expr() + other
346
+
347
+ def __radd__(self, other) -> sy.Expr:
348
+ """Right addition - handles x + D(2, 5)."""
349
+ return other + self._as_expr()
350
+
351
+ def __sub__(self, other) -> sy.Expr:
352
+ """
353
+ Subtraction with other expressions.
354
+
355
+ Enables expressions like: D(2, 5) - x or D(3, 4) - D(1, 2)
356
+ """
357
+ if isinstance(other, _D):
358
+ return self._as_expr() - other._as_expr()
359
+ return self._as_expr() - other
360
+
361
+ def __rsub__(self, other) -> sy.Expr:
362
+ """Right subtraction - handles x - D(2, 5)."""
363
+ return other - self._as_expr()
364
+
365
+ def __mul__(self, other) -> sy.Expr:
366
+ """
367
+ Multiplication with other expressions.
368
+
369
+ Enables expressions like: D(2, 5) * x or D(1, 2) * D(3, 4)
370
+
371
+ Args:
372
+ other: Another D object, SymPy expression, or numeric value
373
+
374
+ Returns:
375
+ SymPy expression representing the product
376
+ """
377
+ if isinstance(other, _D):
378
+ return self._as_expr() * other._as_expr()
379
+ return self._as_expr() * other
380
+
381
+ def __rmul__(self, other) -> sy.Expr:
382
+ """Right multiplication - handles x * D(2, 5)."""
383
+ return other * self._as_expr()
384
+
385
+ def __truediv__(self, other) -> sy.Expr:
386
+ """
387
+ Division with other expressions.
388
+
389
+ Enables expressions like: D(2, 5) / x or D(3, 4) / D(1, 2)
390
+ """
391
+ if isinstance(other, _D):
392
+ return self._as_expr() / other._as_expr()
393
+ return self._as_expr() / other
394
+
395
+ def __rtruediv__(self, other) -> sy.Expr:
396
+ """Right division - handles x / D(2, 5)."""
397
+ return other / self._as_expr()
398
+
399
+ def __pow__(self, other) -> sy.Expr:
400
+ """
401
+ Exponentiation with other expressions.
402
+
403
+ Enables expressions like: D(2, 5) ** 2 or D(1, 2) ** x
404
+ """
405
+ return self._as_expr() ** other
406
+
407
+ def __rpow__(self, other) -> sy.Expr:
408
+ """Right exponentiation - handles x ** D(2, 5)."""
409
+ return other ** self._as_expr()
410
+
411
+ def __neg__(self) -> sy.Expr:
412
+ """Negation - handles -D(2, 5)."""
413
+ return -self._as_expr()
414
+
415
+ def __pos__(self) -> sy.Expr:
416
+ """Positive - handles +D(2, 5)."""
417
+ return +self._as_expr()
418
+
419
+ def __eq__(self, other) -> bool:
420
+ """Equality comparison based on n, o, and basis values."""
421
+ if isinstance(other, _D):
422
+ return self._n == other._n and self._o == other._o and self._basis == other._basis
423
+ return False
424
+
425
+ def __hash__(self) -> int:
426
+ """Hash based on n, o, and basis values."""
427
+ return hash((self._n, self._o, self._basis))
428
+
429
+
430
+ @lru_cache(maxsize=1000)
431
+ def _create_d_cached(o: int, e: int, basis_hash: int) -> _D:
432
+ """Create _D instance with LRU caching based on (o, e, basis) combination."""
433
+ # Reconstruct basis from hash - this is a workaround since we can't cache
434
+ # Basis objects directly. In practice, most usage will be with common bases.
435
+ if basis_hash == hash(B.Symbolic):
436
+ basis = B.Symbolic
437
+ elif basis_hash == hash(B.Collatz):
438
+ basis = B.Collatz
439
+ elif basis_hash == hash(B.Collatz_5_2):
440
+ basis = B.Collatz_5_2
441
+ elif basis_hash == hash(B.Collatz_7_2):
442
+ basis = B.Collatz_7_2
443
+ elif basis_hash == hash(B.Collatz_5_4):
444
+ basis = B.Collatz_5_4
445
+ elif basis_hash == hash(B.Collatz_7_4):
446
+ basis = B.Collatz_7_4
447
+ else:
448
+ # For custom bases, we skip caching to avoid hash collisions
449
+ raise ValueError(f"Cannot reconstruct basis from hash {basis_hash}")
450
+
451
+ return _D(o, e, basis=basis)
452
+
453
+
454
+ def D(o: Optional[int] = None,
455
+ e: Optional[int] = None,
456
+ n: Optional[int] = None,
457
+ basis: Optional[Basis] = None) -> _D:
458
+ """
459
+ Factory function for creating D instances from bit counts.
460
+
461
+ This is the main entry point for creating D objects. It supports multiple
462
+ calling patterns for flexibility.
463
+
464
+ Args:
465
+ o: Number of odd bits
466
+ e: Number of even bits
467
+ n: Total number of bits (alternative parameter)
468
+ basis: The mathematical basis for this encoding (default: symbolic basis)
469
+
470
+ Returns:
471
+ _D instance representing the d-polynomial h^e - g^o
472
+
473
+ Raises:
474
+ ValueError: If parameters are invalid or inconsistent
475
+
476
+ Usage Patterns:
477
+ - D(o, e): Direct polynomial specification h^e - g^o
478
+ - D(o=2, e=5): Named parameters
479
+ - D(o=2, n=7): Named, compute e = n - o
480
+ - D(e=5, n=7): Named, compute o = n - e
481
+
482
+ Examples:
483
+ >>> d1 = D(2, 5) # h^5 - g^2
484
+ >>> d2 = D(o=2, e=5, basis=B.Collatz) # With specific basis
485
+ >>> d3 = D(o=2, n=7) # Compute e = 7 - 2 = 5
486
+ >>> d4 = D(e=5, n=7) # Compute o = 7 - 5 = 2
487
+ """
488
+ # Set default basis
489
+ if basis is None:
490
+ basis = B.Symbolic
491
+
492
+ # Count how many parameters are provided
493
+ provided = sum(x is not None for x in [o, e, n])
494
+
495
+ if provided == 2:
496
+ if o is not None and e is not None:
497
+ # D(o, e) or D(o=2, e=5) - direct specification
498
+ pass # o and e are already set
499
+ elif o is not None and n is not None:
500
+ # D(o=2, n=7) - compute e = n - o
501
+ e = n - o
502
+ if e < 0:
503
+ raise ValueError(f"Invalid: n={n}, o={o} results in e={e} < 0")
504
+ elif e is not None and n is not None:
505
+ # D(e=5, n=7) - compute o = n - e
506
+ o = n - e
507
+ if o < 0:
508
+ raise ValueError(f"Invalid: n={n}, e={e} results in o={o} < 0")
509
+ else:
510
+ raise ValueError("Must specify exactly two of (o, e, n)")
511
+ elif provided == 3:
512
+ # All three provided - validate consistency
513
+ if n != o + e:
514
+ raise ValueError(
515
+ f"Inconsistent parameters: n={n} but o+e={o}+{e}={o+e}. "
516
+ f"Specify exactly two of (o, e, n)."
517
+ )
518
+ else:
519
+ raise ValueError("Must specify exactly two of (o, e, n)")
520
+
521
+ # Use cached version for predefined bases
522
+ try:
523
+ return _create_d_cached(o, e, hash(basis))
524
+ except ValueError:
525
+ # Custom basis - skip caching
526
+ return _D(o, e, basis=basis)
527
+
528
+
529
+ def clear_d_cache() -> None:
530
+ """
531
+ Clear the D instance cache.
532
+
533
+ This function clears all cached D instances, which can be useful for
534
+ memory management or when you want to ensure fresh instances are created.
535
+ After calling this function, subsequent calls to D() will create new
536
+ instances rather than returning cached ones.
537
+
538
+ Examples:
539
+ >>> d1 = D(2, 5)
540
+ >>> clear_d_cache()
541
+ >>> d2 = D(2, 5)
542
+ >>> assert d1 is not d2 # Different instances after cache clear
543
+ """
544
+ _create_d_cached.cache_clear()
545
+
546
+
547
+ def d_cache_info() -> CacheInfo:
548
+ """
549
+ Get cache statistics for D instances.
550
+
551
+ Returns cache hit/miss statistics and current cache size information
552
+ for the D instance cache. This is useful for performance monitoring
553
+ and cache effectiveness analysis.
554
+
555
+ Returns:
556
+ Cache information object with hits, misses, maxsize, and currsize
557
+
558
+ Examples:
559
+ >>> info = d_cache_info()
560
+ >>> print(f"D cache hits: {info.hits}, misses: {info.misses}")
561
+ >>> print(f"D cache size: {info.currsize}/{info.maxsize}")
562
+ """
563
+ return _create_d_cached.cache_info()