PhantomTrace — a mathematical framework where numbers exist in present or absent states with custom operations to include addition, subtraction, multiplication, division, and erasure.
Project description
PhantomTrace
A Python library implementing an experimental mathematical framework where numbers can exist in two states: present or absent. It defines five operations that interact with these states in consistent, rule-based ways.
Zero is redefined: 0 is not emptiness — it's one absence (1(0)). This means every operation has a defined result, including division by zero.
Read the paper: Absence Theory
Installation
pip install phantomtrace
Shorthand Notation (v0.3.0)
Use the n() shorthand to create numbers quickly:
from absence_calculator import n
n(5) # → 5 (present)
n(5)(0) # → 5(0) (absent) — closest to writing 5(0) directly
n(5)(1) # → 5 (stays present)
n(3)(5) # → 15 (multiplier — 3 × 5)
n(10)(0) # → 10(0) (absent)
# Build vectors naturally
vec = [n(10)(0), n(20), n(30)(0), n(40), n(50)(0)]
# → [10(0), 20, 30(0), 40, 50(0)]
You can also use the full form: AbsentNumber(value, absence_level).
Quick Start
from absence_calculator import n, add, subtract, multiply, divide, erase, format_result
# Create numbers — present (default) or absent
five = n(5) # 5 (present)
three_absent = n(3)(0) # 3(0) (absent)
# Addition — same state combines, mixed state is unresolved
result = add(n(5), n(3))
print(result) # 8
# Subtraction — equal values cancel to void
result = subtract(n(7), n(7))
print(result) # void
# Multiplication — states combine (like XOR)
result = multiply(n(5)(0), n(3))
print(result) # 15(0)
# Erasure — flips the state of the erased portion
result = erase(n(5), n(3))
print(result) # 2 + 3(0)
# Over-erasure — excess becomes erased debt
result = erase(n(7), n(10))
print(result) # 7(0) + erased 3
# Resolve erased excess by adding
resolved = add(result, n(3))
print(resolved) # 10(0)
# Division by zero — defined! (0 is one absence)
result = divide(n(10), n(1)(0))
print(result) # 10(0)
Using the Expression Solver
from absence_calculator import solve, format_result
# Parse and solve string expressions
print(format_result(solve("5 + 3"))) # 8
print(format_result(solve("5(0) + 3(0)"))) # 8(0)
print(format_result(solve("7 - 7"))) # void
print(format_result(solve("5(0) * 3"))) # 15(0)
print(format_result(solve("5 erased 3"))) # 2 + 3(0)
print(format_result(solve("7 erased 10"))) # 7(0) + erased 3 (over-erasure)
print(format_result(solve("5(0)(0)"))) # 5 (double absence = present)
# Parenthesized expressions (operations on unresolved inputs)
print(format_result(solve("(1 + 5(0)) erased 1"))) # 6(0)
# Zero operations
print(format_result(solve("0 + 0"))) # 2(0) (two absences)
print(format_result(solve("0 * 0"))) # 1 (absence of absence = presence)
print(format_result(solve("10 * 0"))) # 10(0)
print(format_result(solve("10 / 0"))) # 10(0)
Interactive Calculator
After installing, you can run the interactive calculator from the command line:
phantomtrace
Or as a Python module:
python -m absence_calculator
This gives you a calc >> prompt where you can type expressions and see results.
Core Concepts
Objects and States
An object is a number that has both a value and a state:
- Present (default): Written normally, e.g.
5. Present quantities reflect the presence of a given unit of interest. (e.g. if the unit is a cat, then 5 represents 5 cats that are there or in a present state) - Absent: Written with
(0), e.g.5(0)— think of it as5 * 0. Absent quantities reflect the absence of a given unit of interest. (e.g. if the unit is a phone, then 5(0) represents 5 phones that are not currently there but are still considered for computation)
Absence
- Zero:
0is not emptiness, it's one absence (1(0) = 1 * 0 = 0) - Absence of absence returns to present:
5(0)(0) = 5, and0(0) = 1
Operations
| Operation | Symbol | Rule |
|---|---|---|
| Addition | + |
Expands the amount of objects under consideration. Same state: magnitudes combine. Mixed: unresolved |
| Subtraction | - |
Contracts the amount of objects under consideration. (If the domain of consideration is constricted to nothing then the result is void. Void is not an object, nor the new zero, it simply means we are not considering anything on which to act.) Same state: magnitudes reduce. Mixed: unresolved |
| Multiplication | * |
Magnitudes multiply. States combine (presentpresent=present, absentpresent=absent, absent*absent=present) |
| Division | / |
Magnitudes divide. States combine same as multiplication. Division by 0 is defined! |
| Erasure | erased |
Same state required. Remainder keeps state, erased portion flips state. Over-erasure creates erased excess |
Over-Erasure (v0.2.0)
When you erase more than the total, the result carries an erased excess (erasure debt):
7 erased 10=7(0) + erased 3— all 7 flip state, 3 excess erasure persists- Adding resolves excess:
(7(0) + erased 3) + 3=10(0) - Erasing erased:
(erased 3) erased (erased 3)=erased 3(0)(absence of erased)
Compound Expressions (v0.2.0)
Operations can now accept unresolved expressions as inputs:
(1 + 5(0)) erased 1=6(0)— erases the present part, combining with the absent part
Result Types
- AbsentNumber: A number with a state (present or absent)
- Void: Complete cancellation — not zero, but the absence of any quantity under consideration
- ErasureResult: Two parts — remainder (keeps state) and erased portion (flipped state)
- ErasedExcess: Excess erasure debt that persists until resolved
- Unresolved: An expression that cannot be simplified (e.g., adding present + absent)
Toggle Module
The toggle module flips states of elements in vectors and matrices using pattern-based index selection. Three functions:
toggle.where(pattern, range, data)— flip elements at pattern-computed indicestoggle.exclude(pattern, range, data)— flip everything except pattern-computed indicestoggle.all(data)— flip every element
Vectors — Present
from absence_calculator import toggle, n
# Present vector — all elements start as present
vec = [10, 20, 30, 40, 50]
toggle.where(lambda x: x * 2, (0, 2), vec)
# → [10(0), 20, 30(0), 40, 50(0)] targets flipped to absent
toggle.exclude(lambda x: x * 2, (0, 2), vec)
# → [10, 20(0), 30, 40(0), 50] non-targets flipped to absent
toggle.all(vec)
# → [10(0), 20(0), 30(0), 40(0), 50(0)] everything flipped to absent
Vectors — Absent
# Absent vector — all elements start as absent
vec = [n(10)(0), n(20)(0), n(30)(0), n(40)(0), n(50)(0)]
toggle.where(lambda x: x * 2, (0, 2), vec)
# → [10, 20(0), 30, 40(0), 50] targets flipped back to present
toggle.exclude(lambda x: x * 2, (0, 2), vec)
# → [10(0), 20, 30(0), 40, 50(0)] non-targets flipped back to present
toggle.all(vec)
# → [10, 20, 30, 40, 50] everything flipped back to present
Vectors — Mixed
# Mixed vector — some present, some absent
vec = [n(10), n(20)(0), n(30), n(40)(0), n(50)]
toggle.where(lambda x: x * 2, (0, 2), vec)
# → [10(0), 20(0), 30(0), 40(0), 50(0)] targets flip (present→absent, absent→present)
toggle.exclude(lambda x: x * 2, (0, 2), vec)
# → [10, 20, 30, 40, 50] non-targets flip
toggle.all(vec)
# → [10(0), 20, 30(0), 40, 50(0)] every element flips its state
String Patterns and Single Index
# String pattern — "x^2" computes target indices
toggle.where("x^2", (1, 4), [4, 7, 19, 22, 26])
# → [4, 7(0), 19, 22, 26(0)] indices 1 (1²) and 4 (2²) toggled
# Single index — use pattern "x" with range (i, i)
toggle.where("x", (2, 2), [10, 20, 30, 40, 50])
# → [10, 20, 30(0), 40, 50] only index 2 toggled
Matrices — Present
# Present matrix — toggle.all flips every element in every row
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
toggle.all(matrix)
# → [[0, 2(0), 3(0)],
# [4(0), 5(0), 6(0)],
# [7(0), 8(0), 9(0)]]
toggle.where("x", (0, 0), matrix)
# → [[0, 2, 3], index 0 toggled in each row
# [4(0), 5, 6],
# [7(0), 8, 9]]
toggle.exclude("x", (0, 0), matrix)
# → [[1, 2(0), 3(0)], everything except index 0 toggled
# [4, 5(0), 6(0)],
# [7, 8(0), 9(0)]]
Matrices — Absent
# Absent matrix
matrix = [[n(1)(0), n(2)(0)], [n(3)(0), n(4)(0)]]
toggle.all(matrix)
# → [[1, 2], everything flipped back to present
# [3, 4]]
Matrices — Mixed
# Mixed matrix — rows have different states
matrix = [[n(10)(0), n(20), n(30)(0)],
[n(40), n(50)(0), n(60)]]
toggle.where("x", (1, 1), matrix)
# → [[10(0), 20(0), 30(0)], index 1 toggled in each row
# [40, 50, 60]]
toggle.all(matrix)
# → [[10, 20(0), 30], every element flips
# [40(0), 50, 60(0)]]
Backward Compatibility
toggle.ys = toggle.where, toggle.nt = toggle.exclude — old names still work.
API Reference
Types
AbsentNumber(value, absence_level=0)— A number with a state.absence_level0 = present, 1 = absent. Callable:num(0)flips state,num(1)keeps state,num(k)multipliesn(value, absence_level=0)— Shorthand for creating AbsentNumbers:n(5)= present 5,n(5)(0)= absent 5Void/VOID— Represents complete cancellationErasureResult(remainder, erased)— Result of an erasure operationErasedExcess(value, absence_level=0)— Excess erasure debt from over-erasureUnresolved(left, op, right)— An expression that can't be simplified
Functions
add(x, y)— Add two values (supports compound inputs with excess resolution)subtract(x, y)— Subtract two AbsentNumbersmultiply(x, y)— Multiply two AbsentNumbersdivide(x, y)— Divide two AbsentNumberserase(x, y)— Erase y from x (supports over-erasure and compound inputs)solve(expr_string)— Parse and evaluate a string expression (supports parentheses)format_result(result)— Convert any result to a readable stringparse_number(s)— Parse a string like"5(0)"into an AbsentNumber
Toggle
toggle.where(pattern, range, data)— Toggle elements at pattern-computed indices (vectors or matrices)toggle.exclude(pattern, range, data)— Toggle all elements NOT at pattern-computed indices (vectors or matrices)toggle.all(data)— Flip the state of every element (vectors or matrices)toggle.ys/toggle.nt— Backward-compatible aliases forwhere/exclude
Constants
ALL_OPERATIONS— Dictionary describing all operations with rules and examples
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file phantomtrace-0.3.1.tar.gz.
File metadata
- Download URL: phantomtrace-0.3.1.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2d1aaae70316ae21fd6f949b80f9d9178a0743e8b9ad5c8ef169e965e88f39b
|
|
| MD5 |
75acb1b39866188b6ed0d4346e9ae429
|
|
| BLAKE2b-256 |
de56c885fcec018ab9662559fb07b3f66bbdd76a767e928f9ef0c4e1379c5e01
|
File details
Details for the file phantomtrace-0.3.1-py3-none-any.whl.
File metadata
- Download URL: phantomtrace-0.3.1-py3-none-any.whl
- Upload date:
- Size: 12.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54d291593630655b70f187eda505a10fa16061b6ab52652827c5fabf16daab8f
|
|
| MD5 |
16386123b6c6d72fc808cfc5a8acb720
|
|
| BLAKE2b-256 |
17d64412878022881fe8fa21a3e97dac611f1871e933a05844c2cad54edfc267
|