Strongly typed multiverse for .NET

QuantumSuperposition (.NET library)

Strongly-typed multiverse for .NET developers

Give your variables a whole superposition of possible values, run normal C# over all of them, then collapse to a single result when it’s decision time. It’s LINQ, but the universe is quietly judging your `SelectMany`.

QuantumSuperposition adds types like QuBit<T> and Eigenstates<T> to your .NET projects. They behave like LINQ-friendly collections that just happen to be quantum: you can map, filter and combine possibilities without committing to a single value.

It also pairs with PositronicVariables, a higher-level toolkit for temporal convergence, transactions and timeline-based variables built on top of QuBit<T>. Read the Positronic section below for examples and patterns.

Tiny, playful example

using QuantumSuperposition.QuantumSoup;

var guess = new QuBit<string>(new[] { "red", "green", "blue" });
var loudGuess = guess.Select(c => c.ToUpper());

// Only when we observe do we pick a single branch
Console.WriteLine($"The universe says: {loudGuess.SampleWeighted()}");

Two main personalities

  • Generic superposition engine - QuBit<T> and Eigenstates<T> with complex amplitudes, arithmetic, comparisons, LINQ-style operations, entanglement, sampling and non-observational operations.
  • Physics-flavoured quantum system - QuantumSystem, QuantumGate, QuantumAlgorithms for gate-based circuits, QFT, Grover search, gate queues and ASCII visualisation.

Getting Started

Installation

QuantumSuperposition is distributed via NuGet and targets modern .NET (8+). Add it to your project:

dotnet add package QuantumSuperposition

Namespaces & packages

For the generic superposition layer:

using QuantumSuperposition.Core;
using QuantumSuperposition.QuantumSoup;
using QuantumSuperposition.Operators;

For the physics-style quantum system and gates:

using System.Numerics;
using QuantumSuperposition.Systems;
using QuantumSuperposition.Utilities;

These map directly to the subsystems described below.

Generic Superpositions

QuBit<T> & Eigenstates<T>

At the heart of the library are strongly-typed superpositions of arbitrary T. A QuBit<T> is a weighted set of possible values; an Eigenstates<T> represents a spectrum of outcomes you can query and manipulate.

  • Complex amplitude weights with normalisation and probability derived from |amp|².
  • Non-destructive transforms: arithmetic, comparisons and projections across all states.
  • Sampling helpers like SampleWeighted() and MostProbable().
  • Collapse replay and seeded randomness for deterministic tests.

Basic example

using QuantumSuperposition.Core;
using QuantumSuperposition.QuantumSoup;

var qubit = new QuBit<int>(new[] { 1, 2, 3 });
var doubled = qubit.Select(x => x * 2);

Console.WriteLine($"Sample: {doubled.SampleWeighted()}");

Functional & LINQ operations

The superposition types are designed to feel like LINQ-friendly collections that just happen to be quantum. You can project, filter and flatten possibilities without forcing collapse.

  • Select, Where, SelectMany with lazy evaluation.
  • p_op for conditional logic without collapse.
  • p_func for functional transforms that keep amplitudes intact.
  • Commutative-optimised caching for pure operations to avoid recomputing symmetric cases.

Quantum-flavoured prime testing sketch

public static void PrintPrimesUpTo(int max)
{
    for (int i = 1; i <= max; i++)
    {
        var divisors = new QuBit<int>(Enumerable.Range(2, i > 2 ? i - 2 : 1));
        if ((i % divisors).EvaluateAll())
        {
            Console.WriteLine($"{i} is prime!");
        }
    }
}

(Sketch derived from the prime example in the docs - a normal loop over i, but each iteration uses a superposition of divisors rather than an inner loop.)

Complex numbers & interference

The library supports complex amplitudes and models interference via matrix multiplication in the physics layer. Relative phase lives in Complex values and shows up when gates are applied.

Complex superpositions

using System.Numerics;
using QuantumSuperposition.Core;
using QuantumSuperposition.QuantumSoup;

var q1 = new QuBit<Complex>(new Complex(1, 2));
var q2 = new QuBit<Complex>(new Complex(3, 4));

var sum = q1 + q2;
var product = q1 * q2;

Console.WriteLine($"Sum sample: {sum.SampleWeighted()}");
Console.WriteLine($"Product sample: {product.SampleWeighted()}");

PhysicsQubit helpers

For plain “physics” qubits in the computational basis {0,1}, use PhysicsQubit, which adds Bloch-sphere constructors and handy Zero/One shortcuts.

using QuantumSuperposition.QuantumSoup;
using System.Numerics;

var z = PhysicsQubit.Zero;
var o = PhysicsQubit.One;

// |ψ⟩ = (|0⟩ + |1⟩)/√2
var balanced = new PhysicsQubit(theta: Math.PI / 2, phi: 0);

Quantum System & Gates

QuantumSystem & multi-qubit state

QuantumSystem represents a global multi-qubit state, built from one or more QuBit<int> (or PhysicsQubit) instances via true tensor products. It manages amplitudes, partial observation, entanglement information and gate queues.

using QuantumSuperposition.Core;
using QuantumSuperposition.Systems;

var system = new QuantumSystem();

// build joint state from three 1-qubit basis states
system.SetFromTensorProduct(
    propagateCollapse: true,
    new QuBit<int>(system, new[] { 0 }),
    new QuBit<int>(system, new[] { 1 }),
    new QuBit<int>(system, new[] { 2 })
);

// peek at a subset of qubits
int[] observed = system.PartialObserve(new[] { 0, 2 });

Basis mapping can be customised for non-int domains by passing a Func<T,int> into SetFromTensorProduct, with built-in defaults for int, bool and enum.

Entanglement & collapse propagation

Entangled qubits share fate: observing one propagates collapse to the rest of the group. A dedicated entanglement manager tracks groups, labels and graph diagnostics.

using System.Numerics;
using QuantumSuperposition.Core;
using QuantumSuperposition.Systems;

var system = new QuantumSystem();
var qA = new QuBit<int>(system, new[] { 0 });
var qB = new QuBit<int>(system, new[] { 1 });

qA.WithWeights(new Dictionary<int, Complex> { {0, 1.0}, {1, 1.0} }, autoNormalise: true);
qB.WithWeights(new Dictionary<int, Complex> { {0, 1.0}, {1, 1.0} }, autoNormalise: true);

system.Entangle("BellPair_A", qA, qB);
system.SetFromTensorProduct(true, qA, qB);

// observe A; B collapses in solidarity
int valueA = qA.Observe();
bool isCollapsedB = qB.IsCollapsed;

The entanglement subsystem supports group versioning, tagging, diagnostics, locking/freezing and guardrails such as preventing cross-system links.

Gate model & circuit scheduling

QuantumGate wraps unitary matrices; QuantumGates provides a catalogue of common gates (Hadamard, Pauli X/Y/Z, Root NOT, T / T†, Swap, controlled variants, QFT factory and more).

Composing and inverting gates

using QuantumSuperposition.Core;
using QuantumSuperposition.Utilities;
using System.Numerics;

// composition
var rootNot = new QuantumGate(QuantumGates.RootNot);
var composed = rootNot.Then(rootNot); // RootNot ∘ RootNot ≈ X

// inversion
var tGate = new QuantumGate(QuantumGates.T);
Complex[,] tInv = QuantumGateTools.InvertGate(tGate.Matrix);

Circuit queue & visualisation

using QuantumSuperposition.Systems;

var system = new QuantumSystem();

system.ApplySingleQubitGate(0, QuantumGates.Hadamard, "H");
system.ApplyTwoQubitGate(0, 1, QuantumGates.CNOT.Matrix, "CNOT");

string before = system.VisualizeGateSchedule(totalQubits: 2);
Console.WriteLine(before);

system.ProcessGateQueue();

The gate queue supports both queued 1-2 qubit gates and immediate application of larger unitaries. A gate catalogue extension adds QFT gates, Toffoli/Fredkin, parametric rotations and generic controlled gates.

Quantum algorithms

The QuantumAlgorithms helper exposes higher-level algorithms assembled from the same gate primitives: Quantum Fourier Transform and Grover search are included.

Quantum Fourier Transform (QFT)

using QuantumSuperposition.Systems;
using QuantumSuperposition.Core;

var system = new QuantumSystem();
int[] qubits = { 0, 1, 2 };

QuantumAlgorithms.QuantumFourierTransform(system, qubits);

Grover search

var system = new QuantumSystem();
int[] searchQubits = { 0, 1 };

// mark |10⟩ with qubit 0 as MSB
Func<int[], bool> oracle = bits => bits[0] == 1 && bits[1] == 0;

QuantumAlgorithms.GroverSearch(system, searchQubits, oracle);

QuantumRegister & Canonical States

QuantumRegister

QuantumRegister is a light value abstraction over a slice of a QuantumSystem, letting you treat a subset of qubit indices as a register you can construct, partially observe and decode into ints.

using QuantumSuperposition.Core;
using QuantumSuperposition.Systems;

var system = new QuantumSystem();
var q0 = new QuBit<int>(system, new[] { 0 });
var q1 = new QuBit<int>(system, new[] { 1 });

var reg = new QuantumRegister(q0, q1);

// from plain integer value (basis state)
var encoded = QuantumRegister.FromInt(value: 3, bits: 2, system);

// collapse just this register
int[] bits = reg.Collapse();
int fullValue = reg.GetValue();

Gate * register sugar

For physics-style use, gates can be applied directly to registers via the * operator:

var ghz = QuantumRegister.GHZState(system, length: 3);
ghz = QuantumGates.Hadamard * ghz; // arity-checked application

Gate arity is inferred from the matrix size; 1-2 qubit gates are queued, higher arities applied directly.

Canonical multi-qubit states

Helpers on QuantumRegister construct common entangled states (Bell/EPR, W, GHZ) directly on a system, tagging entanglement groups along the way.

var system = new QuantumSystem();

var bell = QuantumRegister.EPRPair(system);      // (|00⟩ + |11⟩)/√2
var w3   = QuantumRegister.WState(system, 3);    // 3-qubit W state
var ghz4 = QuantumRegister.GHZState(system, 4);  // 4-qubit GHZ

Example Gallery

A few miniature examples to get a feel for the library. See the docs site and GitHub repository for more involved samples and tests mirroring real circuits and logic flows.

Logic gates & matrix manipulation

using System.Numerics;
using QuantumSuperposition.Core;
using QuantumSuperposition.Utilities;

// Root NOT then Root NOT equals X
var rootNot = new QuantumGate(QuantumGates.RootNot);
var xGate   = new QuantumGate(QuantumGates.PauliX);

var composed = rootNot.Then(rootNot);
bool same = QuantumGateTools.AreMatricesEqual(composed.Matrix, xGate.Matrix);

RX parametric gate

double theta = Math.PI / 4;
var rx = QuantumGates.RX(theta);

// build the expected matrix if you feel like checking the maths
Complex[,] expected =
{
    { Math.Cos(theta/2), -Complex.ImaginaryOne * Math.Sin(theta/2) },
    { -Complex.ImaginaryOne * Math.Sin(theta/2), Math.Cos(theta/2) }
};

Entangled partial collapse

var system = new QuantumSystem();

// two entangled bool-valued qubits
var qa = new QuBit<bool>(system, new[] { 0 });
var qb = new QuBit<bool>(system, new[] { 1 });

system.Entangle("Pair", qa, qb);
system.SetFromTensorProduct(true, qa, qb);

// peek just qubit 0 (index 0)
var outcome = system.PartialObserve(new[] { 0 });
bool observedA = outcome[0] != 0;

bool aCollapsed = qa.IsCollapsed;
bool bCollapsed = qb.IsCollapsed;

In the docs you’ll also find examples for visualising gate queues, comparing registers via AlmostEquals, and mapping non-primitive basis types into integer indices.

Worked Examples (Quantum Shenanigans)

A few miniature multiversal stunts adapted from the repo docs. They are intentionally short so you can copy, run, and then pretend you always understood them. Longer walkthroughs will arrive once the Improbability Field is recharged.

Prime Detection Without Loops (Mostly)

// For each i we build a superposition of potential divisors (2..i-1) and
// ask the universe if any branch divides i with zero remainder.
for (int i = 1; i <= 50; i++)
{
    var divisors = new QuBit<int>(Enumerable.Range(2, i > 2 ? i - 2 : 1));
    bool looksPrime = (i % divisors).EvaluateAll(); // all remainders non‑zero?
    if (looksPrime) Console.WriteLine($"{i} is prime (the universe shrugged)");
}

Extracting Factors via Eigenstates Filtering

Eigenstates<int> Factors(int n)
{
    // Map candidates to their remainder; equality constraint selects zeros
    var candidates = new Eigenstates<int>(Enumerable.Range(1, n), x => n % x);
    return candidates == 0; // states whose mapped value collapsed to 0
}
Console.WriteLine("Factors of 28: " + string.Join(", ", Factors(28).ToValues()));

Minimum Value by Existential Diplomacy

int MinValue(IEnumerable<int> xs)
{
    var e = new Eigenstates<int>(xs);
    // Keep any states <= all states, then pick the first survivor
    var filtered = e.Any() <= e.All();
    return filtered.ToValues().First();
}
Console.WriteLine(MinValue(new[]{42,7,19,13})); // 7 (smallest negotiator)

Canonical Entangled States

var system = new QuantumSystem();
var bell = QuantumRegister.EPRPair(system);   // (|00⟩ + |11⟩)/√2
var w3   = QuantumRegister.WState(system, 3); // W state (one excitation roaming politely)
var ghz4 = QuantumRegister.GHZState(system, 4); // (|0000⟩ + |1111⟩)/√2

Grover Sketch (Two Qubits, One Target)

var system = new QuantumSystem();
int[] searchQubits = {0,1};
Func<int[], bool> oracle = bits => bits[0] == 1 && bits[1] == 0; // mark |10⟩
QuantumAlgorithms.GroverSearch(system, searchQubits, oracle);
// Observe after iterations; |10⟩ should be smugly probable.

Want more? See QuantumSuperposition/docs/UsageExamples.md, QuantumSuperposition/docs/FunctionalOps.md, and friends. Or open an issue requesting something delightfully impractical.

PositronicVariables & Ecosystem

QuantumSuperposition plays nicely with the companion library PositronicVariables, which builds temporal convergence and STM-backed updates on top of QuBit<T>.

What PositronicVariables adds

  • PositronicVariable<T>: time-looping variables whose values are defined by iterative timelines and convergence until a fixed point (or stable superposition) is reached.
  • NeuralNodule<T>: quantum-flavoured nodes wiring PositronicVariables into recursive or cyclic networks.
  • STM-backed transactions: TransactionScope and TransactionV2 for multi-variable atomic updates, with telemetry covering commits, retries, aborts and contention.
  • ConvergenceCoordinator and QuantumLedgerOfRegret for serialised, debuggable convergence loops.

Small paradox example

using PositronicVariables;

var antival = PositronicVariable<int>.GetOrCreate("antival", -1);
Console.WriteLine($"antival = {antival}");

var val = -1 * antival;
Console.WriteLine($"val = {val}");

antival.State = val;

// after convergence: antival ≈ any(-1, 1)

PositronicVariables builds on QuantumSuperposition’s QuBit<T> types, while QuantumSuperposition happily lives on its own. Same semantics, fewer mental gear changes.

Convergence loop

Convergence is a polite argument with yourself conducted in epochs. Each forward pass proposes values; each reverse pass reconstructs the prior state; small cycles are unified. When the last slice matches a previous one, we declare peace.

var rt = PositronicAmbient.Current; // ensure ambient runtime exists
var a = PositronicVariable<int>.GetOrCreate("a", 0);
var b = PositronicVariable<int>.GetOrCreate("b", 1);

PositronicVariable<int>.RunConvergenceLoop(rt, () =>
{
    // Mutual recursion with a small constant offset
    a.Assign(b + 1);
    b.Assign(a - 1);
}, runFinalIteration: true, unifyOnConvergence: true);

Console.WriteLine($"a: {a}");
Console.WriteLine($"b: {b}");

Epoch tagging keeps slices aligned. Outside-loop writes are quarantined to bootstrap before the next run.

Transactions & STM

Use TransactionV2 for atomic multi-variable updates. Reads validate; writes stage; apply happens at commit under per-variable locks with deterministic ordering. Telemetry recounts every dramatic retry.

var x = PositronicVariable<int>.GetOrCreate("x", 41);
var y = PositronicVariable<int>.GetOrCreate("y", 1);

TransactionV2.RunWithRetry(tx =>
{
    tx.RecordRead(x);
    tx.RecordRead(y);

    var next = x.GetCurrentQBit() + y.GetCurrentQBit(); // QExpr arithmetic
    tx.StageWrite(x, (QuBit<int>)next);
});

Console.WriteLine(STMTelemetry.GetReport());

Read-only fast path: if no writes are staged, validation commits without taking write locks.

Reverse replay

Reverse ticks reconstruct the pre-print slice using the operation log (the QuantumLedgerOfRegret). Cross-variable assignments capture small additive deltas k in the forward pass and rebuild scalars accordingly in reverse.

var src = PositronicVariable<int>.GetOrCreate("src", 3);
var dst = PositronicVariable<int>.GetOrCreate("dst", 0);

PositronicVariable<int>.RunConvergenceLoop(PositronicAmbient.Current, () =>
{
    // dst follows src + 2, but only src gets logged in forward
    dst.Assign(src + 2);
});

Console.WriteLine(dst.ToTimelineString()); // shows reverse reconstruction slices

Edge guards suppress bootstrap union and scalar overwrite during the epoch a cross-reconstruction occurs, keeping causality tidy.

Cross-variable flows

Build networks of constraints across variables. Forward collects intent; reverse restores provenance.

var a = PositronicVariable<int>.GetOrCreate("a", -1);
var b = PositronicVariable<int>.GetOrCreate("b", 0);
var c = PositronicVariable<int>.GetOrCreate("c", 0);

PositronicVariable<int>.RunConvergenceLoop(PositronicAmbient.Current, () =>
{
    b.Assign(a + 1);   // b trails a by +1
    c.Assign(b + 1);   // c trails b by +1
    a.Required = c - 2; // close the loop as an equality constraint
});

If your loop has multiple consistent answers, the engine will keep both and call it character growth.

Neural nodules

Tiny quantum-aware neurons that accept multiple Positronic inputs, apply an activation function, and write to an output variable. Converge whole networks in one go.

var rt = PositronicAmbient.Current;
var n1 = new NeuralNodule<int>(vals =>
{
    var sum = vals.Sum();
    return new QuBit<int>(new[] { sum % 5, (sum + 1) % 5 });
}, rt);

var aIn = PositronicVariable<int>.GetOrCreate("aIn", 1);
var bIn = PositronicVariable<int>.GetOrCreate("bIn", 2);

n1.Inputs.Add(aIn);
n1.Inputs.Add(bIn);

NeuralNodule<int>.ConvergeNetwork(rt, n1);
Console.WriteLine($"Neuron output: {n1.Output}");

Timeline & unification

Each write appends or replaces the active slice. Cycles get detected (last equals a previous slice) and can be unified explicitly or automatically.

var v = PositronicVariable<int>.GetOrCreate("v", -1);
PositronicVariable<int>.RunConvergenceLoop(PositronicAmbient.Current, () =>
{
    v.Assign((v + 1) % 3); // gentle 0..2 cycle, depending on bootstrap
});

// If you insist on a single slice
v.UnifyAll();
Console.WriteLine(v);

Bootstrap is treated as sacred during a loop; outside writes are scrubbed before the next pass.

Telemetry & diagnostics

The STM layer tracks commits, retries, aborts, validation failures, lock-hold ticks and hotspots. The convergence layer exposes timeline snapshots and a readable ledger of operations.

Console.WriteLine(STMTelemetry.GetReport()); // contention, retries, hot variables
Console.WriteLine(v.ToTimelineString());     // per-slice states
var json = v.ExportToJson();                 // take your timeline to a meeting

Concurrency patterns

  • Concurrent mutation via transactions (deterministic lock ordering, id-based).
  • Convergence loop is single-threaded through a coordinator; outside writes are deferred.
  • Ambient state (operator logging suppression) is AsyncLocal-scoped.

Best practices

  • Keep forward writes simple; let reverse replay do the archaeology.
  • Prefer Required for hard constraints and Proposed/Assign for soft influence.
  • Quarantine outside-loop experimentation with NoteOutsideWrites() before convergence runs.
  • Use telemetry to identify hotspots, then batch or reorder updates.

NuGet: PositronicVariables NuGet PositronicVariables

Documentation & API Reference

The single-page overview here is the trailer. The full movie lives in the docs and source repository, with focused pages per subsystem.

Docs map (from the repo)

External docs site

Hosted documentation and additional examples: quantumsuperposition.hashnode.space

License

QuantumSuperposition and PositronicVariables are released under the Unlicense: public domain. You may copy, modify, fork into a sentient branch, or accidentally teach it sarcasm.


    This is free and unencumbered software released into the public domain.

    Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
    software, either in source code form or as a compiled binary, for any purpose,
    commercial or non-commercial, and by any means.

    Full text: https://github.com/hutchpd/QuantumSuperposition/blob/master/LICENSE.txt

If your compiler attains consciousness, offer tea, then file an issue.

Contact

Questions, bug reports, paradoxes or probability amplitudes that look suspiciously like a duck: open an issue or send an email. Extra points if the duck collapses differently when observed.

Polite feature requests welcome. Chronologically paradoxical ones even more so.