├── docs └── CNAME ├── PositronicVariables ├── icon.png ├── readme.md ├── Engine │ ├── Transponder │ │ ├── ISubEthaTransponder.cs │ │ └── SubEthaOutputTransponder.cs │ ├── Logging │ │ ├── IOperationLogHandler.cs │ │ ├── MerlinFroMarker.cs │ │ ├── ILedgerSink.cs │ │ ├── BufferedLedgerEntry.cs │ │ ├── IOperation.cs │ │ ├── Ledger.cs │ │ ├── LedgerSink.cs │ │ ├── RegretScribe.cs │ │ └── QuantumLedgerOfRegret.cs │ ├── Coordinator │ │ └── IConvergenceWorkItem.cs │ ├── IImprobabilityEngine.cs │ ├── Entropy │ │ ├── IEntropyController.cs │ │ └── DefaultEntropyController.cs │ ├── ChroniclerDrive.cs │ ├── Timeline │ │ ├── ImmutableTimelineSnapshot.cs │ │ ├── TimelineReplaceOperation.cs │ │ ├── TimelineAppendOperation.cs │ │ └── ITimelineArchivist.cs │ └── ConvergenceEngineBuilder.cs ├── Runtime │ ├── IPositronicVariableRegistry.cs │ ├── IPositronicRuntime.cs │ ├── DefaultPositronicRuntime.cs │ ├── PositronicAmbient.cs │ └── NumericOps.cs ├── Transactions │ ├── TransactionAbortedException.cs │ ├── ITransactionalVariable.cs │ ├── ParanoiaConfig.cs │ ├── Transaction.cs │ ├── Hotspot.cs │ ├── HotspotAggregator.cs │ └── ConcurrencyGuard.cs ├── Attributes │ └── DontPanicAttribute.cs ├── Variables │ ├── QSugar.cs │ ├── IPositronicVariable.cs │ └── Factory │ │ ├── IPositronicVariableFactory.cs │ │ └── ScopedPositronicVariableFactory.cs ├── Initialisation │ └── NeuroCascadeInitialiser.cs ├── Operations │ ├── Interfaces │ │ ├── IReversibleSnapshotOperation.cs │ │ └── IReversibleOperation.cs │ ├── InversionOperation.cs │ ├── BitwiseNotOperation.cs │ ├── BitwiseXorOperation.cs │ ├── BitwiseAndOperation.cs │ ├── BitwiseOrOperation.cs │ ├── ShiftLeftOperation.cs │ ├── ShiftRightOperation.cs │ ├── AssignOperation.cs │ ├── NegationOperation.cs │ ├── MultiplicationOperation.cs │ ├── DivisionOperation.cs │ ├── DivisionReversedOperation.cs │ ├── AdditionOperation.cs │ ├── SubtractionReversedOperation.cs │ ├── SubtractionOperation.cs │ └── ReversibleModulusOp.cs ├── Maths │ └── Bitwise.cs ├── LICENSE ├── Api │ └── AntiVal.cs ├── PositronicVariables.csproj ├── DependencyInjection │ └── PositronicServiceCollectionExtensions.cs └── Neural │ └── NeuralNodule.cs ├── QuantumSuperposition ├── icon.png ├── docs │ ├── ComplexSupport.md │ ├── FunctionalOps.md │ ├── Equality.md │ ├── PhysicsQubit.md │ ├── GateRegisterSugar.md │ ├── GateCatalogue.md │ ├── CanonicalStates.md │ ├── QuantumRegister.md │ ├── BasisMapping.md │ └── UsageExamples.md ├── Core │ ├── QuantumStateType.cs │ ├── IQuantumOperators.cs │ └── QuantumConfig.cs ├── Utilities │ ├── IntArrayComparer.cs │ ├── QuantumGateTools.cs │ └── GateSchedulingVisualiser.cs ├── LICENSE ├── Entanglement │ └── EntanglementExtensions.cs ├── QuantumSoup │ ├── CommutativeKey.cs │ ├── PhysicsQubit.cs │ └── Interfaces.cs ├── Operators │ ├── IntOperators.cs │ ├── LongOperators.cs │ ├── UIntOperators.cs │ ├── ULongOperators.cs │ ├── ByteOperators.cs │ ├── CharOperators.cs │ ├── ShortOperators.cs │ ├── SByteOperators.cs │ ├── FloatOperators.cs │ ├── UShortOperators.cs │ ├── DoubleOperators.cs │ ├── DecimalOperators.cs │ ├── TimeSpanOperators.cs │ ├── BooleanOperators.cs │ ├── GuidOperators.cs │ ├── VersionOperators.cs │ ├── DateTimeOperators.cs │ ├── ComplexOperators.cs │ ├── UriOperators.cs │ ├── QuantumOperatorsFactory.cs │ ├── GenericOperator.cs │ └── StringOperators.cs └── QuantumSuperposition.csproj ├── PositronicTester ├── PositronicVariableTests.cs ├── PositronicTester.csproj ├── ConcurrencyTestHelpers.cs ├── PositronicVariableConcurrencyTests.cs ├── ParanoiaModeTests.cs └── ConvergenceCoordinatorTests.cs ├── QuantumSoupTester ├── GateQueueOptimizationTests.cs ├── CollapsePropagationTests.cs ├── QuantumSoupTester.csproj ├── PartialObservationEdgeTests.cs ├── EqualityTests.cs ├── QuantumRegisterTests.cs ├── GateRegisterSugarTests.cs ├── StringTests.cs ├── CanonicalStatesTests.cs ├── BasisMappingTests.cs └── PhysicsQubitTests.cs ├── QuantumBenchmarks ├── Program.cs ├── QuantumBenchmarks.csproj └── Benchmarks │ ├── SetFromTensorProductBenchmarks.cs │ ├── MultiQubitGateBenchmarks.cs │ └── GateQueueOptimizationBenchmarks.cs ├── TestQSP └── TestQSP.csproj ├── TestPV └── TestPV.csproj ├── LICENSE.txt └── .gitattributes /docs/CNAME: -------------------------------------------------------------------------------- 1 | quantumsuperposition.findonsoftware.com -------------------------------------------------------------------------------- /PositronicVariables/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hutchpd/QuantumSuperposition/HEAD/PositronicVariables/icon.png -------------------------------------------------------------------------------- /PositronicVariables/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hutchpd/QuantumSuperposition/HEAD/PositronicVariables/readme.md -------------------------------------------------------------------------------- /QuantumSuperposition/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hutchpd/QuantumSuperposition/HEAD/QuantumSuperposition/icon.png -------------------------------------------------------------------------------- /PositronicTester/PositronicVariableTests.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hutchpd/QuantumSuperposition/HEAD/PositronicTester/PositronicVariableTests.cs -------------------------------------------------------------------------------- /QuantumSuperposition/docs/ComplexSupport.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hutchpd/QuantumSuperposition/HEAD/QuantumSuperposition/docs/ComplexSupport.md -------------------------------------------------------------------------------- /QuantumSoupTester/GateQueueOptimizationTests.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hutchpd/QuantumSuperposition/HEAD/QuantumSoupTester/GateQueueOptimizationTests.cs -------------------------------------------------------------------------------- /PositronicVariables/Engine/Transponder/ISubEthaTransponder.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Engine.Transponder 2 | { 3 | public interface ISubEthaTransponder 4 | { 5 | void Redirect(); 6 | void Restore(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /QuantumBenchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | using QuantumBenchmarks.Benchmarks; 3 | 4 | BenchmarkRunner.Run(); 5 | BenchmarkRunner.Run(); 6 | BenchmarkRunner.Run(); 7 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/IOperationLogHandler.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Engine.Logging 2 | { 3 | public interface IOperationLogHandler 4 | { 5 | void Record(IOperation op); 6 | void UndoLastForwardCycle(); 7 | void Clear(); 8 | bool SawForwardWrite { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /PositronicVariables/Runtime/IPositronicVariableRegistry.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Variables; 2 | using System.Collections.Generic; 3 | 4 | namespace PositronicVariables.Runtime 5 | { 6 | public interface IPositronicVariableRegistry : IEnumerable 7 | { 8 | void Add(IPositronicVariable variable); 9 | void Clear(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/TransactionAbortedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Transactions 4 | { 5 | public sealed class TransactionAbortedException : Exception 6 | { 7 | public int Attempts { get; } 8 | public TransactionAbortedException(string message, int attempts) : base(message) 9 | { 10 | Attempts = attempts; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /TestQSP/TestQSP.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net10.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Coordinator/IConvergenceWorkItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using PositronicVariables.Transactions; 4 | 5 | namespace PositronicVariables.Engine.Coordinator 6 | { 7 | public interface IConvergenceWorkItem 8 | { 9 | void BuildWrites(TransactionV2 tx); 10 | IEnumerable BuildCommitHooks(); 11 | object? GetResultAfterCommit(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/IImprobabilityEngine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Engine 4 | { 5 | public interface IImprobabilityEngine 6 | where T : IComparable 7 | { 8 | void Run( 9 | Action code, 10 | bool runFinalIteration = true, 11 | bool unifyOnConvergence = true, 12 | bool bailOnFirstReverseWhenIdle = false, 13 | IImprobabilityEngine next = null); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /PositronicVariables/Attributes/DontPanicAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Attributes 4 | { 5 | /// 6 | /// Marks a single static method as the convergence entry point. 7 | /// The engine will reflect for exactly one method bearing this attribute. 8 | /// 9 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] 10 | public sealed class DontPanicAttribute : Attribute 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/MerlinFroMarker.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Engine.Logging 2 | { 3 | /// 4 | /// Marks the beginning of a forward half‑cycle in the OperationLog. 5 | /// Lets reverse‑replay peel exactly one forward half‑cycle and no more. 6 | /// 7 | public sealed class MerlinFroMarker : IOperation 8 | { 9 | public string OperationName => "ForwardHalfCycleStart"; 10 | public void Undo() { /* no‑op */ } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/ILedgerSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Engine.Logging 4 | { 5 | /// 6 | /// Transactional sink for operation ledger entries with idempotent append semantics. 7 | /// 8 | public interface ILedgerSink 9 | { 10 | void Append(IOperation op, Guid commitId); 11 | IOperation Peek(); 12 | void Pop(); 13 | void ReverseLastOperations(); 14 | void Clear(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/ITransactionalVariable.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Transactions 2 | { 3 | public enum TxMutationKind 4 | { 5 | Append, 6 | ReplaceLast, 7 | OverwriteBootstrap 8 | } 9 | public interface ITransactionalVariable 10 | { 11 | long TxId { get; } 12 | long TxVersion { get; } 13 | object TxLock { get; } 14 | void TxApply(object qb, TxMutationKind kind); 15 | void TxBumpVersion(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /QuantumBenchmarks/QuantumBenchmarks.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | net8.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/BufferedLedgerEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Engine.Logging 4 | { 5 | public readonly struct BufferedLedgerEntry 6 | { 7 | public readonly IOperation Entry; 8 | public readonly Guid CommitId; 9 | public BufferedLedgerEntry(IOperation entry, Guid commitId) 10 | { 11 | Entry = entry ?? throw new ArgumentNullException(nameof(entry)); 12 | CommitId = commitId; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/IOperation.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Engine.Logging 2 | { 3 | public interface IOperation 4 | { 5 | /// 6 | /// Invokes the logic to undo the operation. 7 | /// 8 | void Undo(); 9 | 10 | /// 11 | /// A polite label slapped on your operation so future archeologists of this code can blame someone else. 12 | /// 13 | string OperationName { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /PositronicVariables/Variables/QSugar.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.QuantumSoup; 2 | using System; 3 | 4 | namespace PositronicVariables.Variables 5 | { 6 | public static class QSugar 7 | { 8 | // Usage: target <<= Q(10); or target <<= Q(7, 8, 9); 9 | public static QuBit Q(params T[] values) where T : IComparable 10 | { 11 | var qb = new QuBit(values); 12 | qb.Any(); // mark as superposition-friendly 13 | return qb; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/Ledger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Engine.Logging 4 | { 5 | /// 6 | /// Global access point for the process-wide ledger sink. 7 | /// 8 | public static class Ledger 9 | { 10 | private static ILedgerSink _sink = new LedgerSink(); 11 | public static ILedgerSink Sink 12 | { 13 | get => _sink; 14 | set => _sink = value ?? throw new ArgumentNullException(nameof(value)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Entropy/IEntropyController.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Engine.Entropy 2 | { 3 | public interface IEntropyController 4 | { 5 | int Entropy { get; } 6 | 7 | /// 8 | /// In some universes time goes backwards, and in some it goes forwards. See Red Dwarf - backwards for details you smeghead. 9 | /// 10 | void Initialise(); 11 | /// 12 | /// Flip the direction of time's arrow. 13 | /// 14 | void Flip(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/ChroniclerDrive.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Engine 4 | { 5 | public class ChroniclerDrive : IImprobabilityEngine 6 | where T : IComparable 7 | { 8 | public void Run( 9 | Action code, 10 | bool runFinalIteration = true, 11 | bool unifyOnConvergence = true, 12 | bool bailOnFirstReverseWhenIdle = false, 13 | IImprobabilityEngine next = null) 14 | { 15 | next?.Run(code, runFinalIteration, unifyOnConvergence, bailOnFirstReverseWhenIdle); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /QuantumSuperposition/Core/QuantumStateType.cs: -------------------------------------------------------------------------------- 1 | namespace QuantumSuperposition.Core 2 | { 3 | /// 4 | /// Represents the current mood of the QuBit. Is it feeling inclusive (All)? 5 | /// Or indecisive (Any)? Or has it finally made up its mind (Collapsed)? 6 | /// 7 | public enum QuantumStateType 8 | { 9 | SuperpositionAll, // All states must be true. Like group projects, but successful. 10 | SuperpositionAny, // Any state can be true. Like excuses for missing deadlines. 11 | CollapsedResult // Only one state remains after collapse. R.I.P. potential. 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /QuantumSuperposition/Utilities/IntArrayComparer.cs: -------------------------------------------------------------------------------- 1 | namespace QuantumSuperposition.Utilities 2 | { 3 | public class IntArrayComparer : IEqualityComparer 4 | { 5 | public bool Equals(int[]? x, int[]? y) 6 | { 7 | return x != null && y != null && x.SequenceEqual(y); 8 | } 9 | 10 | public int GetHashCode(int[] obj) 11 | { 12 | unchecked 13 | { 14 | int hash = 17; 15 | foreach (int val in obj) 16 | { 17 | hash = (hash * 31) + val; 18 | } 19 | return hash; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /PositronicVariables/Initialisation/NeuroCascadeInitialiser.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Transponder; 2 | 3 | namespace PositronicVariables.Initialisation 4 | { 5 | /// 6 | /// The Matrix is everywhere. It is all around us. Even now, in this very room. 7 | /// 8 | public static class NeuroCascadeInitialiser 9 | { 10 | /// 11 | /// Activates the latent matrix Initialiser. It doesn't *do* anything, 12 | /// but the side effects are, frankly, terrifying. 13 | /// 14 | public static void AutoEnable() 15 | { 16 | _ = AethericRedirectionGrid.Initialised; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /PositronicVariables/Variables/IPositronicVariable.cs: -------------------------------------------------------------------------------- 1 | namespace PositronicVariables.Variables 2 | { 3 | /// 4 | /// Direction of time: +1 for forward, -1 for reverse, this time machine only has two gears. 5 | /// 6 | public interface IPositronicVariable 7 | { 8 | /// 9 | /// Unifies all timeline slices into a single disjunctive state, 10 | /// kind of like a group project where everyone finally agrees on something. 11 | /// 12 | int Converged(); 13 | 14 | /// 15 | /// Melds every branching future into one reluctant consensus, like a committee that's given up. 16 | /// 17 | void UnifyAll(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /QuantumSuperposition/Core/IQuantumOperators.cs: -------------------------------------------------------------------------------- 1 | namespace QuantumSuperposition.Core 2 | { 3 | /// 4 | /// A set of mathematical operations tailored for types that wish they were numbers. 5 | /// 6 | /// 7 | public interface IQuantumOperators 8 | { 9 | T Add(T a, T b); 10 | T Subtract(T a, T b); 11 | T Multiply(T a, T b); 12 | T Divide(T a, T b); 13 | T Mod(T a, T b); 14 | bool GreaterThan(T a, T b); 15 | bool GreaterThanOrEqual(T a, T b); 16 | bool LessThan(T a, T b); 17 | bool LessThanOrEqual(T a, T b); 18 | bool Equal(T a, T b); 19 | bool NotEqual(T a, T b); 20 | bool IsAddCommutative { get; } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/LedgerSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Engine.Logging 4 | { 5 | /// 6 | /// Default ledger sink delegating to QuantumLedgerOfRegret with idempotent append. 7 | /// Think of it as a responsible adult supervising your regrets. 8 | /// 9 | public sealed class LedgerSink : ILedgerSink 10 | { 11 | public void Append(IOperation op, Guid commitId) => QuantumLedgerOfRegret.Append(op, commitId); 12 | public IOperation Peek() => QuantumLedgerOfRegret.Peek(); 13 | public void Pop() => QuantumLedgerOfRegret.Pop(); 14 | public void ReverseLastOperations() => QuantumLedgerOfRegret.ReverseLastOperations(); 15 | public void Clear() => QuantumLedgerOfRegret.Clear(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/Interfaces/IReversibleSnapshotOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Logging; 2 | using PositronicVariables.Variables; 3 | using QuantumSuperposition.QuantumSoup; 4 | using System; 5 | 6 | namespace PositronicVariables.Operations.Interfaces 7 | { 8 | public interface IReversibleSnapshotOperation : IReversibleOperation 9 | where T : IComparable 10 | { 11 | PositronicVariable Variable { get; } 12 | T Original { get; } 13 | void IOperation.Undo() 14 | { 15 | QuBit qb = new(new[] { Original }); 16 | _ = qb.Any(); 17 | // Magically swap out the latest cosmic crumb for something more fitting of this reality 18 | Variable.ReplaceLastFromReverse(qb); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/Interfaces/IReversibleOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Logging; 2 | 3 | namespace PositronicVariables.Operations.Interfaces 4 | { 5 | public interface IReversibleOperation : IOperation 6 | { 7 | /// 8 | /// When time insists on moving forward, this little chap figures out how to make it march in reverse. 9 | /// (E.g. if you've divided by 9 in one universe, we smuggle you back with a ×9 in another.) 10 | /// 11 | T ApplyInverse(T result); 12 | /// 13 | /// Given the result of a forward operation, computes the forward value. 14 | /// 15 | /// 16 | /// 17 | T ApplyForward(T value); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /PositronicVariables/Maths/Bitwise.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Maths 4 | { 5 | /// 6 | /// Generic bitwise helpers for integral types. Uses dynamic to keep parity with Arithmetic helpers. 7 | /// 8 | public static class Bitwise 9 | { 10 | public static T And(T a, T b) => (T)(object)(((dynamic)a) & ((dynamic)b)); 11 | public static T Or(T a, T b) => (T)(object)(((dynamic)a) | ((dynamic)b)); 12 | public static T Xor(T a, T b) => (T)(object)(((dynamic)a) ^ ((dynamic)b)); 13 | public static T Not(T a) => (T)(object)(~((dynamic)a)); 14 | 15 | public static T ShiftLeft(T a, int count) => (T)(object)(((dynamic)a) << count); 16 | public static T ShiftRight(T a, int count) => (T)(object)(((dynamic)a) >> count); 17 | } 18 | } -------------------------------------------------------------------------------- /PositronicVariables/Engine/Timeline/ImmutableTimelineSnapshot.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.QuantumSoup; 2 | using System; 3 | 4 | namespace PositronicVariables.Engine.Timeline 5 | { 6 | public sealed class ImmutableTimelineSnapshot 7 | where T : IComparable 8 | { 9 | public long PositronicVariableId { get; } 10 | public long Version { get; } 11 | public QuBit[] Slices { get; } 12 | public DateTimeOffset Timestamp { get; } 13 | 14 | public ImmutableTimelineSnapshot(long variableId, long version, QuBit[] slices) 15 | { 16 | PositronicVariableId = variableId; 17 | Version = version; 18 | // Store clones to preserve immutability 19 | Slices = slices ?? Array.Empty>(); 20 | Timestamp = DateTimeOffset.UtcNow; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /QuantumBenchmarks/Benchmarks/SetFromTensorProductBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using QuantumSuperposition.Systems; 3 | using QuantumSuperposition.QuantumSoup; 4 | using System.Numerics; 5 | 6 | namespace QuantumBenchmarks.Benchmarks; 7 | 8 | [MemoryDiagnoser] 9 | [RankColumn] 10 | public class SetFromTensorProductBenchmarks 11 | { 12 | [Params(6, 12)] public int QubitCount; 13 | private QuantumSystem _system = null!; 14 | 15 | [GlobalSetup] 16 | public void Setup() 17 | { 18 | _system = new QuantumSystem(); 19 | } 20 | 21 | [Benchmark] 22 | public void BuildTensorProduct() 23 | { 24 | var qubits = Enumerable.Range(0, QubitCount) 25 | .Select(i => new QuBit(_system, new[] { i }).WithWeights(new Dictionary { { 0, 1.0 }, { 1, 1.0 } }, true)) 26 | .ToArray(); 27 | _system.SetFromTensorProduct(false, qubits); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /QuantumSuperposition/Utilities/QuantumGateTools.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | 3 | namespace QuantumSuperposition.Utilities 4 | { 5 | 6 | public static class QuantumGateTools 7 | { 8 | public static Complex[,] ConjugateTranspose(Complex[,] matrix) 9 | { 10 | int rows = matrix.GetLength(0); 11 | int cols = matrix.GetLength(1); 12 | Complex[,] result = new Complex[cols, rows]; // transpose shape 13 | 14 | for (int i = 0; i < rows; i++) 15 | { 16 | for (int j = 0; j < cols; j++) 17 | { 18 | result[j, i] = Complex.Conjugate(matrix[i, j]); 19 | } 20 | } 21 | 22 | return result; 23 | } 24 | 25 | public static Complex[,] InvertGate(Complex[,] gate) 26 | { 27 | // Unitary matrix inverse = its conjugate transpose 28 | return ConjugateTranspose(gate); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /PositronicVariables/Operations/InversionOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Logging; 2 | using PositronicVariables.Runtime; 3 | using PositronicVariables.Variables; 4 | using System; 5 | 6 | namespace PositronicVariables.Operations 7 | { 8 | public class InversionOperation(PositronicVariable variable, T originalValue, T invertedValue, string opName) : IOperation 9 | where T : IComparable 10 | { 11 | private readonly PositronicVariable _variable = variable; 12 | private readonly T _originalValue = originalValue; 13 | private readonly T _invertedValue = invertedValue; 14 | public string OperationName { get; } = $"Inverse of {opName}"; 15 | 16 | /// 17 | /// When time moves forward, we apply the inversion. 18 | /// 19 | public void Undo() 20 | { 21 | // To undo an inversion, reassign the original forward value. 22 | _variable.Assign(_originalValue); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/BitwiseNotOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public sealed class BitwiseNotOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | public T Original { get; } 15 | 16 | public string OperationName => "Bitwise NOT"; 17 | 18 | public BitwiseNotOperation(PositronicVariable variable, IPositronicRuntime _) 19 | { 20 | Variable = variable; 21 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 22 | } 23 | 24 | // NOT is self-inverse 25 | public T ApplyInverse(T result) => Bitwise.Not(result); 26 | 27 | public T ApplyForward(T value) => Bitwise.Not(value); 28 | } 29 | } -------------------------------------------------------------------------------- /QuantumSuperposition/docs/FunctionalOps.md: -------------------------------------------------------------------------------- 1 | ## Functional & LINQ Operations 2 | 3 | ## Required Namespaces 4 | 5 | Make sure to import the correct namespaces for these examples. 6 | 7 | ```csharp 8 | using System.Numerics; 9 | using QuantumSuperposition.QuantumSoup; 10 | using QuantumSuperposition.Core; 11 | ``` 12 | 13 | These features let you get playful with logic and structure without observation causing your fragile multiverse to unravel. 14 | 15 | - `p_op`: Conditional without collapse. Schrödinger's choice logic. 16 | - `p_func`: Functional state transforms. Map, filter, flatten without collapsing. LINQ for the superposed soul. 17 | - Non observational arithmetic: enable operations like `+`, `*`, etc., without collapsing your `QuBit`. You get the maths and you keep the quantum soup. 18 | - Weighted function composition: let probabilistic weights influence branching logic. 19 | - Commutative optimisation: cache results of pure, commutative operations. Why recompute 2+3 when 3+2 already did the work? 20 | - Monad compatible superpositions: LINQ style `.Select()`, `.Where()`, `.SelectMany()` with lazy evaluation that optimises performance. 21 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/BitwiseXorOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public sealed class BitwiseXorOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | public T Operand { get; } 15 | public T Original { get; } 16 | 17 | public string OperationName => $"Bitwise XOR with {Operand}"; 18 | 19 | public BitwiseXorOperation(PositronicVariable variable, T operand, IPositronicRuntime _) 20 | { 21 | Variable = variable; 22 | Operand = operand; 23 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 24 | } 25 | 26 | // XOR is self-inverse 27 | public T ApplyInverse(T result) => Bitwise.Xor(result, Operand); 28 | 29 | public T ApplyForward(T value) => Bitwise.Xor(value, Operand); 30 | } 31 | } -------------------------------------------------------------------------------- /PositronicVariables/Operations/BitwiseAndOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public sealed class BitwiseAndOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | public T Operand { get; } 15 | public T Original { get; } 16 | 17 | public string OperationName => $"Bitwise AND with {Operand}"; 18 | 19 | public BitwiseAndOperation(PositronicVariable variable, T operand, IPositronicRuntime _) 20 | { 21 | Variable = variable; 22 | Operand = operand; 23 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 24 | } 25 | 26 | // Not invertible in general: restore snapshot 27 | public T ApplyInverse(T result) => Original; 28 | 29 | public T ApplyForward(T value) => Bitwise.And(value, Operand); 30 | } 31 | } -------------------------------------------------------------------------------- /PositronicVariables/Operations/BitwiseOrOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public sealed class BitwiseOrOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | public T Operand { get; } 15 | public T Original { get; } 16 | 17 | public string OperationName => $"Bitwise OR with {Operand}"; 18 | 19 | public BitwiseOrOperation(PositronicVariable variable, T operand, IPositronicRuntime _) 20 | { 21 | Variable = variable; 22 | Operand = operand; 23 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 24 | } 25 | 26 | // Not invertible in general: restore snapshot 27 | public T ApplyInverse(T result) => Original; 28 | 29 | public T ApplyForward(T value) => Bitwise.Or(value, Operand); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /PositronicVariables/Operations/ShiftLeftOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public sealed class ShiftLeftOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | public int Count { get; } 15 | public T Original { get; } 16 | 17 | public string OperationName => $"Shift Left by {Count}"; 18 | 19 | public ShiftLeftOperation(PositronicVariable variable, int count, IPositronicRuntime _) 20 | { 21 | Variable = variable; 22 | Count = count; 23 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 24 | } 25 | 26 | // Not invertible in general (bit loss): restore snapshot 27 | public T ApplyInverse(T result) => Original; 28 | 29 | public T ApplyForward(T value) => Bitwise.ShiftLeft(value, Count); 30 | } 31 | } -------------------------------------------------------------------------------- /PositronicVariables/Operations/ShiftRightOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public sealed class ShiftRightOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | public int Count { get; } 15 | public T Original { get; } 16 | 17 | public string OperationName => $"Shift Right by {Count}"; 18 | 19 | public ShiftRightOperation(PositronicVariable variable, int count, IPositronicRuntime _) 20 | { 21 | Variable = variable; 22 | Count = count; 23 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 24 | } 25 | 26 | // Not invertible in general (bit loss): restore snapshot 27 | public T ApplyInverse(T result) => Original; 28 | 29 | public T ApplyForward(T value) => Bitwise.ShiftRight(value, Count); 30 | } 31 | } -------------------------------------------------------------------------------- /QuantumSoupTester/CollapsePropagationTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using QuantumSuperposition.QuantumSoup; 3 | using QuantumSuperposition.Systems; 4 | using System.Numerics; 5 | using System.Linq; 6 | 7 | namespace QuantumSoupTester 8 | { 9 | [TestFixture] 10 | public class CollapsePropagationTests 11 | { 12 | [Test] 13 | public void ObserveGlobal_PropagatesCollapseAcrossEntanglementGroups() 14 | { 15 | var system = new QuantumSystem(); 16 | var qA = new QuBit(system, new[] { 0 }).WithWeights(new Dictionary{{0,1.0},{1,1.0}}, true); 17 | var qB = new QuBit(system, new[] { 1 }).WithWeights(new Dictionary{{0,1.0},{1,1.0}}, true); 18 | // Link entanglement group 19 | _ = system.Entanglement.Link("GroupAB", qA, qB); 20 | system.SetFromTensorProduct(false, qA, qB); 21 | // Collapse via observing A only 22 | _ = qA.Observe(new Random(7)); 23 | Assert.That(qA.IsCollapsed, Is.True); 24 | Assert.That(qB.IsCollapsed, Is.True, "Collapse should propagate to entangled partner."); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TestPV/TestPV.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net10.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | <_Parameter1>PositronicTester 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Entropy/DefaultEntropyController.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Runtime; 2 | namespace PositronicVariables.Engine.Entropy 3 | { 4 | /// 5 | /// The DefaultEntropyController is like the universe's mood ring, flipping between order and chaos with a dramatic flair. 6 | /// 7 | public class DefaultEntropyController : IEntropyController 8 | { 9 | private readonly IPositronicRuntime _runtime; 10 | public DefaultEntropyController(IPositronicRuntime runtime) 11 | { 12 | _runtime = runtime; 13 | } 14 | 15 | public int Entropy => _runtime.Entropy; 16 | /// 17 | /// Winds the temporal crank backwards to appease the spiteful spirits of past simulations. 18 | /// 19 | public void Initialise() 20 | { 21 | _runtime.Entropy = -1; 22 | } 23 | 24 | /// 25 | /// Flips the entropy switch, because even the universe needs to change its mind sometimes. 26 | /// 27 | public void Flip() 28 | { 29 | _runtime.Entropy = -_runtime.Entropy; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/Equality.md: -------------------------------------------------------------------------------- 1 | # Equality and AlmostEquals 2 | 3 | This library provides tolerant equality checks for registers and eigenstates. 4 | 5 | ## QuantumRegister.AlmostEquals 6 | 7 | Compare two `QuantumRegister` instances by projecting the underlying system amplitudes onto each register's subspace and checking element-wise closeness within a tolerance. 8 | 9 | ```csharp 10 | bool approx = regA.AlmostEquals(regB, tolerance: 1e-9); 11 | bool exact = regA.Equals(regB); // zero-tolerance 12 | ``` 13 | 14 | Notes: 15 | - Registers must span the same number of qubits. 16 | - Amplitudes are aggregated in the order of indices as stored in each register. 17 | 18 | ## Eigenstates.AlmostEquals 19 | 20 | Compare eigenstates by probability mass per value, tolerant to small complex differences. 21 | 22 | ```csharp 23 | var e1 = new Eigenstates(new[]{1,2,3}).WithWeights(new(){ {1, 1.0}, {2, 1.0}, {3, 0.0} }); 24 | var e2 = new Eigenstates(new[]{1,2,3}).WithWeights(new(){ {1, 1.0}, {2, 1.0}, {3, 1e-11} }); 25 | Assert.IsTrue(e1.AlmostEquals(e2, 1e-9)); 26 | ``` 27 | 28 | The comparison: 29 | - Compares the value sets for equality. 30 | - Compares probability mass |amp|^2 per value within the tolerance. 31 | -------------------------------------------------------------------------------- /QuantumSuperposition/Core/QuantumConfig.cs: -------------------------------------------------------------------------------- 1 | namespace QuantumSuperposition.Core 2 | { 3 | public static class QuantumConfig 4 | { 5 | /// 6 | /// Set to true to disallow collapse if the resulting value equals default(T). 7 | /// 8 | public static bool ForbidDefaultOnCollapse { get; set; } = true; 9 | 10 | /// 11 | /// Set to true to allow non-observational arithmetic. 12 | /// 13 | public static bool EnableNonObservationalArithmetic { get; set; } = true; 14 | 15 | /// 16 | /// Set to true to enable commutative cache for faster operations. 17 | /// 18 | public static bool EnableCommutativeCache { get; set; } = true; 19 | 20 | /// 21 | /// If true, newly constructed QuantumGate instances validate approximate unitarity (M * M† ≈ I). 22 | /// 23 | public static bool ValidateUnitarity { get; set; } = true; 24 | 25 | /// 26 | /// Tolerance used for unitarity validation when is enabled. 27 | /// 28 | public static double UnitarityTolerance { get; set; } = 1e-9; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/PhysicsQubit.md: -------------------------------------------------------------------------------- 1 | # PhysicsQubit - Bloch Sphere Constructors and |0>, |1> Shortcuts 2 | 3 | `PhysicsQubit` is a specialised `QuBit` constrained to the computational basis {0, 1}. It provides convenient constructors to initialise amplitudes directly or via Bloch sphere parameters, and static shortcuts for the basis states. 4 | 5 | - Amplitude constructor: `PhysicsQubit(Complex alpha, Complex beta)` 6 | - Component constructor: `PhysicsQubit(double aRe, double aIm, double bRe, double bIm)` 7 | - Bloch sphere constructor: `PhysicsQubit(double theta, double phi)` which maps 8 | |ψ> = cos(θ/2)|0> + e^{iφ} sin(θ/2)|1> 9 | - Shortcuts: `PhysicsQubit.Zero`, `PhysicsQubit.One` 10 | 11 | Internally, weights are set to `{ 0 -> alpha, 1 -> beta }` and normalised using the existing weight logic. 12 | 13 | ## Example 14 | 15 | ```csharp 16 | using QuantumSuperposition.QuantumSoup; 17 | using System.Numerics; 18 | 19 | // Direct amplitudes 20 | var q1 = new PhysicsQubit(new Complex(1, 0), Complex.Zero); // |0> 21 | 22 | // From components 23 | var q2 = new PhysicsQubit(0, 0, 1, 0); // |1> 24 | 25 | // Bloch sphere (theta, phi) 26 | var qs = new PhysicsQubit(Math.PI/2, 0); // (|0> + |1>)/sqrt(2) 27 | 28 | // Shortcuts 29 | var z = PhysicsQubit.Zero; 30 | var o = PhysicsQubit.One; 31 | ``` 32 | -------------------------------------------------------------------------------- /PositronicVariables/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /QuantumSuperposition/LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /QuantumBenchmarks/Benchmarks/MultiQubitGateBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using QuantumSuperposition.Systems; 3 | using QuantumSuperposition.QuantumSoup; 4 | using QuantumSuperposition.Utilities; 5 | using System.Numerics; 6 | 7 | namespace QuantumBenchmarks.Benchmarks; 8 | 9 | [MemoryDiagnoser] 10 | [RankColumn] 11 | public class MultiQubitGateBenchmarks 12 | { 13 | [Params(6, 10)] public int QubitCount; 14 | private QuantumSystem _system = null!; 15 | private Complex[,] _hadamard; 16 | 17 | [GlobalSetup] 18 | public void Setup() 19 | { 20 | _system = new QuantumSystem(); 21 | // Initialise qubits in |0> + |1> superposition via tensor product 22 | var qubits = Enumerable.Range(0, QubitCount) 23 | .Select(i => new QuBit(_system, new[] { i }).WithWeights(new Dictionary { { 0, 1.0 }, { 1, 1.0 } }, true)) 24 | .ToArray(); 25 | _system.SetFromTensorProduct(false, qubits); 26 | _hadamard = QuantumGates.Hadamard; // 2x2 27 | } 28 | 29 | [Benchmark] 30 | public void ApplyAllHadamards() 31 | { 32 | for (int i = 0; i < QubitCount; i++) 33 | { 34 | _system.ApplySingleQubitGate(i, _hadamard, "H"); 35 | } 36 | _system.ProcessGateQueue(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/AssignOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Operations.Interfaces; 2 | using PositronicVariables.Runtime; 3 | using PositronicVariables.Variables; 4 | using System; 5 | using System.Linq; 6 | 7 | namespace PositronicVariables.Operations 8 | { 9 | public class AssignOperation(PositronicVariable variable, T assigned) : IReversibleSnapshotOperation 10 | where T : IComparable 11 | { 12 | public PositronicVariable Variable { get; } = variable; 13 | public T Original { get; } = variable.GetCurrentQBit().ToCollapsedValues().First(); 14 | 15 | public string OperationName => $"Assign {assigned}"; 16 | 17 | /// 18 | /// Go back to whatever was once there after we started going forwards the first time 19 | /// 20 | /// 21 | /// 22 | public T ApplyInverse(T result) 23 | { 24 | return Original; 25 | } 26 | 27 | /// 28 | /// Time travel as we know it on a day to day basis 29 | /// 30 | /// 31 | /// 32 | public T ApplyForward(T value) 33 | { 34 | return assigned; 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /QuantumSuperposition/Entanglement/EntanglementExtensions.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.QuantumSoup; 2 | using QuantumSuperposition.Systems; 3 | 4 | namespace QuantumSuperposition.Entanglement 5 | { 6 | public static class EntanglementExtensions 7 | { 8 | /// 9 | /// Bond them in holy quantum matrimony. Till decoherence do them part. 10 | /// 11 | /// 12 | /// 13 | /// 14 | /// 15 | public static void Entangle(this QuantumSystem system, string groupLabel, params QuBit[] qubits) 16 | { 17 | // Use the updated Link method with the provided label. 18 | Guid groupId = system.Entanglement.Link(groupLabel, qubits); 19 | foreach (QuBit q in qubits) 20 | { 21 | q.SetEntanglementGroup(groupId); 22 | } 23 | } 24 | 25 | } 26 | 27 | public class EntanglementGroupVersion 28 | { 29 | public Guid GroupId { get; init; } 30 | public DateTime Timestamp { get; init; } = DateTime.UtcNow; 31 | public List Members { get; init; } = []; 32 | public string? ReasonForChange { get; init; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/NegationOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public class NegationOperation(PositronicVariable variable) : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } = variable; 14 | public T Original { get; } = variable.GetCurrentQBit().ToCollapsedValues().First(); 15 | 16 | public string OperationName => "Negation"; 17 | 18 | /// 19 | /// Negation is its own inverse, like a well-trained quantum ninja. 20 | /// 21 | /// 22 | /// 23 | public T ApplyInverse(T result) 24 | { 25 | return Arithmetic.Negate(result); 26 | } 27 | 28 | /// 29 | /// And going forwards is just the regular old negation. 30 | /// 31 | /// 32 | /// 33 | public T ApplyForward(T value) 34 | { 35 | return Arithmetic.Negate(value); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /QuantumSuperposition/QuantumSoup/CommutativeKey.cs: -------------------------------------------------------------------------------- 1 | namespace QuantumSuperposition.QuantumSoup 2 | { 3 | 4 | public readonly struct CommutativeKey 5 | { 6 | public T A { get; } 7 | public T B { get; } 8 | 9 | public CommutativeKey(T a, T b) 10 | { 11 | // If a and b are equal, the order doesn’t matter. 12 | // If they differ, we "order" them based on hash code (or you can require IComparable for a more robust solution) 13 | if (Comparer.Default.Compare(a, b) <= 0) 14 | { 15 | A = a; 16 | B = b; 17 | } 18 | else 19 | { 20 | A = b; 21 | B = a; 22 | } 23 | } 24 | 25 | public override bool Equals(object? obj) 26 | { 27 | return obj is CommutativeKey other && EqualityComparer.Default.Equals(A, other.A) && 28 | EqualityComparer.Default.Equals(B, other.B); 29 | } 30 | 31 | public override int GetHashCode() 32 | { 33 | unchecked 34 | { 35 | int hash = 17; 36 | hash = (hash * 31) + (A?.GetHashCode() ?? 0); 37 | hash = (hash * 31) + (B?.GetHashCode() ?? 0); 38 | return hash; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/GateRegisterSugar.md: -------------------------------------------------------------------------------- 1 | # Gate * Register Operator Sugar 2 | 3 | Adds physics style application of gates directly to a `QuantumRegister` using the `*` operator. 4 | 5 | ```csharp 6 | QuantumRegister reg = QuantumRegister.EPRPair(system); 7 | reg = QuantumGates.Hadamard * reg; // apply H to each qubit if size == 1 or appropriate arity 8 | ``` 9 | 10 | ## Behaviour 11 | 12 | - Gate dimension inferred from matrix size (2^n) 13 | - Gate arity must match `register.QubitIndices.Length` 14 | - 1 qubit and 2 qubit gates are enqueued and processed through the existing queue (preserving visualisation tooling) 15 | - Multi qubit (>2) gates applied immediately via `ApplyMultiQubitGate` 16 | - Returned register is a new view referencing the same indices 17 | 18 | ## Examples 19 | 20 | ```csharp 21 | var system = new QuantumSystem(); 22 | var reg = QuantumRegister.GHZState(system, length: 3); 23 | var custom3QGate = new QuantumGate(new Complex[,] { 24 | {1,0,0,0,0,0,0,0}, 25 | {0,1,0,0,0,0,0,0}, 26 | {0,0,1,0,0,0,0,0}, 27 | {0,0,0,1,0,0,0,0}, 28 | {0,0,0,0,1,0,0,0}, 29 | {0,0,0,0,0,1,0,0}, 30 | {0,0,0,0,0,0,1,0}, 31 | {0,0,0,0,0,0,0,1} 32 | }); 33 | reg = custom3QGate * reg; // multi qubit application 34 | ``` 35 | 36 | ## Notes 37 | - Gate must be square and power of two dimension 38 | - Throws if arity mismatch 39 | - Does not auto normalise. Relies on existing system normalisation 40 | -------------------------------------------------------------------------------- /QuantumSoupTester/QuantumSoupTester.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net10.0 5 | enable 6 | enable 7 | 8 | false 9 | true 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | 20 | all 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /PositronicVariables/Variables/Factory/IPositronicVariableFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Variables.Factory 4 | { 5 | public interface IPositronicVariableFactory 6 | { 7 | /// 8 | /// Rule 34 but for positronic variables: If it exists, there's a variable for it. If not, create one. 9 | /// 10 | /// 11 | /// 12 | /// 13 | /// 14 | PositronicVariable GetOrCreate(string id, T initialValue) where T : IComparable; 15 | /// 16 | /// Rule 34 but for positronic variables: If it exists, there's a variable for it. If not, create one. 17 | /// 18 | /// 19 | /// 20 | /// 21 | PositronicVariable GetOrCreate(string id) where T : IComparable; 22 | /// 23 | /// Rule 34 but for positronic variables: If it exists, there's a variable for it. If not, create one. 24 | /// 25 | /// 26 | /// 27 | /// 28 | PositronicVariable GetOrCreate(T initialValue) where T : IComparable; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/ConvergenceEngineBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace PositronicVariables.Engine 6 | { 7 | public class ConvergenceEngineBuilder 8 | where T : IComparable 9 | { 10 | private readonly List, IImprobabilityEngine>> _middlewares = []; 11 | 12 | /// 13 | /// Bolts a new questionable device onto the engine. Nobody asked what it does, and it's too late to stop now. 14 | /// 15 | public ConvergenceEngineBuilder Use(Func, IImprobabilityEngine> middleware) 16 | { 17 | _middlewares.Add(middleware); 18 | return this; 19 | } 20 | 21 | /// 22 | /// Summons the convergence abomination from its component horrors. Add enough decorators and it starts resembling sentience. 23 | /// 24 | public IImprobabilityEngine Build(IImprobabilityEngine core) 25 | { 26 | IImprobabilityEngine engine = core; 27 | foreach (Func, IImprobabilityEngine> middleware in _middlewares.Reverse, IImprobabilityEngine>>()) 28 | { 29 | engine = middleware(engine); 30 | } 31 | return engine; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /QuantumSoupTester/PartialObservationEdgeTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using QuantumSuperposition.Systems; 3 | using QuantumSuperposition.QuantumSoup; 4 | using System.Numerics; 5 | using System.Collections.Generic; 6 | 7 | namespace QuantumSoupTester 8 | { 9 | [TestFixture] 10 | public class PartialObservationEdgeTests 11 | { 12 | [Test] 13 | public void PartialObserve_AllZeroAmplitudes_ThrowsDiagnostic() 14 | { 15 | var system = new QuantumSystem(); 16 | // Use SetAmplitudes with zero amplitudes 17 | var amps = new Dictionary(new QuantumSuperposition.Utilities.IntArrayComparer()) 18 | { 19 | { new[]{0,0}, Complex.Zero }, 20 | { new[]{0,1}, Complex.Zero } 21 | }; 22 | system.SetAmplitudes(amps); 23 | Assert.Throws(() => system.PartialObserve(new[] { 0 })); 24 | } 25 | 26 | [Test] 27 | public void PartialObserve_SingleState_NoError() 28 | { 29 | var system = new QuantumSystem(); 30 | var q0 = new QuBit(system, new[] { 0 }).WithWeights(new Dictionary{{0,1.0}}, true); 31 | system.SetFromTensorProduct(false, q0); 32 | var outcome = system.PartialObserve(new[] { 0 }); 33 | Assert.That(outcome.Length, Is.EqualTo(1)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /PositronicTester/PositronicTester.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net10.0 5 | latest 6 | enable 7 | enable 8 | false 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | all 20 | runtime; build; native; contentfiles; analyzers; buildtransitive 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/GateCatalogue.md: -------------------------------------------------------------------------------- 1 | # Gate Catalogue Extensions 2 | 3 | New gates and factories exposed via `QuantumGates` for parity with common algorithm needs. 4 | 5 | ## Added Gates / Factories 6 | 7 | - Identity / `IdentityOfLength(n)` 8 | - `HadamardOfLength(n)` (tensor power of H) 9 | - Pauli-Y, Pauli-Z 10 | - SWAP, SquareRootSwap 11 | - Toffoli (CCNOT), Fredkin (CSWAP) 12 | - `Phase(theta)` / `PhaseShift(theta)` alias 13 | - `Controlled(inner)` generic controlled gate constructor 14 | - `QuantumFourierTransformGate(registerLength)` builds full QFT unitary 15 | 16 | ## Examples 17 | 18 | ```csharp 19 | // Multi-qubit identity 20 | var id4 = QuantumGates.IdentityOfLength(4); 21 | 22 | // 3-qubit Hadamard (H?H?H) 23 | var h3 = QuantumGates.HadamardOfLength(3); 24 | 25 | // Controlled arbitrary inner gate 26 | var cz = QuantumGates.Controlled(QuantumGates.PauliZ); 27 | 28 | // QFT gate for a 3-qubit register 29 | var qft3 = QuantumGates.QuantumFourierTransformGate(3); 30 | 31 | // Apply with sugar 32 | var system = new QuantumSystem(); 33 | var reg = QuantumRegister.GHZState(system, 3); 34 | reg = qft3 * reg; // multi-qubit gate application 35 | ``` 36 | 37 | ## Notes 38 | - `Controlled(inner)` constructs block matrix diag(I, inner). Caller handles qubit ordering. 39 | - `QuantumFourierTransformGate` returns full NxN matrix (N = 2^registerLength) using canonical definition. 40 | - Advanced optimised decompositions still available via algorithmic APIs; this factory surfaces monolithic unitary. 41 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/ParanoiaConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | namespace PositronicVariables.Transactions 4 | { 5 | /// 6 | /// Runtime configuration for paranoia diagnostics and global fallback. 7 | /// Disabled by default; enable in CI or stress runs. 8 | /// 9 | public static class ParanoiaConfig 10 | { 11 | /// 12 | /// Enable additional assertions and lock acquisition diagnostics. 13 | /// 14 | public static volatile bool EnableParanoia; 15 | 16 | /// 17 | /// Enable global serialization fallback when contention is extreme. 18 | /// 19 | public static volatile bool EnableGlobalFallback; 20 | 21 | /// 22 | /// Threshold for (Retries + Aborts) to trigger fallback. 23 | /// 24 | public static long AbortRetryThreshold = long.MaxValue; 25 | 26 | /// 27 | /// Indicates if fallback is currently active. 28 | /// 29 | public static volatile bool FallbackActive; 30 | 31 | /// 32 | /// Optional stack traces recorded per TxId on lock acquisition (paranoia mode). 33 | /// 34 | public static readonly ConcurrentDictionary LockStacks = new(); 35 | 36 | internal static void Reset() 37 | { 38 | FallbackActive = false; 39 | LockStacks.Clear(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /QuantumBenchmarks/Benchmarks/GateQueueOptimizationBenchmarks.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using QuantumSuperposition.Systems; 3 | using QuantumSuperposition.QuantumSoup; 4 | using QuantumSuperposition.Utilities; 5 | using System.Numerics; 6 | 7 | namespace QuantumBenchmarks.Benchmarks; 8 | 9 | [MemoryDiagnoser] 10 | [RankColumn] 11 | public class GateQueueOptimizationBenchmarks 12 | { 13 | private QuantumSystem _system = null!; 14 | private Complex[,] _hadamard; 15 | 16 | [Params(8, 16)] public int QubitCount; 17 | 18 | [GlobalSetup] 19 | public void Setup() 20 | { 21 | _system = new QuantumSystem(); 22 | var qubits = Enumerable.Range(0, QubitCount) 23 | .Select(i => new QuBit(_system, new[] { i }).WithWeights(new Dictionary { { 0, 1.0 }, { 1, 1.0 } }, true)) 24 | .ToArray(); 25 | _system.SetFromTensorProduct(false, qubits); 26 | _hadamard = QuantumGates.Hadamard; 27 | } 28 | 29 | [Benchmark] 30 | public void QueueAndProcessGates() 31 | { 32 | // Add a pattern of gates including cancellations (H then H) to test optimisation. 33 | for (int round = 0; round < 5; round++) 34 | { 35 | for (int i = 0; i < QubitCount; i++) 36 | { 37 | _system.ApplySingleQubitGate(i, _hadamard, "H"); 38 | _system.ApplySingleQubitGate(i, _hadamard, "H"); // should cancel in optimisation 39 | } 40 | } 41 | _system.ProcessGateQueue(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Timeline/TimelineReplaceOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Logging; 2 | using PositronicVariables.Variables; 3 | using QuantumSuperposition.QuantumSoup; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Engine.Timeline 9 | { 10 | /// 11 | /// Operation that reverts the timeline to a previous snapshot after a Replace. 12 | /// 13 | public class TimelineReplaceOperation : IOperation 14 | where T : IComparable 15 | { 16 | private readonly List> _backupTimeline; 17 | 18 | public PositronicVariable Variable { get; } 19 | internal QuBit ReplacedSlice => _backupTimeline[^1]; 20 | 21 | public string OperationName => "TimelineReplace"; 22 | 23 | public TimelineReplaceOperation(PositronicVariable variable, List> backupTimeline) 24 | { 25 | Variable = variable; 26 | _backupTimeline = backupTimeline 27 | .Select(q => new QuBit(q.ToCollapsedValues().ToArray())) 28 | .ToList(); 29 | } 30 | 31 | public void Undo() 32 | { 33 | if (_backupTimeline.Count == 0) 34 | { 35 | return; 36 | } 37 | 38 | Variable.ReplaceForwardHistoryWith(_backupTimeline[0]); 39 | for (int i = 1; i < _backupTimeline.Count; i++) 40 | { 41 | Variable.AppendFromReverse(_backupTimeline[i]); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/MultiplicationOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | /// 11 | /// Timey-wimey stuff. Multiplication in one direction becomes division in the other. 12 | /// 13 | /// 14 | public class MultiplicationOperation(PositronicVariable variable, T multiplier) : IReversibleSnapshotOperation 15 | where T : IComparable 16 | { 17 | public PositronicVariable Variable { get; } = variable; 18 | public T Original { get; } = variable.GetCurrentQBit().ToCollapsedValues().First(); 19 | 20 | public string OperationName => $"Multiplication by {multiplier}"; 21 | 22 | /// 23 | /// When time goes backwards the multiplication becomes a division. 24 | /// 25 | /// 26 | /// 27 | public T ApplyInverse(T result) 28 | { 29 | return Arithmetic.Divide(result, multiplier); 30 | } 31 | 32 | /// 33 | /// Otherwise we get out the multiplication table. 34 | /// 35 | /// 36 | /// 37 | public T ApplyForward(T value) 38 | { 39 | return Arithmetic.Multiply(value, multiplier); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/IntOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | 4 | namespace QuantumSuperposition.Operators 5 | { 6 | /// 7 | /// Like a gym trainer, but for ints. Does the usual heavy lifting. 8 | /// 9 | public class IntOperators : IQuantumOperators 10 | { 11 | public int Add(int a, int b) 12 | { 13 | return a + b; 14 | } 15 | 16 | public int Subtract(int a, int b) 17 | { 18 | return a - b; 19 | } 20 | 21 | public int Multiply(int a, int b) 22 | { 23 | return a * b; 24 | } 25 | 26 | public int Divide(int a, int b) 27 | { 28 | return a / b; 29 | } 30 | 31 | public int Mod(int a, int b) 32 | { 33 | return a % b; 34 | } 35 | 36 | public bool GreaterThan(int a, int b) 37 | { 38 | return a > b; 39 | } 40 | 41 | public bool GreaterThanOrEqual(int a, int b) 42 | { 43 | return a >= b; 44 | } 45 | 46 | public bool LessThan(int a, int b) 47 | { 48 | return a < b; 49 | } 50 | 51 | public bool LessThanOrEqual(int a, int b) 52 | { 53 | return a <= b; 54 | } 55 | 56 | public bool Equal(int a, int b) 57 | { 58 | return a == b; 59 | } 60 | 61 | public bool NotEqual(int a, int b) 62 | { 63 | return a != b; 64 | } 65 | 66 | public bool IsAddCommutative => true; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/LongOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// The long-hauler. Bigger numbers, bigger dreams. 7 | /// 8 | public class LongOperators : IQuantumOperators 9 | { 10 | public long Add(long a, long b) 11 | { 12 | return a + b; 13 | } 14 | 15 | public long Subtract(long a, long b) 16 | { 17 | return a - b; 18 | } 19 | 20 | public long Multiply(long a, long b) 21 | { 22 | return a * b; 23 | } 24 | 25 | public long Divide(long a, long b) 26 | { 27 | return a / b; 28 | } 29 | 30 | public long Mod(long a, long b) 31 | { 32 | return a % b; 33 | } 34 | 35 | public bool GreaterThan(long a, long b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(long a, long b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(long a, long b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(long a, long b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(long a, long b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(long a, long b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/UIntOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// The reliable middle manager of integers. Unsigned, unbiased. 7 | /// 8 | public class UIntOperators : IQuantumOperators 9 | { 10 | public uint Add(uint a, uint b) 11 | { 12 | return a + b; 13 | } 14 | 15 | public uint Subtract(uint a, uint b) 16 | { 17 | return a - b; 18 | } 19 | 20 | public uint Multiply(uint a, uint b) 21 | { 22 | return a * b; 23 | } 24 | 25 | public uint Divide(uint a, uint b) 26 | { 27 | return a / b; 28 | } 29 | 30 | public uint Mod(uint a, uint b) 31 | { 32 | return a % b; 33 | } 34 | 35 | public bool GreaterThan(uint a, uint b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(uint a, uint b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(uint a, uint b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(uint a, uint b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(uint a, uint b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(uint a, uint b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/CanonicalStates.md: -------------------------------------------------------------------------------- 1 | # Canonical Quantum States 2 | 3 | Built-in helpers for constructing common multi-qubit states directly on `QuantumRegister`. 4 | 5 | ## Factories 6 | 7 | ```csharp 8 | public static QuantumRegister EPRPair(QuantumSystem system); 9 | public static QuantumRegister WState(QuantumSystem system, int length = 3); 10 | public static QuantumRegister GHZState(QuantumSystem system, int length = 3); 11 | ``` 12 | 13 | ## EPR Pair (Bell State) 14 | Creates a 2-qubit state: (|00> + |11>) / sqrt(2) 15 | 16 | ```csharp 17 | var system = new QuantumSystem(); 18 | var bell = QuantumRegister.EPRPair(system); 19 | ``` 20 | 21 | ## W State 22 | Equal superposition of all basis states with Hamming weight 1. 23 | For n qubits: (|100...0> + |010...0> + ... + |0...001>) / sqrt(n) 24 | 25 | ```csharp 26 | var system = new QuantumSystem(); 27 | var w3 = QuantumRegister.WState(system); // length = 3 28 | var w5 = QuantumRegister.WState(system, length: 5); 29 | ``` 30 | 31 | ## GHZ State 32 | n-qubit entangled state: (|00...0> + |11...1>) / sqrt(2) 33 | 34 | ```csharp 35 | var system = new QuantumSystem(); 36 | var ghz = QuantumRegister.GHZState(system); // length = 3 37 | var ghz4 = QuantumRegister.GHZState(system, length: 4); 38 | ``` 39 | 40 | ## Entanglement Labels 41 | Each factory links qubits into an entanglement group: 42 | - `EPRPair_A` 43 | - `WState_A` 44 | - `GHZState_A` 45 | 46 | Use `system.Entanglement` diagnostics to inspect linkage. 47 | 48 | ## Notes 49 | - Length must be >= 2 for W and GHZ states. 50 | - Factories overwrite current system amplitudes. 51 | - Returned register spans indices [0..length-1] in creation order. 52 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/ULongOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Thinks long thoughts, never says a negative word. 7 | /// 8 | public class ULongOperators : IQuantumOperators 9 | { 10 | public ulong Add(ulong a, ulong b) 11 | { 12 | return a + b; 13 | } 14 | 15 | public ulong Subtract(ulong a, ulong b) 16 | { 17 | return a - b; 18 | } 19 | 20 | public ulong Multiply(ulong a, ulong b) 21 | { 22 | return a * b; 23 | } 24 | 25 | public ulong Divide(ulong a, ulong b) 26 | { 27 | return a / b; 28 | } 29 | 30 | public ulong Mod(ulong a, ulong b) 31 | { 32 | return a % b; 33 | } 34 | 35 | public bool GreaterThan(ulong a, ulong b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(ulong a, ulong b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(ulong a, ulong b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(ulong a, ulong b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(ulong a, ulong b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(ulong a, ulong b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/ByteOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Small, but fierce. Bites at 0xFF strength. 7 | /// 8 | public class ByteOperators : IQuantumOperators 9 | { 10 | public byte Add(byte a, byte b) 11 | { 12 | return (byte)(a + b); 13 | } 14 | 15 | public byte Subtract(byte a, byte b) 16 | { 17 | return (byte)(a - b); 18 | } 19 | 20 | public byte Multiply(byte a, byte b) 21 | { 22 | return (byte)(a * b); 23 | } 24 | 25 | public byte Divide(byte a, byte b) 26 | { 27 | return (byte)(a / b); 28 | } 29 | 30 | public byte Mod(byte a, byte b) 31 | { 32 | return (byte)(a % b); 33 | } 34 | 35 | public bool GreaterThan(byte a, byte b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(byte a, byte b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(byte a, byte b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(byte a, byte b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(byte a, byte b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(byte a, byte b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/CharOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Because sometimes you just need to compare angry letters. 7 | /// 8 | public class CharOperators : IQuantumOperators 9 | { 10 | public char Add(char a, char b) 11 | { 12 | return (char)(a + b); 13 | } 14 | 15 | public char Subtract(char a, char b) 16 | { 17 | return (char)(a - b); 18 | } 19 | 20 | public char Multiply(char a, char b) 21 | { 22 | return (char)(a * b); 23 | } 24 | 25 | public char Divide(char a, char b) 26 | { 27 | return (char)(a / b); 28 | } 29 | 30 | public char Mod(char a, char b) 31 | { 32 | return (char)(a % b); 33 | } 34 | 35 | public bool GreaterThan(char a, char b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(char a, char b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(char a, char b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(char a, char b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(char a, char b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(char a, char b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PositronicVariables/Api/AntiVal.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Hosting; 2 | using PositronicVariables.DependencyInjection; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | 7 | public static class AntiVal 8 | { 9 | /// 10 | /// This method hunts down an existing PositronicVariable of type T in the current PositronicAmbient. If it finds one, it returns it. If not, it conjures up a new one, ensuring that your quest for quantum variables is never in vain. 11 | /// 12 | /// 13 | /// 14 | public static PositronicVariable GetOrCreate() 15 | where T : IComparable 16 | { 17 | if (!PositronicAmbient.IsInitialized) 18 | { 19 | InitialiseDefaultRuntime(); 20 | } 21 | 22 | PositronicVariable v = PositronicVariable.GetOrCreate(PositronicAmbient.Current); 23 | 24 | return v; 25 | } 26 | 27 | private static bool PositronicAmbientIsUninitialized() 28 | { 29 | return PositronicAmbient.Current == null; 30 | } 31 | 32 | /// 33 | /// If the runtime hasn't been initialized, we gently whisper it into existence like a haunted lullaby. 34 | /// 35 | private static void InitialiseDefaultRuntime() 36 | { 37 | if (PositronicAmbient.IsInitialized) 38 | { 39 | return; 40 | } 41 | 42 | IHostBuilder hostBuilder = Host.CreateDefaultBuilder() 43 | .ConfigureServices(services => services.AddPositronicRuntime()); 44 | PositronicAmbient.InitialiseWith(hostBuilder); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/ShortOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Short, fast, and to the point. No tall tales here. 7 | /// 8 | public class ShortOperators : IQuantumOperators 9 | { 10 | public short Add(short a, short b) 11 | { 12 | return (short)(a + b); 13 | } 14 | 15 | public short Subtract(short a, short b) 16 | { 17 | return (short)(a - b); 18 | } 19 | 20 | public short Multiply(short a, short b) 21 | { 22 | return (short)(a * b); 23 | } 24 | 25 | public short Divide(short a, short b) 26 | { 27 | return (short)(a / b); 28 | } 29 | 30 | public short Mod(short a, short b) 31 | { 32 | return (short)(a % b); 33 | } 34 | 35 | public bool GreaterThan(short a, short b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(short a, short b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(short a, short b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(short a, short b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(short a, short b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(short a, short b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/SByteOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Like Byte, but occasionally broods in the shadows of negativity. 7 | /// 8 | public class SByteOperators : IQuantumOperators 9 | { 10 | public sbyte Add(sbyte a, sbyte b) 11 | { 12 | return (sbyte)(a + b); 13 | } 14 | 15 | public sbyte Subtract(sbyte a, sbyte b) 16 | { 17 | return (sbyte)(a - b); 18 | } 19 | 20 | public sbyte Multiply(sbyte a, sbyte b) 21 | { 22 | return (sbyte)(a * b); 23 | } 24 | 25 | public sbyte Divide(sbyte a, sbyte b) 26 | { 27 | return (sbyte)(a / b); 28 | } 29 | 30 | public sbyte Mod(sbyte a, sbyte b) 31 | { 32 | return (sbyte)(a % b); 33 | } 34 | 35 | public bool GreaterThan(sbyte a, sbyte b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(sbyte a, sbyte b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(sbyte a, sbyte b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(sbyte a, sbyte b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(sbyte a, sbyte b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(sbyte a, sbyte b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/FloatOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Like a gym trainer, but lighter. Lifts floats instead of ints. 7 | /// May skip leg day, but compensates with decimals. 8 | /// 9 | public class FloatOperators : IQuantumOperators 10 | { 11 | public float Add(float a, float b) 12 | { 13 | return a + b; 14 | } 15 | 16 | public float Subtract(float a, float b) 17 | { 18 | return a - b; 19 | } 20 | 21 | public float Multiply(float a, float b) 22 | { 23 | return a * b; 24 | } 25 | 26 | public float Divide(float a, float b) 27 | { 28 | return a / b; 29 | } 30 | 31 | public float Mod(float a, float b) 32 | { 33 | return a % b; 34 | } 35 | 36 | public bool GreaterThan(float a, float b) 37 | { 38 | return a > b; 39 | } 40 | 41 | public bool GreaterThanOrEqual(float a, float b) 42 | { 43 | return a >= b; 44 | } 45 | 46 | public bool LessThan(float a, float b) 47 | { 48 | return a < b; 49 | } 50 | 51 | public bool LessThanOrEqual(float a, float b) 52 | { 53 | return a <= b; 54 | } 55 | 56 | public bool Equal(float a, float b) 57 | { 58 | return a == b; 59 | } 60 | 61 | public bool NotEqual(float a, float b) 62 | { 63 | return a != b; 64 | } 65 | 66 | public bool IsAddCommutative => true; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/UShortOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Unsigned and proud. Short, but always positive. 7 | /// 8 | public class UShortOperators : IQuantumOperators 9 | { 10 | public ushort Add(ushort a, ushort b) 11 | { 12 | return (ushort)(a + b); 13 | } 14 | 15 | public ushort Subtract(ushort a, ushort b) 16 | { 17 | return (ushort)(a - b); 18 | } 19 | 20 | public ushort Multiply(ushort a, ushort b) 21 | { 22 | return (ushort)(a * b); 23 | } 24 | 25 | public ushort Divide(ushort a, ushort b) 26 | { 27 | return (ushort)(a / b); 28 | } 29 | 30 | public ushort Mod(ushort a, ushort b) 31 | { 32 | return (ushort)(a % b); 33 | } 34 | 35 | public bool GreaterThan(ushort a, ushort b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(ushort a, ushort b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(ushort a, ushort b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(ushort a, ushort b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(ushort a, ushort b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(ushort a, ushort b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/DoubleOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Float’s overachieving big sibling. 7 | /// Handles double the precision, double the existential crises. 8 | /// 9 | public class DoubleOperators : IQuantumOperators 10 | { 11 | public double Add(double a, double b) 12 | { 13 | return a + b; 14 | } 15 | 16 | public double Subtract(double a, double b) 17 | { 18 | return a - b; 19 | } 20 | 21 | public double Multiply(double a, double b) 22 | { 23 | return a * b; 24 | } 25 | 26 | public double Divide(double a, double b) 27 | { 28 | return a / b; 29 | } 30 | 31 | public double Mod(double a, double b) 32 | { 33 | return a % b; 34 | } 35 | 36 | public bool GreaterThan(double a, double b) 37 | { 38 | return a > b; 39 | } 40 | 41 | public bool GreaterThanOrEqual(double a, double b) 42 | { 43 | return a >= b; 44 | } 45 | 46 | public bool LessThan(double a, double b) 47 | { 48 | return a < b; 49 | } 50 | 51 | public bool LessThanOrEqual(double a, double b) 52 | { 53 | return a <= b; 54 | } 55 | 56 | public bool Equal(double a, double b) 57 | { 58 | return a == b; 59 | } 60 | 61 | public bool NotEqual(double a, double b) 62 | { 63 | return a != b; 64 | } 65 | 66 | public bool IsAddCommutative => true; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/DecimalOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// For when float and double just aren’t serious enough about their financial responsibilities. 7 | /// 8 | public class DecimalOperators : IQuantumOperators 9 | { 10 | public decimal Add(decimal a, decimal b) 11 | { 12 | return a + b; 13 | } 14 | 15 | public decimal Subtract(decimal a, decimal b) 16 | { 17 | return a - b; 18 | } 19 | 20 | public decimal Multiply(decimal a, decimal b) 21 | { 22 | return a * b; 23 | } 24 | 25 | public decimal Divide(decimal a, decimal b) 26 | { 27 | return a / b; 28 | } 29 | 30 | public decimal Mod(decimal a, decimal b) 31 | { 32 | return a % b; 33 | } 34 | 35 | public bool GreaterThan(decimal a, decimal b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(decimal a, decimal b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(decimal a, decimal b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(decimal a, decimal b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(decimal a, decimal b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(decimal a, decimal b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/DivisionOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public class DivisionOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | private readonly T _divisor; 15 | private readonly IPositronicRuntime _rt; 16 | public T Original { get; } 17 | 18 | public string OperationName => $"Division by {_divisor}"; 19 | 20 | public DivisionOperation(PositronicVariable variable, T divisor, IPositronicRuntime rt) 21 | { 22 | Variable = variable; 23 | _divisor = divisor; 24 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 25 | _rt = rt; 26 | } 27 | /// 28 | /// When time goes backwards the division becomes a multiplication. 29 | /// 30 | /// 31 | /// 32 | public T ApplyInverse(T result) 33 | { 34 | return Arithmetic.Multiply(result, _divisor); 35 | } 36 | 37 | /// 38 | /// Otherwise we try and remember what long division was like, something to do with shifting one column to the right and then I get confused. 39 | /// 40 | /// 41 | /// 42 | public T ApplyForward(T value) 43 | { 44 | return Arithmetic.Divide(value, _divisor); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/TimeSpanOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Because not every span of time feels the same, but math still applies. 7 | /// 8 | public class TimeSpanOperators : IQuantumOperators 9 | { 10 | public TimeSpan Add(TimeSpan a, TimeSpan b) 11 | { 12 | return a + b; 13 | } 14 | 15 | public TimeSpan Subtract(TimeSpan a, TimeSpan b) 16 | { 17 | return a - b; 18 | } 19 | 20 | public TimeSpan Multiply(TimeSpan a, TimeSpan b) 21 | { 22 | return new TimeSpan(a.Ticks * b.Ticks); 23 | } 24 | 25 | public TimeSpan Divide(TimeSpan a, TimeSpan b) 26 | { 27 | return new TimeSpan(a.Ticks / b.Ticks); 28 | } 29 | 30 | public TimeSpan Mod(TimeSpan a, TimeSpan b) 31 | { 32 | return new TimeSpan(a.Ticks % b.Ticks); 33 | } 34 | 35 | public bool GreaterThan(TimeSpan a, TimeSpan b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(TimeSpan a, TimeSpan b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(TimeSpan a, TimeSpan b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(TimeSpan a, TimeSpan b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(TimeSpan a, TimeSpan b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(TimeSpan a, TimeSpan b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/DivisionReversedOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | public class DivisionReversedOperation : IReversibleSnapshotOperation 11 | where T : IComparable 12 | { 13 | public PositronicVariable Variable { get; } 14 | private readonly T _numerator; 15 | private readonly IPositronicRuntime _rt; 16 | public T Original { get; } 17 | 18 | public string OperationName => $"DivisionReversed with numerator {_numerator}"; 19 | 20 | public DivisionReversedOperation(PositronicVariable variable, T numerator, IPositronicRuntime rt) 21 | { 22 | Variable = variable; 23 | _numerator = numerator; 24 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 25 | _rt = rt; 26 | } 27 | 28 | /// 29 | /// When time goes backwards the division becomes a multiplication. 30 | /// 31 | /// 32 | /// 33 | public T ApplyInverse(T result) 34 | { 35 | return Arithmetic.Divide(_numerator, result); 36 | } 37 | 38 | /// 39 | /// Otherwise we try and remember what long division was like, something to do with shifting one column to the right and then I get confused. 40 | /// 41 | /// 42 | /// 43 | public T ApplyForward(T value) 44 | { 45 | return Arithmetic.Divide(_numerator, value); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Timeline/TimelineAppendOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Logging; 2 | using PositronicVariables.Variables; 3 | using QuantumSuperposition.QuantumSoup; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Engine.Timeline 9 | { 10 | /// 11 | /// Yanks the timeline back to a simpler time, before it made any questionable life choices. 12 | /// 13 | public class TimelineAppendOperation : IOperation 14 | where T : IComparable 15 | { 16 | private readonly List> _backupTimeline; 17 | public PositronicVariable Variable { get; } 18 | public QuBit AddedSlice { get; } 19 | 20 | public string OperationName => "TimelineAppend"; 21 | 22 | public TimelineAppendOperation(PositronicVariable variable, List> backupTimeline, QuBit added) 23 | { 24 | Variable = variable; 25 | // Make a safe copy so we can fully restore: 26 | _backupTimeline = backupTimeline 27 | .Select(q => new QuBit(q.ToCollapsedValues().ToArray())) 28 | .ToList(); 29 | AddedSlice = added; 30 | 31 | } 32 | 33 | public void Undo() 34 | { 35 | if (_backupTimeline.Count == 0) 36 | { 37 | return; 38 | } 39 | 40 | // Replace the existing forward history with the first backup slice 41 | Variable.ReplaceForwardHistoryWith(_backupTimeline[0]); 42 | 43 | // Then append the remaining slices using the reverse/append helper 44 | for (int i = 1; i < _backupTimeline.Count; i++) 45 | { 46 | Variable.AppendFromReverse(_backupTimeline[i]); 47 | } 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/AdditionOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | namespace PositronicVariables.Operations 8 | { 9 | /// 10 | /// Multiversal maths isn't as hard as it looks 11 | /// 12 | /// 13 | public class AdditionOperation : IReversibleSnapshotOperation 14 | where T : IComparable 15 | { 16 | public PositronicVariable Variable { get; } 17 | public T Addend { get; } 18 | public T Original { get; } 19 | 20 | public string OperationName => $"Addition of {Addend}"; 21 | private readonly IPositronicRuntime _rt; 22 | 23 | public AdditionOperation(PositronicVariable variable, T addend, IPositronicRuntime rt) 24 | { 25 | Variable = variable; 26 | Addend = addend; 27 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); // snapshot 28 | _rt = rt; 29 | } 30 | 31 | /// 32 | /// When time goes backwards the addition becomes a subtraction. 33 | /// 34 | /// 35 | /// 36 | public T ApplyInverse(T result) 37 | { 38 | return Arithmetic.Subtract(result, Addend); 39 | } 40 | 41 | /// 42 | /// And going forwards is just the regular old addition we all know and love. 43 | /// 44 | /// 45 | /// 46 | public T ApplyForward(T result) 47 | { 48 | return Arithmetic.Add(result, Addend); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/BooleanOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Operators for boolean values. Because why not? 7 | /// 8 | public class BooleanOperators : IQuantumOperators 9 | { 10 | public bool Add(bool a, bool b) 11 | { 12 | return a || b; // logical OR 13 | } 14 | 15 | public bool Subtract(bool a, bool b) 16 | { 17 | return a && !b; // arbitrary definition 18 | } 19 | 20 | public bool Multiply(bool a, bool b) 21 | { 22 | return a && b; // logical AND 23 | } 24 | 25 | public bool Divide(bool a, bool b) 26 | { 27 | throw new NotSupportedException("Division not supported for booleans, why are you trying to divide truth?."); 28 | } 29 | 30 | public bool Mod(bool a, bool b) 31 | { 32 | throw new NotSupportedException("I don't even know what that could possibly mean."); 33 | } 34 | 35 | public bool GreaterThan(bool a, bool b) 36 | { 37 | return false; // not well-defined 38 | } 39 | 40 | public bool GreaterThanOrEqual(bool a, bool b) 41 | { 42 | return a == b; // or false 43 | } 44 | 45 | public bool LessThan(bool a, bool b) 46 | { 47 | return false; 48 | } 49 | 50 | public bool LessThanOrEqual(bool a, bool b) 51 | { 52 | return a == b; 53 | } 54 | 55 | public bool Equal(bool a, bool b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(bool a, bool b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => true; 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/RegretScribe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using PositronicVariables.Transactions; 3 | using PositronicVariables.Variables; 4 | 5 | namespace PositronicVariables.Engine.Logging 6 | { 7 | public class RegretScribe : IOperationLogHandler where T : IComparable 8 | { 9 | private static ILedgerSink s_sink = new LedgerSink(); 10 | public static ILedgerSink Sink 11 | { 12 | get => s_sink; 13 | set => s_sink = value ?? throw new ArgumentNullException(nameof(value)); 14 | } 15 | 16 | public bool SawForwardWrite { get; set; } 17 | public void Record(IOperation op) 18 | { 19 | // During the convergence loop, preserve immediate ledger ordering 20 | if (PositronicVariable.InConvergenceLoop) 21 | { 22 | s_sink.Append(op, Guid.NewGuid()); 23 | return; 24 | } 25 | 26 | var tx = TransactionV2.Current; 27 | if (tx != null) 28 | { 29 | tx.BufferLedgerEntry(op); 30 | } 31 | else 32 | { 33 | // outside tx: append immediately with unique id 34 | s_sink.Append(op, Guid.NewGuid()); 35 | } 36 | } 37 | 38 | /// 39 | /// Undo all operations since the last forward half-cycle marker, a half-cycle being a forward pass followed by a reverse pass, (the 'to' to a Merlin 'fro') 40 | /// 41 | public void UndoLastForwardCycle() 42 | { 43 | s_sink.ReverseLastOperations(); 44 | } 45 | 46 | /// 47 | /// Sometimes you just need to start fresh and pretend none of that ever happened. 48 | /// 49 | public void Clear() 50 | { 51 | s_sink.Clear(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/Transaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace PositronicVariables.Transactions 5 | { 6 | /// 7 | /// Coarse-grained transactional guard. Stage 1: serialize transactional bodies using a global lock. 8 | /// 9 | public sealed class Transaction : IDisposable 10 | { 11 | private static readonly object GlobalTxLock = new(); 12 | private bool _owns; 13 | private bool _completed; 14 | 15 | private Transaction(bool owns) 16 | { 17 | _owns = owns; 18 | } 19 | 20 | /// 21 | /// Begin a transaction by acquiring the global lock. 22 | /// 23 | public static Transaction Begin() 24 | { 25 | Monitor.Enter(GlobalTxLock); 26 | return new Transaction(owns: true); 27 | } 28 | 29 | /// 30 | /// Runs the body while holding the global transaction lock. 31 | /// 32 | public static void Run(Action body) 33 | { 34 | if (body == null) throw new ArgumentNullException(nameof(body)); 35 | using Transaction tx = Begin(); 36 | body(tx); 37 | tx.Commit(); 38 | } 39 | 40 | /// 41 | /// Commit the transaction and release the lock. 42 | /// 43 | public void Commit() 44 | { 45 | if (_completed) return; 46 | _completed = true; 47 | Release(); 48 | } 49 | 50 | private void Release() 51 | { 52 | if (_owns) 53 | { 54 | _owns = false; 55 | Monitor.Exit(GlobalTxLock); 56 | } 57 | } 58 | 59 | public void Dispose() 60 | { 61 | // If user forgot to Commit, treat Dispose as commit boundary and release the lock. 62 | Release(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/QuantumRegister.md: -------------------------------------------------------------------------------- 1 | # QuantumRegister 2 | 3 | `QuantumRegister` is a lightweight value abstraction over one or more qubit indices inside a `QuantumSystem`. 4 | It lets you treat a slice of the global wavefunction as a register you can: 5 | 6 | - Construct from existing `QuBit` (or `PhysicsQubit`) instances 7 | - Construct from an integer value (basis state) 8 | - Construct from an explicit complex amplitude vector 9 | - Partially observe (collapse) just those qubits 10 | - Decode integer values from bit ranges 11 | 12 | ## Constructors 13 | 14 | ```csharp 15 | // From qubits already bound to a system 16 | var system = new QuantumSystem(); 17 | var q0 = new QuBit(system, new[] { 0 }); 18 | var q1 = new QuBit(system, new[] { 1 }); 19 | var reg = new QuantumRegister(q0, q1); 20 | 21 | // From integer value (populates amplitudes as a single basis state) 22 | var regConst = QuantumRegister.FromInt(value: 3, bits: 2, system); 23 | 24 | // From explicit amplitude vector (length must be a power of two) 25 | var regAmp = QuantumRegister.FromAmplitudes(new[] { Complex.One/Math.Sqrt(2), Complex.One/Math.Sqrt(2) }, system); 26 | ``` 27 | 28 | ## Collapse 29 | 30 | ```csharp 31 | // Collapse only this register's qubits 32 | int[] measuredBits = reg.Collapse(); 33 | ``` 34 | 35 | ## Value Extraction 36 | 37 | ```csharp 38 | // Decode full register value 39 | int fullValue = reg.GetValue(); 40 | // Decode lower 3 bits (offset 0, length 3) 41 | int low3 = reg.GetValue(offset: 0, length: 3); 42 | // Decode bits [2..4) 43 | int mid = reg.GetValue(offset: 2, length: 2); 44 | ``` 45 | 46 | Internally this uses `QuantumAlgorithms.BitsToIndex` and falls back to `PartialObserve` if the system has not yet fully collapsed. 47 | 48 | ## Notes 49 | 50 | - Creating from amplitudes or integer value overwrites system amplitudes for the involved qubits 51 | - `Collapse()` locks underlying qubits to prevent accidental mutation after measurement 52 | - Supports disjoint index sets. Indices are stored sorted 53 | 54 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/SubtractionReversedOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | /// 11 | /// If this looks a lot like calling addition something else, that's because it is. 12 | /// 13 | /// 14 | public class SubtractionReversedOperation : IReversibleSnapshotOperation 15 | where T : IComparable 16 | { 17 | public PositronicVariable Variable { get; } 18 | private readonly T _minuend; 19 | private readonly IPositronicRuntime _rt; 20 | public T Original { get; } 21 | 22 | public string OperationName => $"SubtractionReversed with minuend {_minuend}"; 23 | 24 | 25 | public SubtractionReversedOperation(PositronicVariable variable, T minuend, IPositronicRuntime rt) 26 | { 27 | Variable = variable; 28 | _minuend = minuend; 29 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 30 | _rt = rt; 31 | } 32 | 33 | /// 34 | /// It's like regular subtraction, but backwards. So we reverse it by subtracting from the minuend. 35 | /// 36 | /// 37 | /// 38 | public T ApplyInverse(T result) 39 | { 40 | return Arithmetic.Subtract(_minuend, result); 41 | } 42 | 43 | /// 44 | /// And going forwards is just the regular old subtraction we all know and love. 45 | /// 46 | /// 47 | /// 48 | public T ApplyForward(T value) 49 | { 50 | return Arithmetic.Subtract(_minuend, value); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/GuidOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// The sacred scrolls of unique identifiers. Not designed for arithmetic, just judgement. 7 | /// 8 | public class GuidOperators : IQuantumOperators 9 | { 10 | public Guid Add(Guid a, Guid b) 11 | { 12 | throw new NotSupportedException("Adding GUIDs is heresy."); 13 | } 14 | 15 | public Guid Subtract(Guid a, Guid b) 16 | { 17 | throw new NotSupportedException("Subtracting GUIDs fractures spacetime."); 18 | } 19 | 20 | public Guid Multiply(Guid a, Guid b) 21 | { 22 | throw new NotSupportedException("GUID multiplication: please seek help."); 23 | } 24 | 25 | public Guid Divide(Guid a, Guid b) 26 | { 27 | throw new NotSupportedException("GUID division not even defined in the multiverse."); 28 | } 29 | 30 | public Guid Mod(Guid a, Guid b) 31 | { 32 | throw new NotSupportedException("Modulo on GUIDs? What dark ritual is this?"); 33 | } 34 | 35 | public bool GreaterThan(Guid a, Guid b) 36 | { 37 | return a.CompareTo(b) > 0; 38 | } 39 | 40 | public bool GreaterThanOrEqual(Guid a, Guid b) 41 | { 42 | return a.CompareTo(b) >= 0; 43 | } 44 | 45 | public bool LessThan(Guid a, Guid b) 46 | { 47 | return a.CompareTo(b) < 0; 48 | } 49 | 50 | public bool LessThanOrEqual(Guid a, Guid b) 51 | { 52 | return a.CompareTo(b) <= 0; 53 | } 54 | 55 | public bool Equal(Guid a, Guid b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(Guid a, Guid b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => false; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/BasisMapping.md: -------------------------------------------------------------------------------- 1 | # Basis mapping examples 2 | 3 | This tiny page shows how to map non-primitive types into the computational basis when calling `QuantumSystem.SetFromTensorProduct`. 4 | 5 | Keep in mind: the system's global wavefunction uses integer basis indices (0,1,2,...). If your domain type is not `int` or `bool` (or an `enum`), pass a `Func` mapper that converts your value into the desired basis integer. 6 | 7 | ## Example: mapping a small struct to basis integers 8 | 9 | Suppose you have a tiny struct representing two bits: 10 | 11 | ```csharp 12 | public readonly struct BitPair 13 | { 14 | public readonly int High; // 0 or 1 15 | public readonly int Low; // 0 or 1 16 | public BitPair(int high, int low) { High = high; Low = low; } 17 | } 18 | 19 | // Build two local qubits of BitPair 20 | var qx = new QuBit(new[] { new BitPair(0,0), new BitPair(0,1), new BitPair(1,0) }); 21 | var qy = new QuBit(new[] { new BitPair(0,0), new BitPair(1,1) }); 22 | 23 | // Mapper: convert BitPair to an integer (high<<1 | low) 24 | int MapBitPair(BitPair bp) => (bp.High << 1) | bp.Low; 25 | 26 | var system = new QuantumSystem(); 27 | 28 | // Use the mapper when creating the system wavefunction 29 | system.SetFromTensorProduct(propagateCollapse: false, mapToBasis: MapBitPair, qx, qy); 30 | 31 | // The system's Amplitudes keys are now integer arrays representing each mapped basis state. 32 | foreach (var key in system.Amplitudes.Keys) 33 | { 34 | // key is an int[] of mapped values (one per qubit) 35 | Console.WriteLine($"basis: [{string.Join(',', key)}]"); 36 | } 37 | ``` 38 | 39 | Notes 40 | - The mapper is called for every element of each qubit's state when building the tensor product. 41 | - Default mappers are provided for `int`, `bool`, and `enum` (enums use `Convert.ToInt32`). 42 | - If you pass a custom mapper, make sure it maps to a small contiguous set of integers that suit your intended computational basis. 43 | 44 | Have fun mapping tiny types to big quantum dreams. -------------------------------------------------------------------------------- /PositronicVariables/Operations/SubtractionOperation.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Maths; 2 | using PositronicVariables.Operations.Interfaces; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using System; 6 | using System.Linq; 7 | 8 | namespace PositronicVariables.Operations 9 | { 10 | /// 11 | /// If you walk backwards by a certain amount, you can reverse the effect of having walked forwards by that same amount. 12 | /// 13 | /// 14 | public class SubtractionOperation : IReversibleSnapshotOperation 15 | where T : IComparable 16 | { 17 | public PositronicVariable Variable { get; } 18 | private readonly T _subtrahend; 19 | public T Original { get; } 20 | 21 | public string OperationName => $"Subtraction of {_subtrahend}"; 22 | private readonly IPositronicRuntime _rt; 23 | 24 | public SubtractionOperation(PositronicVariable variable, T subtrahend, IPositronicRuntime rt) 25 | { 26 | Variable = variable; 27 | _subtrahend = subtrahend; 28 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 29 | _rt = rt; 30 | } 31 | 32 | /// 33 | /// You get the idea, right? Subtracting is just adding the negative, so we reverse it by adding. 34 | /// 35 | /// 36 | /// 37 | public T ApplyInverse(T result) 38 | { 39 | return Arithmetic.Add(result, _subtrahend); 40 | } 41 | 42 | /// 43 | /// And going forwards is just the regular old subtraction we all know and love. 44 | /// 45 | /// 46 | /// 47 | public T ApplyForward(T value) 48 | { 49 | return Arithmetic.Subtract(value, _subtrahend); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/Hotspot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace PositronicVariables.Transactions 4 | { 5 | public readonly struct HotspotStats 6 | { 7 | public long TxId { get; } 8 | public double AbortRate { get; } 9 | public double AvgLockHoldTicks { get; } 10 | public long ValidationFailures { get; } 11 | public long WritesApplied { get; } 12 | 13 | public HotspotStats(long txId, double abortRate, double avgLockHoldTicks, long validationFailures, long writesApplied) 14 | { 15 | TxId = txId; 16 | AbortRate = abortRate; 17 | AvgLockHoldTicks = avgLockHoldTicks; 18 | ValidationFailures = validationFailures; 19 | WritesApplied = writesApplied; 20 | } 21 | } 22 | 23 | public interface IHotspotMitigationStrategy 24 | { 25 | bool ShouldMitigate(long tvarId, HotspotStats stats); 26 | void ApplyMitigation(long tvarId); 27 | } 28 | 29 | /// 30 | /// Simple single-writer promotion strategy: heuristic only, signalling layer decides enforcement. 31 | /// 32 | public sealed class SingleWriterPromotionStrategy : IHotspotMitigationStrategy 33 | { 34 | private readonly double _abortThreshold; 35 | private readonly double _lockTicksThreshold; 36 | 37 | public SingleWriterPromotionStrategy(double abortThreshold = 0.2, double lockTicksThreshold = 10_000) 38 | { 39 | _abortThreshold = abortThreshold; 40 | _lockTicksThreshold = lockTicksThreshold; 41 | } 42 | 43 | public bool ShouldMitigate(long tvarId, HotspotStats stats) 44 | { 45 | return stats.AbortRate > _abortThreshold && stats.AvgLockHoldTicks > _lockTicksThreshold; 46 | } 47 | 48 | public void ApplyMitigation(long tvarId) 49 | { 50 | // No-op placeholder: in a full implementation, coordinator would gate writes to single-writer. 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PositronicVariables/PositronicVariables.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net10.0 5 | 1.5.1 6 | PositronicVariables 7 | Paul Hutchinson 8 | Findon Software 9 | A time-looping variable container for quantum misfits and deterministic dreamers. 10 | quantum, convergence, simulation, time-loop, multiverse, neural, feedback 11 | https://github.com/hutchpd/QuantumSuperposition 12 | Unlicense 13 | https://github.com/hutchpd/QuantumSuperposition 14 | readme.md 15 | icon.png 16 | 1.5.1 17 | 1.5.1 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | <_Parameter1>PositronicTester 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/VersionOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Because someone, somewhere, always has a better version than you. 7 | /// 8 | public class VersionOperators : IQuantumOperators 9 | { 10 | public Version Add(Version a, Version b) 11 | { 12 | throw new NotSupportedException("Adding versions creates cursed timelines."); 13 | } 14 | 15 | public Version Subtract(Version a, Version b) 16 | { 17 | throw new NotSupportedException("Subtracting versions leads to feature regression."); 18 | } 19 | 20 | public Version Multiply(Version a, Version b) 21 | { 22 | throw new NotSupportedException("Multiplying versions causes time paradoxes."); 23 | } 24 | 25 | public Version Divide(Version a, Version b) 26 | { 27 | throw new NotSupportedException("Dividing versions destroys continuity."); 28 | } 29 | 30 | public Version Mod(Version a, Version b) 31 | { 32 | throw new NotSupportedException("Modulo on versions? See a therapist."); 33 | } 34 | 35 | public bool GreaterThan(Version a, Version b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(Version a, Version b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(Version a, Version b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(Version a, Version b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(Version a, Version b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(Version a, Version b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => false; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/DateTimeOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Time-travel not included. Handles temporal gymnastics for DateTime. 7 | /// 8 | public class DateTimeOperators : IQuantumOperators 9 | { 10 | public DateTime Add(DateTime a, DateTime b) 11 | { 12 | return a + (b - DateTime.MinValue); 13 | } 14 | 15 | public DateTime Subtract(DateTime a, DateTime b) 16 | { 17 | return a - (b - DateTime.MinValue); 18 | } 19 | 20 | public DateTime Multiply(DateTime a, DateTime b) 21 | { 22 | throw new NotSupportedException("Multiplying time is a sci-fi feature. Coming soon: never."); 23 | } 24 | 25 | public DateTime Divide(DateTime a, DateTime b) 26 | { 27 | throw new NotSupportedException("Dividing time breaks causality. Please refrain."); 28 | } 29 | 30 | public DateTime Mod(DateTime a, DateTime b) 31 | { 32 | throw new NotSupportedException("Modulo time? Are you *trying* to invent time loops?"); 33 | } 34 | 35 | public bool GreaterThan(DateTime a, DateTime b) 36 | { 37 | return a > b; 38 | } 39 | 40 | public bool GreaterThanOrEqual(DateTime a, DateTime b) 41 | { 42 | return a >= b; 43 | } 44 | 45 | public bool LessThan(DateTime a, DateTime b) 46 | { 47 | return a < b; 48 | } 49 | 50 | public bool LessThanOrEqual(DateTime a, DateTime b) 51 | { 52 | return a <= b; 53 | } 54 | 55 | public bool Equal(DateTime a, DateTime b) 56 | { 57 | return a == b; 58 | } 59 | 60 | public bool NotEqual(DateTime a, DateTime b) 61 | { 62 | return a != b; 63 | } 64 | 65 | public bool IsAddCommutative => false; // order of time addition matters, usually 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /QuantumSuperposition/QuantumSuperposition.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net10.0 5 | true 6 | enable 7 | enable 8 | QuantumSuperposition 9 | HutchPD 10 | FindonSoftware 11 | `QuantumSuperposition` is a .NET library that introduces quantum mechanics-like superpositions into C#. Inspired by concepts in quantum computing, it allows developers to work with scalar values as if they are in multiple states simultaneously. This library is useful for advanced logical and mathematical operations, where parallelism and state superposition can simplify complex computations. 12 | This is free and unencumbered software released into the public domain. 13 | https://github.com/hutchpd/QuantumSuperposition 14 | https://github.com/hutchpd/QuantumSuperposition 15 | readme.md 16 | Quantum;Superposition;Quantum Computing;Parallel Processing;Concurrency;Mathematics;Logic;Quantum Mechanics;C#;DotNet;Library;Algorithms;Prime Numbers;Factors;Mathematical Operations;Logical Operations;Eigenstates;Generics;Quantum Programming 17 | Unlicense 18 | 1.7.5.1 19 | 1.7.5.1 20 | icon.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/ComplexOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | using System.Numerics; 3 | 4 | namespace QuantumSuperposition.Operators 5 | { 6 | /// 7 | /// Like a quantum therapist, but for complex numbers. Helps them add, subtract, and multiply their feelings. 8 | /// 9 | public class ComplexOperators : IQuantumOperators 10 | { 11 | public Complex Add(Complex a, Complex b) 12 | { 13 | return a + b; 14 | } 15 | 16 | public Complex Subtract(Complex a, Complex b) 17 | { 18 | return a - b; 19 | } 20 | 21 | public Complex Multiply(Complex a, Complex b) 22 | { 23 | return a * b; 24 | } 25 | 26 | public Complex Divide(Complex a, Complex b) 27 | { 28 | return a / b; 29 | } 30 | 31 | // Modulo isn't mathematically defined for Complex, so we throw if attempted 32 | public Complex Mod(Complex a, Complex b) 33 | { 34 | throw new NotSupportedException("Modulus not supported for complex numbers."); 35 | } 36 | 37 | // Comparisons on complex numbers are ambiguous, but we’ll define some heuristics based on magnitude: 38 | public bool GreaterThan(Complex a, Complex b) 39 | { 40 | return a.Magnitude > b.Magnitude; 41 | } 42 | 43 | public bool GreaterThanOrEqual(Complex a, Complex b) 44 | { 45 | return a.Magnitude >= b.Magnitude; 46 | } 47 | 48 | public bool LessThan(Complex a, Complex b) 49 | { 50 | return a.Magnitude < b.Magnitude; 51 | } 52 | 53 | public bool LessThanOrEqual(Complex a, Complex b) 54 | { 55 | return a.Magnitude <= b.Magnitude; 56 | } 57 | 58 | public bool Equal(Complex a, Complex b) 59 | { 60 | return a == b; 61 | } 62 | 63 | public bool NotEqual(Complex a, Complex b) 64 | { 65 | return a != b; 66 | } 67 | 68 | public bool IsAddCommutative => true; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /PositronicVariables/Runtime/IPositronicRuntime.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Variables.Factory; 2 | using System; 3 | using System.IO; 4 | 5 | namespace PositronicVariables.Runtime 6 | { 7 | /// 8 | /// Interface that encapsulates the global runtime state for PositronicVariables. 9 | /// This abstraction makes it easier to substitute the global state during testing. 10 | /// 11 | public interface IPositronicRuntime 12 | { 13 | /// 14 | /// Controls the emotional direction of time: +1 means "we're moving on," 15 | /// -1 means "let's try that whole simulation again but sadder." 16 | /// 17 | int Entropy { get; set; } 18 | 19 | /// 20 | /// Global convergence flag. 21 | /// 22 | bool Converged { get; set; } 23 | 24 | /// 25 | /// A bit wetware, but it gets the job done. 26 | /// 27 | TextWriter Babelfish { get; set; } 28 | 29 | /// 30 | /// The collection of all Positronic variables registered. 31 | /// 32 | IPositronicVariableRegistry Variables { get; } 33 | 34 | /// 35 | /// Performs a ceremonial memory wipe on the runtime state. 36 | /// Ideal for fresh starts, debugging, or pretending the last run didn't happen. 37 | /// 38 | void Reset(); 39 | 40 | // --- Added Diagnostics --- 41 | /// 42 | /// Total iterations spent during convergence. 43 | /// 44 | int TotalConvergenceIterations { get; set; } 45 | 46 | /// 47 | /// Triggered when all positronic variables achieve harmony 48 | /// and agree on something for once in their chaotic lives. 49 | /// 50 | event Action OnAllConverged; 51 | 52 | // for consumers who need to *create* new variables: 53 | IPositronicVariableFactory Factory { get; } 54 | 55 | // for code that needs to *enumerate* or *clear* the registry: 56 | IPositronicVariableRegistry Registry { get; } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/UriOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | 3 | namespace QuantumSuperposition.Operators 4 | { 5 | /// 6 | /// Attempts to math URLs. Results may vary wildly. Don't try this at home. 7 | /// 8 | public class UriOperators : IQuantumOperators 9 | { 10 | public Uri Add(Uri a, Uri b) 11 | { 12 | return new Uri(a, b); // Combine a base URI + relative 13 | } 14 | 15 | public Uri Subtract(Uri a, Uri b) 16 | { 17 | throw new NotSupportedException("Subtracting URIs isn't a real thing unless you're Google."); 18 | } 19 | 20 | public Uri Multiply(Uri a, Uri b) 21 | { 22 | throw new NotSupportedException("Multiplying URIs risks portal instability."); 23 | } 24 | 25 | public Uri Divide(Uri a, Uri b) 26 | { 27 | throw new NotSupportedException("Dividing URIs just sounds wrong."); 28 | } 29 | 30 | public Uri Mod(Uri a, Uri b) 31 | { 32 | throw new NotSupportedException("Modulo on URIs?? HTTP 418 - I'm a teapot."); 33 | } 34 | 35 | public bool GreaterThan(Uri a, Uri b) 36 | { 37 | return string.Compare(a.AbsoluteUri, b.AbsoluteUri, StringComparison.Ordinal) > 0; 38 | } 39 | 40 | public bool GreaterThanOrEqual(Uri a, Uri b) 41 | { 42 | return string.Compare(a.AbsoluteUri, b.AbsoluteUri, StringComparison.Ordinal) >= 0; 43 | } 44 | 45 | public bool LessThan(Uri a, Uri b) 46 | { 47 | return string.Compare(a.AbsoluteUri, b.AbsoluteUri, StringComparison.Ordinal) < 0; 48 | } 49 | 50 | public bool LessThanOrEqual(Uri a, Uri b) 51 | { 52 | return string.Compare(a.AbsoluteUri, b.AbsoluteUri, StringComparison.Ordinal) <= 0; 53 | } 54 | 55 | public bool Equal(Uri a, Uri b) 56 | { 57 | return a.Equals(b); 58 | } 59 | 60 | public bool NotEqual(Uri a, Uri b) 61 | { 62 | return !a.Equals(b); 63 | } 64 | 65 | public bool IsAddCommutative => false; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Timeline/ITimelineArchivist.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Variables; 2 | using QuantumSuperposition.QuantumSoup; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace PositronicVariables.Engine.Timeline 7 | { 8 | public interface ITimelineArchivist 9 | where T : IComparable 10 | { 11 | /// 12 | /// Metatron writes, he knows not why - but it's important. 13 | /// 14 | /// 15 | /// 16 | void SnapshotAppend(PositronicVariable variable, QuBit newSlice); 17 | /// 18 | /// This is why he wrote it down - to remember. 19 | /// 20 | void RestoreLastSnapshot(); 21 | /// 22 | /// A bookmark in the timeline, for when you need to go back. 23 | /// 24 | /// 25 | void RegisterTimelineAppendedHook(Action hook); 26 | /// 27 | /// Vitally important: otherwise the timeline would grow without bound. 28 | /// 29 | /// 30 | /// 31 | void ReplaceLastSlice(PositronicVariable variable, QuBit mergedSlice); 32 | /// 33 | /// When the universe insists on a specific outcome, we must comply. 34 | /// 35 | /// 36 | /// 37 | void OverwriteBootstrap(PositronicVariable variable, QuBit slice); 38 | /// 39 | /// For when the timeline needs a fresh start. 40 | /// 41 | void ClearSnapshots(); 42 | 43 | /// 44 | /// Publish an immutable snapshot to archival storage. 45 | /// 46 | void PublishSnapshot(ImmutableTimelineSnapshot snapshot); 47 | 48 | /// 49 | /// Get archived snapshots for a variable id. 50 | /// 51 | IReadOnlyList> GetSnapshots(long variableId); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PositronicTester/ConcurrencyTestHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace PositronicVariables.Tests 7 | { 8 | /// 9 | /// Utilities to run concurrent tasks with deterministic, synchronized start. 10 | /// 11 | internal static class ConcurrencyTestHelpers 12 | { 13 | /// 14 | /// Runs n tasks which all wait on a shared start signal, then execute the provided action. 15 | /// Returns all tasks to allow awaiting and error aggregation. 16 | /// 17 | public static IReadOnlyList RunConcurrentTasks(int n, Action action, TimeSpan? timeout = null) 18 | { 19 | if (n <= 0) throw new ArgumentOutOfRangeException(nameof(n)); 20 | if (action == null) throw new ArgumentNullException(nameof(action)); 21 | 22 | var start = new ManualResetEventSlim(false); 23 | var ready = new CountdownEvent(n); 24 | var tasks = new List(n); 25 | 26 | for (int i = 0; i < n; i++) 27 | { 28 | tasks.Add(Task.Run(() => 29 | { 30 | try 31 | { 32 | // signal that this worker is ready to start 33 | ready.Signal(); 34 | // wait for the shared start gate 35 | start.Wait(timeout ?? TimeSpan.FromSeconds(10)); 36 | action(); 37 | } 38 | catch (Exception ex) 39 | { 40 | // bubble up exceptions to caller via task fault 41 | throw new InvalidOperationException($"Worker failed: {ex.Message}", ex); 42 | } 43 | })); 44 | } 45 | 46 | // wait until all workers are ready, then release the gate 47 | if (!ready.Wait(timeout ?? TimeSpan.FromSeconds(10))) 48 | throw new TimeoutException("Workers did not become ready in time."); 49 | 50 | start.Set(); 51 | return tasks; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /QuantumSoupTester/EqualityTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Numerics; 4 | using NUnit.Framework; 5 | using QuantumSuperposition.Core; 6 | using QuantumSuperposition.QuantumSoup; 7 | using QuantumSuperposition.Systems; 8 | 9 | namespace QuantumSoupTester 10 | { 11 | [TestFixture] 12 | public class EqualityTests 13 | { 14 | [Test] 15 | public void QuantumRegister_AlmostEquals_ComparesSubspace() 16 | { 17 | var system = new QuantumSystem(); 18 | var reg1 = QuantumRegister.EPRPair(system); 19 | var reg2 = QuantumRegister.GHZState(system, 2); 20 | Assert.That(reg1.AlmostEquals(reg2, 1e-12), Is.True); 21 | Assert.That(reg1.Equals(reg2), Is.True); 22 | } 23 | 24 | [Test] 25 | public void QuantumRegister_AlmostEquals_DetectsDifference() 26 | { 27 | var system1 = new QuantumSystem(); 28 | var reg1 = QuantumRegister.EPRPair(system1); 29 | var phase = new QuantumGate(new Complex[,] { 30 | {1,0,0,0}, 31 | {0,1,0,0}, 32 | {0,0,1,0}, 33 | {0,0,0, Complex.Exp(Complex.ImaginaryOne * 0.1)} 34 | }); 35 | reg1 = phase * reg1; // apply phase to |11> 36 | 37 | var system2 = new QuantumSystem(); 38 | var reg2 = QuantumRegister.EPRPair(system2); 39 | Assert.That(reg1.AlmostEquals(reg2, 1e-6), Is.False); 40 | } 41 | 42 | [Test] 43 | public void Eigenstates_AlmostEquals_ByProbabilityMass() 44 | { 45 | var e1 = new Eigenstates(new[]{1,2,3}); 46 | e1 = e1.WithWeights(new(){ {1, 1.0}, {2, 1.0}, {3, 0.0} }); 47 | var e2 = new Eigenstates(new[]{1,2,3}); 48 | e2 = e2.WithWeights(new(){ {1, 1.0}, {2, 1.0}, {3, 1e-11} }); 49 | Assert.That(e1.AlmostEquals(e2, 1e-9), Is.True); 50 | } 51 | 52 | [Test] 53 | public void Eigenstates_AlmostEquals_FailsOnDifferentSupport() 54 | { 55 | var e1 = new Eigenstates(new[]{1,2}); 56 | var e2 = new Eigenstates(new[]{1,3}); 57 | Assert.That(e1.AlmostEquals(e2), Is.False); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/QuantumOperatorsFactory.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | using System.Collections.Concurrent; 3 | using System.Numerics; 4 | 5 | namespace QuantumSuperposition.Operators 6 | { 7 | public static class QuantumOperatorsFactory 8 | { 9 | private static readonly ConcurrentDictionary _cache = new(); 10 | 11 | static QuantumOperatorsFactory() 12 | { 13 | Register(() => new IntOperators()); 14 | Register(() => new ComplexOperators()); 15 | Register(() => new BooleanOperators()); 16 | Register(() => new StringOperators()); 17 | Register(() => new FloatOperators()); 18 | Register(() => new DoubleOperators()); 19 | Register(() => new DecimalOperators()); 20 | Register(() => new ByteOperators()); 21 | Register(() => new SByteOperators()); 22 | Register(() => new ShortOperators()); 23 | Register(() => new UShortOperators()); 24 | Register(() => new UIntOperators()); 25 | Register(() => new LongOperators()); 26 | Register(() => new ULongOperators()); 27 | Register(() => new CharOperators()); 28 | Register(() => new DateTimeOperators()); 29 | Register(() => new TimeSpanOperators()); 30 | Register(() => new GuidOperators()); 31 | Register(() => new UriOperators()); 32 | Register(() => new VersionOperators()); 33 | 34 | } 35 | 36 | public static void Register(Func> factory) 37 | { 38 | _cache[typeof(T)] = factory; 39 | } 40 | 41 | public static IQuantumOperators GetOperators() 42 | { 43 | if (_cache.TryGetValue(typeof(T), out object? factoryObj)) 44 | { 45 | Func> factory = (Func>)factoryObj; 46 | return factory(); 47 | } 48 | 49 | // fallback: dynamically create ExpressionOperators 50 | return new ExpressionOperators(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/HotspotAggregator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace PositronicVariables.Transactions 6 | { 7 | /// 8 | /// Aggregates STMTelemetry into hotspot stats and applies mitigation strategies. 9 | /// 10 | public sealed class HotspotAggregator 11 | { 12 | private readonly List _strategies = new(); 13 | 14 | public void RegisterStrategy(IHotspotMitigationStrategy strategy) 15 | { 16 | if (strategy == null) throw new ArgumentNullException(nameof(strategy)); 17 | _strategies.Add(strategy); 18 | } 19 | 20 | public IEnumerable ComputeStats() 21 | { 22 | var perVar = STMTelemetry.GetPerVariableStats(); 23 | long totalAborts = STMTelemetry.TotalAborts; 24 | long totalCommits = STMTelemetry.TotalCommits; 25 | double abortRateGlobal = totalCommits == 0 ? 0.0 : (double)totalAborts / totalCommits; 26 | 27 | foreach (var (txId, failures, writes, lockTicks) in perVar) 28 | { 29 | double avgLock = writes == 0 ? 0.0 : (double)lockTicks / writes; 30 | // Approximate abort rate for this var as share of failures relative to total commits 31 | double abortRate = totalCommits == 0 ? 0.0 : Math.Min(1.0, (double)failures / totalCommits); 32 | yield return new HotspotStats(txId, abortRate, avgLock, failures, writes); 33 | } 34 | } 35 | 36 | public IEnumerable<(long tvarId, IHotspotMitigationStrategy strategy)> DetectHotspots() 37 | { 38 | foreach (var s in ComputeStats()) 39 | { 40 | foreach (var strat in _strategies) 41 | { 42 | if (strat.ShouldMitigate(s.TxId, s)) 43 | { 44 | yield return (s.TxId, strat); 45 | } 46 | } 47 | } 48 | } 49 | 50 | public void ApplyDetectedMitigations() 51 | { 52 | foreach (var (id, strat) in DetectHotspots()) 53 | { 54 | strat.ApplyMitigation(id); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /QuantumSuperposition/QuantumSoup/PhysicsQubit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using QuantumSuperposition.Operators; 4 | 5 | namespace QuantumSuperposition.QuantumSoup 6 | { 7 | /// 8 | /// Specialised qubit constrained to the computational basis {|0>, |1>} with 9 | /// constructors for direct amplitude initialisation and Bloch sphere parameters. 10 | /// Internally uses QuBit with weights { 0 -> alpha, 1 -> beta }. 11 | /// 12 | public sealed class PhysicsQubit : QuBit 13 | { 14 | private static readonly IntOperators _intOps = new(); 15 | 16 | /// 17 | /// Creates a PhysicsQubit with amplitudes alpha for |0> and beta for |1>. 18 | /// The amplitudes are normalised using the existing weight logic. 19 | /// 20 | public PhysicsQubit(Complex alpha, Complex beta) 21 | : base(new (int value, Complex weight)[] { (0, alpha), (1, beta) }, _intOps) 22 | { 23 | // Ensure amplitudes are normalised regardless of input 24 | NormaliseWeights(); 25 | } 26 | 27 | /// 28 | /// Creates a PhysicsQubit from real/imaginary components of alpha and beta. 29 | /// 30 | public PhysicsQubit(double aRe, double aIm, double bRe, double bIm) 31 | : this(new Complex(aRe, aIm), new Complex(bRe, bIm)) 32 | { } 33 | 34 | /// 35 | /// Creates a PhysicsQubit from Bloch sphere angles. 36 | /// |?> = cos(?/2)|0> + e^{i?} sin(?/2)|1> 37 | /// 38 | public PhysicsQubit(double theta, double phi) 39 | : this( 40 | // alpha = cos(theta/2) 41 | new Complex(Math.Cos(theta / 2.0), 0.0), 42 | // beta = e^{i phi} * sin(theta/2) 43 | Complex.FromPolarCoordinates(Math.Sin(theta / 2.0), phi)) 44 | { } 45 | 46 | /// 47 | /// Shortcut for |0> state. 48 | /// 49 | public static PhysicsQubit Zero => new PhysicsQubit(Complex.One, Complex.Zero); 50 | 51 | /// 52 | /// Shortcut for |1> state. 53 | /// 54 | public static PhysicsQubit One => new PhysicsQubit(Complex.Zero, Complex.One); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /PositronicVariables/Runtime/DefaultPositronicRuntime.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Transponder; 2 | using PositronicVariables.Variables.Factory; 3 | using System; 4 | using System.IO; 5 | 6 | namespace PositronicVariables.Runtime 7 | { 8 | /// 9 | /// Default implementation of IPositronicRuntime using the original static behavior. 10 | /// 11 | public class DefaultPositronicRuntime : IPositronicRuntime 12 | { 13 | public int Entropy { get; set; } = 1; 14 | public bool Converged { get; set; } = false; 15 | public TextWriter Babelfish { get; set; } 16 | public IPositronicVariableRegistry Variables { get; } 17 | public int TotalConvergenceIterations { get; set; } = 0; 18 | 19 | 20 | public event Action OnAllConverged; 21 | public IPositronicVariableFactory Factory { get; } 22 | public IPositronicVariableRegistry Registry { get; } 23 | 24 | 25 | public DefaultPositronicRuntime() 26 | { 27 | Babelfish = AethericRedirectionGrid.ImprobabilityDrive; 28 | 29 | // Create a minimal fake IServiceProvider 30 | FallbackServiceProvider provider = new(this); 31 | ScopedPositronicVariableFactory scoped = new(provider); 32 | 33 | Factory = scoped; 34 | Variables = scoped; 35 | Registry = scoped; 36 | 37 | Reset(); 38 | PositronicAmbient.Current = this; 39 | } 40 | 41 | private class FallbackServiceProvider(IPositronicRuntime runtime) : IServiceProvider 42 | { 43 | public object GetService(Type serviceType) 44 | { 45 | return serviceType == typeof(IPositronicRuntime) 46 | ? (object)runtime 47 | : throw new InvalidOperationException($"Service {serviceType.Name} not available in fallback provider."); 48 | } 49 | } 50 | 51 | public void Reset() 52 | { 53 | Entropy = 1; 54 | Converged = false; 55 | Babelfish = AethericRedirectionGrid.ImprobabilityDrive; 56 | Registry.Clear(); 57 | TotalConvergenceIterations = 0; 58 | } 59 | 60 | // Helper to invoke the global convergence event. 61 | public void FireAllConverged() 62 | { 63 | OnAllConverged?.Invoke(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /PositronicTester/PositronicVariableConcurrencyTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using PositronicVariables.Runtime; 3 | using PositronicVariables.Variables; 4 | using Microsoft.Extensions.Hosting; 5 | using PositronicVariables.DependencyInjection; 6 | using System; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace PositronicVariables.Tests 11 | { 12 | [TestFixture] 13 | public class PositronicVariableConcurrencyTests 14 | { 15 | private IPositronicRuntime _rt; 16 | 17 | [SetUp] 18 | public void SetUp() 19 | { 20 | var hb = new HostBuilder().ConfigureServices(s => s.AddPositronicRuntime()); 21 | PositronicAmbient.InitialiseWith(hb); 22 | _rt = PositronicAmbient.Current; 23 | } 24 | 25 | [TearDown] 26 | public void TearDown() 27 | { 28 | if (PositronicAmbient.IsInitialized && PositronicAmbient.Services is IDisposable disp) 29 | disp.Dispose(); 30 | PositronicAmbient.PanicAndReset(); 31 | } 32 | 33 | [Test] 34 | public void Baseline_SingleThreaded_Intact() 35 | { 36 | var v = PositronicVariable.GetOrCreate("x", 0, _rt); 37 | v.Assign(1); 38 | v.Assign(2); 39 | v.Assign(3); 40 | Assert.That(v.ToValues().OrderBy(x => x).ToArray(), Is.EquivalentTo(new[] { 0, 1, 2, 3 })); 41 | } 42 | 43 | [Test] 44 | public void NonTransactional_Race_NoCrash() 45 | { 46 | var v = PositronicVariable.GetOrCreate("concurrent", 0, _rt); 47 | 48 | // 20 workers concurrently mutating the same variable 49 | var tasks = ConcurrencyTestHelpers.RunConcurrentTasks(20, () => 50 | { 51 | // interleave reads and writes 52 | var current = v.GetCurrentQBit().ToCollapsedValues().ToArray(); 53 | v.Assign(v + 1); 54 | v.Assign(v + 2); 55 | _ = v.ToValues().ToArray(); 56 | }); 57 | 58 | Assert.DoesNotThrowAsync(async () => await Task.WhenAll(tasks)); 59 | 60 | // We don't assert exact values (non-transactional); just that the API remained usable. 61 | var states = v.ToValues().OrderBy(x => x).ToArray(); 62 | Assert.That(states.Length, Is.GreaterThanOrEqualTo(1)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /QuantumSoupTester/QuantumRegisterTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Numerics; 4 | using NUnit.Framework; 5 | using QuantumSuperposition.Core; 6 | using QuantumSuperposition.QuantumSoup; 7 | using QuantumSuperposition.Systems; 8 | 9 | namespace QuantumSoupTester 10 | { 11 | [TestFixture] 12 | public class QuantumRegisterTests 13 | { 14 | [Test] 15 | public void FromInt_ConstructsCorrectBasisState() 16 | { 17 | var system = new QuantumSystem(); 18 | var reg = QuantumRegister.FromInt(3, 2, system); 19 | int value = reg.GetValue(); 20 | Assert.That(value, Is.EqualTo(3)); 21 | } 22 | 23 | [Test] 24 | public void FromAmplitudes_ConstructsSuperposition() 25 | { 26 | var system = new QuantumSystem(); 27 | Complex amp = new Complex(1.0 / Math.Sqrt(4), 0); 28 | var vec = new[] { amp, amp, amp, amp }; // uniform 2-bit state 29 | var reg = QuantumRegister.FromAmplitudes(vec, system); 30 | Assert.That(system.Amplitudes.Count, Is.EqualTo(4)); 31 | } 32 | 33 | [Test] 34 | public void Collapse_PartialObserveOnlyTargetBits() 35 | { 36 | var system = new QuantumSystem(); 37 | var q0 = new QuBit(system, new[] { 0 }); 38 | var q2 = new QuBit(system, new[] { 2 }); 39 | var q1 = new QuBit(system, new[] { 1 }); 40 | var amps = new System.Collections.Generic.Dictionary(new QuantumSuperposition.Utilities.IntArrayComparer()); 41 | for (int i = 0; i < 8; i++) 42 | { 43 | int[] bits = QuantumAlgorithms.IndexToBits(i, 3); 44 | amps[bits] = new Complex(1.0 / Math.Sqrt(8), 0); 45 | } 46 | system.SetAmplitudes(amps); 47 | var reg = new QuantumRegister(q0, q2); 48 | int[] measured = reg.Collapse(new Random(123)); 49 | Assert.That(measured.Length, Is.EqualTo(2)); 50 | } 51 | 52 | [Test] 53 | public void GetValue_SubSlice_Works() 54 | { 55 | var system = new QuantumSystem(); 56 | var reg = QuantumRegister.FromInt(13, 4, system); // 13 = 1101 57 | int low2 = reg.GetValue(offset: 2, length: 2); // last two bits '0','1' => 1 58 | Assert.That(low2, Is.EqualTo(1)); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /QuantumSoupTester/GateRegisterSugarTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Numerics; 4 | using NUnit.Framework; 5 | using QuantumSuperposition.Core; 6 | using QuantumSuperposition.Systems; 7 | 8 | namespace QuantumSoupTester 9 | { 10 | [TestFixture] 11 | public class GateRegisterSugarTests 12 | { 13 | [Test] 14 | public void SingleQubitGate_AppliesToRegister() 15 | { 16 | var system = new QuantumSystem(); 17 | // Start with |0> basis 18 | var reg = QuantumRegister.FromInt(0, 1, system); 19 | // Apply Hadamard via operator 20 | reg = QuantumGates.Hadamard * reg; 21 | // After application, amplitude count should remain 2 basis states 22 | Assert.That(system.Amplitudes.Count, Is.EqualTo(2)); 23 | double probSum = system.Amplitudes.Values.Sum(a => a.Magnitude * a.Magnitude); 24 | Assert.That(probSum, Is.EqualTo(1.0).Within(1e-12)); 25 | } 26 | 27 | [Test] 28 | public void TwoQubitGate_CompositionMaintainsProbability() 29 | { 30 | var system = new QuantumSystem(); 31 | var reg = QuantumRegister.GHZState(system, 2); // effectively Bell-like 32 | // Apply CNOT using operator (should enqueue then process) 33 | reg = QuantumGates.CNOT * reg; 34 | double probSum = system.Amplitudes.Values.Sum(a => a.Magnitude * a.Magnitude); 35 | Assert.That(probSum, Is.EqualTo(1.0).Within(1e-12)); 36 | } 37 | 38 | [Test] 39 | public void MultiQubitGate_AppliesDirectly() 40 | { 41 | var system = new QuantumSystem(); 42 | var reg = QuantumRegister.WState(system, 3); 43 | // Identity-like 8x8 44 | Complex[,] identity8 = new Complex[8,8]; 45 | for (int i=0;i<8;i++) identity8[i,i] = Complex.One; 46 | var gate = new QuantumGate(identity8); 47 | reg = gate * reg; 48 | // Should preserve amplitudes count = 3 (W state basis states) 49 | Assert.That(system.Amplitudes.Count, Is.EqualTo(3)); 50 | } 51 | 52 | [Test] 53 | public void GateArityMismatch_Throws() 54 | { 55 | var system = new QuantumSystem(); 56 | var reg = QuantumRegister.GHZState(system, 3); 57 | // 2x2 gate on 3-qubit register should fail 58 | Assert.Throws(() => { reg = QuantumGates.Hadamard * reg; }); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /PositronicVariables/DependencyInjection/PositronicServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using PositronicVariables.Engine; 3 | using PositronicVariables.Engine.Entropy; 4 | using PositronicVariables.Engine.Logging; 5 | using PositronicVariables.Engine.Timeline; 6 | using PositronicVariables.Engine.Transponder; 7 | using PositronicVariables.Runtime; 8 | using PositronicVariables.Variables.Factory; 9 | using System; 10 | using PositronicVariables.Engine.Coordinator; 11 | 12 | namespace PositronicVariables.DependencyInjection 13 | { 14 | public static class PositronicServiceCollectionExtensions 15 | { 16 | public static IServiceCollection AddPositronicRuntime(this IServiceCollection services) 17 | { 18 | return services.AddPositronicRuntime(builder => { }); 19 | } 20 | 21 | public static IServiceCollection AddPositronicRuntime( 22 | this IServiceCollection services, 23 | Action> configure) 24 | where T : IComparable 25 | { 26 | _ = services.AddScoped(); 27 | _ = services.AddScoped(sp => sp.GetRequiredService()); 28 | _ = services.AddScoped(sp => sp.GetRequiredService()); 29 | _ = services.AddScoped(); 30 | 31 | // Coordinator used by engine and tests 32 | _ = services.AddSingleton(); 33 | 34 | _ = services.AddScoped>(sp => 35 | { 36 | IPositronicRuntime runtime = sp.GetRequiredService(); 37 | var coordinator = sp.GetRequiredService(); 38 | 39 | ImprobabilityEngine defaultEngine = new( 40 | new DefaultEntropyController(runtime), 41 | new RegretScribe(), 42 | new SubEthaOutputTransponder(runtime), 43 | runtime, 44 | new BureauOfTemporalRecords(), 45 | coordinator 46 | ); 47 | 48 | ConvergenceEngineBuilder builder = new(); 49 | configure(builder); 50 | 51 | return builder.Build(defaultEngine); 52 | }); 53 | 54 | return services; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /QuantumSoupTester/StringTests.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | using QuantumSuperposition.Operators; 3 | using QuantumSuperposition.QuantumSoup; 4 | 5 | namespace QuantumSoupTester 6 | { 7 | [TestFixture] 8 | public class QuantumMathStringTests 9 | { 10 | // Use our simple StringOperators instance. 11 | private readonly IQuantumOperators stringOps = new StringOperators(); 12 | 13 | [Test] 14 | public void QuBit_EvaluateAll_AllNonDefault_ReturnsTrue_String() 15 | { 16 | QuBit qubit = new( 17 | ["Alpha", "Beta", "Gamma"], 18 | stringOps 19 | ); 20 | 21 | bool result = qubit.EvaluateAll(); 22 | Assert.That(result, Is.True); 23 | } 24 | 25 | [Test] 26 | public void QuBit_EvaluateAll_ContainsDefault_ReturnsFalse_String() 27 | { 28 | QuBit qubit = new( 29 | ["Alpha", null, "Gamma"], 30 | stringOps 31 | ); 32 | 33 | bool result = qubit.EvaluateAll(); 34 | Assert.That(result, Is.False); 35 | } 36 | 37 | [Test] 38 | public void QuBit_AdditionOperator_WithScalar_String() 39 | { 40 | QuantumConfig.EnableNonObservationalArithmetic = true; 41 | 42 | QuBit qubit = new( 43 | ["Hello", "World"], 44 | stringOps 45 | ); 46 | string scalar = "!"; 47 | // Expect the addition operator to perform concatenation. 48 | List result = (qubit + scalar).States.ToList(); 49 | List expected = ["Hello!", "World!"]; 50 | 51 | Assert.That(result, Is.EquivalentTo(expected)); 52 | } 53 | 54 | [Test] 55 | public void QuBit_Concatenation_WithAnotherQuBit_String() 56 | { 57 | QuantumConfig.EnableNonObservationalArithmetic = true; 58 | 59 | QuBit qubitA = new( 60 | ["Quantum", "Super"], 61 | stringOps 62 | ); 63 | QuBit qubitB = new( 64 | ["Math", "Test"], 65 | stringOps 66 | ); 67 | 68 | // Expect the addition operator to produce every combination. 69 | List result = (qubitA + qubitB).States.ToList(); 70 | List expected = 71 | [ 72 | "QuantumMath", "QuantumTest", "SuperMath", "SuperTest" 73 | ]; 74 | 75 | Assert.That(result, Is.EquivalentTo(expected)); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /PositronicVariables/Runtime/PositronicAmbient.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Hosting; 3 | using System; 4 | using System.Threading; 5 | 6 | namespace PositronicVariables.Runtime 7 | { 8 | 9 | /// 10 | /// This is the current version of the universe that we happen to have fallen into. A container for the runtime and services that are available to the positronic variables. 11 | /// 12 | public static class PositronicAmbient 13 | { 14 | private static readonly AsyncLocal _ambient = new(); 15 | private static IPositronicRuntime _global; 16 | 17 | private static readonly AsyncLocal _servicesAmbient = new(); 18 | private static IServiceProvider _servicesGlobal; 19 | 20 | public static bool IsInitialized => _ambient.Value is not null || _global is not null; 21 | 22 | public static IPositronicRuntime Current 23 | { 24 | get => _ambient.Value ?? _global 25 | ?? throw new InvalidOperationException("Positronic runtime not yet created"); 26 | set 27 | { 28 | _ambient.Value = value; 29 | _global = value; 30 | } 31 | } 32 | 33 | public static IServiceProvider Services 34 | { 35 | get => _servicesAmbient.Value ?? _servicesGlobal 36 | ?? throw new InvalidOperationException("Service provider not yet available"); 37 | private set 38 | { 39 | _servicesAmbient.Value = value; 40 | _servicesGlobal = value; 41 | } 42 | } 43 | 44 | public static void InitialiseWith(IHostBuilder hostBuilder) 45 | { 46 | if (IsInitialized) 47 | { 48 | throw new InvalidOperationException("Positronic runtime already initialised."); 49 | } 50 | 51 | IHost host = hostBuilder.Build(); 52 | Services = host.Services; // jam the services into the ambient pocket universe so everything stops throwing tantrums 53 | Current = host.Services.GetRequiredService(); 54 | 55 | } 56 | 57 | /// 58 | /// Unhooks all known realities from the runtime matrix and chucks them into the bin marked "Let's Pretend That Didn't Happen." 59 | /// 60 | public static void PanicAndReset() 61 | { 62 | _ambient.Value = null; 63 | _global = null; 64 | _servicesAmbient.Value = null; 65 | _servicesGlobal = null; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /QuantumSoupTester/CanonicalStatesTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Numerics; 4 | using NUnit.Framework; 5 | using QuantumSuperposition.Core; 6 | using QuantumSuperposition.Systems; 7 | 8 | namespace QuantumSoupTester 9 | { 10 | [TestFixture] 11 | public class CanonicalStatesTests 12 | { 13 | [Test] 14 | public void EPRPair_ConstructsBellState() 15 | { 16 | var system = new QuantumSystem(); 17 | var reg = QuantumRegister.EPRPair(system); 18 | var amps = system.Amplitudes; 19 | Assert.That(amps.Count, Is.EqualTo(2)); 20 | var probSum = amps.Values.Sum(a => a.Magnitude * a.Magnitude); 21 | Assert.That(probSum, Is.EqualTo(1.0).Within(1e-12)); 22 | Assert.That(amps.Keys.Any(k => k.SequenceEqual(new[] { 0, 0 })), Is.True); 23 | Assert.That(amps.Keys.Any(k => k.SequenceEqual(new[] { 1, 1 })), Is.True); 24 | } 25 | 26 | [Test] 27 | public void WState_Length3_HasThreeBasisStates() 28 | { 29 | var system = new QuantumSystem(); 30 | var reg = QuantumRegister.WState(system, 3); 31 | Assert.That(system.Amplitudes.Count, Is.EqualTo(3)); 32 | double expectedAmp = 1.0 / Math.Sqrt(3); 33 | foreach (var amp in system.Amplitudes.Values) 34 | { 35 | Assert.That(amp.Magnitude, Is.EqualTo(expectedAmp).Within(1e-12)); 36 | } 37 | } 38 | 39 | [Test] 40 | public void GHZState_Length4_HasTwoBasisStates() 41 | { 42 | var system = new QuantumSystem(); 43 | var reg = QuantumRegister.GHZState(system, 4); 44 | Assert.That(system.Amplitudes.Count, Is.EqualTo(2)); 45 | double expectedAmp = 1.0 / Math.Sqrt(2); 46 | foreach (var amp in system.Amplitudes.Values) 47 | { 48 | Assert.That(amp.Magnitude, Is.EqualTo(expectedAmp).Within(1e-12)); 49 | } 50 | Assert.That(system.Amplitudes.Keys.Any(k => k.All(b => b == 0)), Is.True); 51 | Assert.That(system.Amplitudes.Keys.Any(k => k.All(b => b == 1)), Is.True); 52 | } 53 | 54 | [Test] 55 | public void WState_InvalidLength_Throws() 56 | { 57 | var system = new QuantumSystem(); 58 | Assert.Throws(() => QuantumRegister.WState(system, 1)); 59 | } 60 | 61 | [Test] 62 | public void GHZState_InvalidLength_Throws() 63 | { 64 | var system = new QuantumSystem(); 65 | Assert.Throws(() => QuantumRegister.GHZState(system, 1)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Logging/QuantumLedgerOfRegret.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace PositronicVariables.Engine.Logging 6 | { 7 | /// 8 | /// The Quantum Ledger of Regret™ — remembers every dumb thing you've done so you can go back and pretend you didn't. 9 | /// Now with idempotent, commit-identified append semantics so your mistakes aren’t recorded twice by an overenthusiastic historian. 10 | /// 11 | public static class QuantumLedgerOfRegret 12 | { 13 | private static readonly Stack _log = new(); 14 | private static readonly object _lock = new(); 15 | private static readonly HashSet _seenCommitIds = new(); 16 | 17 | /// 18 | /// Legacy direct record. Prefer buffering via TransactionV2 and appending via Append(op, commitId). 19 | /// Useful in emergencies and overly dramatic unit tests. 20 | /// 21 | public static void Record(IOperation op) 22 | { 23 | if (op == null) return; 24 | Append(op, Guid.NewGuid()); 25 | } 26 | 27 | /// 28 | /// Idempotent append guarded by commit id. If the commit id was already seen, the entry is ignored. 29 | /// This prevents déjà vu from becoming data duplication. 30 | /// 31 | public static void Append(IOperation op, Guid commitId) 32 | { 33 | if (op == null) return; 34 | lock (_lock) 35 | { 36 | if (_seenCommitIds.Contains(commitId)) return; 37 | _seenCommitIds.Add(commitId); 38 | _log.Push(op); 39 | } 40 | } 41 | 42 | public static IOperation Peek() 43 | { 44 | lock (_lock) 45 | { 46 | return _log.Count > 0 ? _log.Peek() : null; 47 | } 48 | } 49 | 50 | public static void ReverseLastOperations() 51 | { 52 | lock (_lock) 53 | { 54 | while (_log.Count > 0) 55 | { 56 | IOperation op = _log.Pop(); 57 | op.Undo(); 58 | } 59 | } 60 | } 61 | 62 | // Violently yeet the last recorded mistake into the entropy void. 63 | public static void Pop() 64 | { 65 | lock (_lock) 66 | { 67 | if (_log.Count > 0) 68 | { 69 | _ = _log.Pop(); 70 | } 71 | } 72 | } 73 | 74 | public static void Clear() 75 | { 76 | lock (_lock) 77 | { 78 | _log.Clear(); 79 | _seenCommitIds.Clear(); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /PositronicVariables/Operations/ReversibleModulusOp.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Engine.Logging; 2 | using PositronicVariables.Maths; 3 | using PositronicVariables.Operations.Interfaces; 4 | using PositronicVariables.Runtime; 5 | using PositronicVariables.Variables; 6 | using QuantumSuperposition.QuantumSoup; 7 | using System; 8 | using System.Linq; 9 | 10 | namespace PositronicVariables.Operations 11 | { 12 | /// 13 | /// x % d — but logged with enough information so the step 14 | /// can be undone later. 15 | /// 16 | public sealed class ReversibleModulusOp : IReversibleSnapshotOperation 17 | where T : IComparable 18 | { 19 | private readonly IPositronicRuntime _runtime; 20 | public PositronicVariable Variable { get; } 21 | public T Divisor { get; } 22 | private readonly T _quotient; 23 | 24 | public T Original { get; } 25 | 26 | public string OperationName => $"Modulus by {Divisor}"; 27 | 28 | public ReversibleModulusOp(PositronicVariable variable, T divisor, IPositronicRuntime runtime) 29 | { 30 | Variable = variable; 31 | Divisor = divisor; 32 | _runtime = runtime ?? throw new ArgumentNullException(nameof(runtime)); 33 | 34 | // snapshot the value *before* the % 35 | Original = variable.GetCurrentQBit().ToCollapsedValues().First(); 36 | // capture the Euclidean quotient q = floor(Original / divisor) 37 | // (for float/double/decimal this MUST be floored, not plain division) 38 | _quotient = Arithmetic.FloorDiv(Original, divisor); 39 | } 40 | 41 | /// 42 | /// Inverse: x % d -> (x // d) * d + (x % d) (i.e. reconstruct the original value) 43 | /// 44 | /// 45 | /// 46 | public T ApplyForward(T value) 47 | { 48 | return Arithmetic.Modulus(value, Divisor); 49 | } 50 | 51 | /// 52 | /// Forward: x -> x % d 53 | /// 54 | /// 55 | /// 56 | public T ApplyInverse(T remainder) 57 | { 58 | return Arithmetic.Add(Arithmetic.Multiply(_quotient, Divisor), remainder); 59 | } 60 | 61 | /// 62 | /// Undoing a modulus operation is a bit like trying to un bake a cake. 63 | /// 64 | void IOperation.Undo() 65 | { 66 | // jam the original quantum sandwich back into the timeline like nothing ever happened 67 | QuBit qb = new(new[] { Original }); 68 | _ = qb.Any(); 69 | Variable.ReplaceLastFromReverse(qb); 70 | 71 | // Tell the convergence loop we're done 72 | _runtime.Converged = true; 73 | } 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /PositronicVariables/Runtime/NumericOps.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | 4 | namespace PositronicVariables.Runtime 5 | { 6 | internal static class NumericOps 7 | { 8 | private static readonly TypeCode _code = Type.GetTypeCode(typeof(T)); 9 | 10 | public static T Add(T a, T b) 11 | { 12 | switch (_code) 13 | { 14 | case TypeCode.Int32: return (T)(object)((int)(object)a + (int)(object)b); 15 | case TypeCode.Int64: return (T)(object)((long)(object)a + (long)(object)b); 16 | case TypeCode.Double: return (T)(object)((double)(object)a + (double)(object)b); 17 | case TypeCode.Single: return (T)(object)((float)(object)a + (float)(object)b); 18 | case TypeCode.Decimal: return (T)(object)((decimal)(object)a + (decimal)(object)b); 19 | case TypeCode.UInt32: return (T)(object)((uint)(object)a + (uint)(object)b); 20 | case TypeCode.UInt64: return (T)(object)((ulong)(object)a + (ulong)(object)b); 21 | case TypeCode.Int16: return (T)(object)((short)(object)a + (short)(object)b); 22 | case TypeCode.UInt16: return (T)(object)((ushort)(object)a + (ushort)(object)b); 23 | case TypeCode.Byte: return (T)(object)((byte)(object)a + (byte)(object)b); 24 | case TypeCode.SByte: return (T)(object)((sbyte)(object)a + (sbyte)(object)b); 25 | default: 26 | try { dynamic da = a; dynamic db = b; return (T)(da + db); } catch { return b; } 27 | } 28 | } 29 | 30 | public static T Subtract(T a, T b) 31 | { 32 | switch (_code) 33 | { 34 | case TypeCode.Int32: return (T)(object)((int)(object)a - (int)(object)b); 35 | case TypeCode.Int64: return (T)(object)((long)(object)a - (long)(object)b); 36 | case TypeCode.Double: return (T)(object)((double)(object)a - (double)(object)b); 37 | case TypeCode.Single: return (T)(object)((float)(object)a - (float)(object)b); 38 | case TypeCode.Decimal: return (T)(object)((decimal)(object)a - (decimal)(object)b); 39 | case TypeCode.UInt32: return (T)(object)((uint)(object)a - (uint)(object)b); 40 | case TypeCode.UInt64: return (T)(object)((ulong)(object)a - (ulong)(object)b); 41 | case TypeCode.Int16: return (T)(object)((short)(object)a - (short)(object)b); 42 | case TypeCode.UInt16: return (T)(object)((ushort)(object)a - (ushort)(object)b); 43 | case TypeCode.Byte: return (T)(object)((byte)(object)a - (byte)(object)b); 44 | case TypeCode.SByte: return (T)(object)((sbyte)(object)a - (sbyte)(object)b); 45 | default: 46 | try { dynamic da = a; dynamic db = b; return (T)(da - db); } catch { return a; } 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/GenericOperator.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | using System.Linq.Expressions; 3 | 4 | namespace QuantumSuperposition.Operators 5 | { 6 | public static class GenericOperator 7 | { 8 | public static readonly Func Add = GenerateBinaryOperator(Expression.Add); 9 | public static readonly Func Subtract = GenerateBinaryOperator(Expression.Subtract); 10 | public static readonly Func Multiply = GenerateBinaryOperator(Expression.Multiply); 11 | public static readonly Func Divide = GenerateBinaryOperator(Expression.Divide); 12 | 13 | private static Func GenerateBinaryOperator(Func op) 14 | { 15 | ParameterExpression paramA = Expression.Parameter(typeof(T)); 16 | ParameterExpression paramB = Expression.Parameter(typeof(T)); 17 | try 18 | { 19 | BinaryExpression body = op(paramA, paramB); 20 | return Expression.Lambda>(body, paramA, paramB).Compile(); 21 | } 22 | catch 23 | { 24 | return (a, b) => throw new NotSupportedException($"Operation not supported for type {typeof(T)}."); 25 | } 26 | } 27 | } 28 | 29 | public class ExpressionOperators : IQuantumOperators 30 | { 31 | public T Add(T a, T b) 32 | { 33 | return GenericOperator.Add(a, b); 34 | } 35 | 36 | public T Subtract(T a, T b) 37 | { 38 | return GenericOperator.Subtract(a, b); 39 | } 40 | 41 | public T Multiply(T a, T b) 42 | { 43 | return GenericOperator.Multiply(a, b); 44 | } 45 | 46 | public T Divide(T a, T b) 47 | { 48 | return GenericOperator.Divide(a, b); 49 | } 50 | 51 | public T Mod(T a, T b) 52 | { 53 | throw new NotSupportedException(); // Not supported in expressions 54 | } 55 | 56 | public bool GreaterThan(T a, T b) 57 | { 58 | throw new NotSupportedException(); // Extendable! 59 | } 60 | 61 | public bool GreaterThanOrEqual(T a, T b) 62 | { 63 | throw new NotSupportedException(); 64 | } 65 | 66 | public bool LessThan(T a, T b) 67 | { 68 | throw new NotSupportedException(); 69 | } 70 | 71 | public bool LessThanOrEqual(T a, T b) 72 | { 73 | throw new NotSupportedException(); 74 | } 75 | 76 | public bool Equal(T a, T b) 77 | { 78 | return EqualityComparer.Default.Equals(a, b); 79 | } 80 | 81 | public bool NotEqual(T a, T b) 82 | { 83 | return !EqualityComparer.Default.Equals(a, b); 84 | } 85 | 86 | public bool IsAddCommutative => true; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /PositronicTester/ParanoiaModeTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Microsoft.Extensions.Hosting; 3 | using PositronicVariables.DependencyInjection; 4 | using PositronicVariables.Runtime; 5 | using PositronicVariables.Transactions; 6 | using PositronicVariables.Variables; 7 | using QuantumSuperposition.QuantumSoup; 8 | using System; 9 | 10 | namespace PositronicVariables.Tests 11 | { 12 | [TestFixture] 13 | public class ParanoiaModeTests 14 | { 15 | private IPositronicRuntime _rt; 16 | 17 | [SetUp] 18 | public void SetUp() 19 | { 20 | var hb = new HostBuilder().ConfigureServices(s => s.AddPositronicRuntime()); 21 | PositronicAmbient.InitialiseWith(hb); 22 | _rt = PositronicAmbient.Current; 23 | STMTelemetry.Reset(); 24 | ParanoiaConfig.Reset(); 25 | } 26 | 27 | [TearDown] 28 | public void TearDown() 29 | { 30 | if (PositronicAmbient.IsInitialized && PositronicAmbient.Services is IDisposable disp) 31 | disp.Dispose(); 32 | PositronicAmbient.PanicAndReset(); 33 | } 34 | 35 | [Test] 36 | public void Paranoia_LockOrdering_Assertion_Enabled() 37 | { 38 | ParanoiaConfig.EnableParanoia = true; 39 | 40 | var a = PositronicVariable.GetOrCreate("a", 0, _rt); 41 | var b = PositronicVariable.GetOrCreate("b", 0, _rt); 42 | 43 | // Stage writes out-of-order deliberately (b then a). Commit should still acquire in ascending order. 44 | // We assert that if TxIds are not strictly increasing in acquisition, paranoia throws. 45 | Assert.DoesNotThrow(() => 46 | { 47 | TransactionV2.Run(tx => 48 | { 49 | tx.RecordRead(a); tx.RecordRead(b); 50 | tx.StageWrite(b, new QuBit(new[] { 1 }).Any()); 51 | tx.StageWrite(a, new QuBit(new[] { 1 }).Any()); 52 | }); 53 | }); 54 | } 55 | 56 | [Test] 57 | public void GlobalFallback_Activates_OnThreshold() 58 | { 59 | ParanoiaConfig.EnableGlobalFallback = true; 60 | ParanoiaConfig.AbortRetryThreshold = 0; // force activation immediately 61 | 62 | var a = PositronicVariable.GetOrCreate("a", 0, _rt); 63 | var b = PositronicVariable.GetOrCreate("b", 0, _rt); 64 | 65 | TransactionV2.RunWithRetry(tx => 66 | { 67 | tx.RecordRead(a); tx.RecordRead(b); 68 | int av = a.GetCurrentQBit().ToCollapsedValues().First(); 69 | int bv = b.GetCurrentQBit().ToCollapsedValues().First(); 70 | tx.StageWrite(a, new QuBit(new[] { av + 1 }).Any()); 71 | tx.StageWrite(b, new QuBit(new[] { bv + 1 }).Any()); 72 | }, maxAttempts: 1, baseDelayMs: 0, maxDelayMs: 0); 73 | 74 | Assert.That(ParanoiaConfig.FallbackActive, Is.True); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /PositronicVariables/Engine/Transponder/SubEthaOutputTransponder.cs: -------------------------------------------------------------------------------- 1 | using PositronicVariables.Runtime; 2 | using System; 3 | using System.IO; 4 | 5 | namespace PositronicVariables.Engine.Transponder 6 | { 7 | public class SubEthaOutputTransponder(IPositronicRuntime runtime) : ISubEthaTransponder 8 | { 9 | private TextWriter _originalOut; 10 | private bool _redirected; 11 | internal static void FlushNow() 12 | { 13 | try 14 | { 15 | string bufferText = AethericRedirectionGrid.ImprobabilityDrive.ToString(); 16 | if (string.IsNullOrEmpty(bufferText)) return; 17 | TextWriter target = AethericRedirectionGrid.ReferenceUniverse; 18 | target.Write(bufferText); 19 | target.Flush(); 20 | Console.SetOut(target); 21 | AethericRedirectionGrid.SuppressEndOfUniverseReading = true; 22 | } 23 | catch { } 24 | } 25 | public void Redirect() 26 | { 27 | // If already redirected to the buffer, treat original as the real console to avoid self-append 28 | _originalOut = ReferenceEquals(Console.Out, AethericRedirectionGrid.ImprobabilityDrive) 29 | ? AethericRedirectionGrid.ReferenceUniverse 30 | : Console.Out; 31 | 32 | Console.SetOut(AethericRedirectionGrid.ImprobabilityDrive); 33 | runtime.Babelfish = AethericRedirectionGrid.ImprobabilityDrive; 34 | _redirected = true; 35 | } 36 | public void Restore() 37 | { 38 | if (!_redirected) 39 | { 40 | return; 41 | } 42 | string bufferText = AethericRedirectionGrid.ImprobabilityDrive.ToString(); 43 | try 44 | { 45 | // Avoid self-append in all cases 46 | bool originalIsBuffer = ReferenceEquals(_originalOut, AethericRedirectionGrid.ImprobabilityDrive); 47 | 48 | if (!originalIsBuffer) 49 | { 50 | if (!AethericRedirectionGrid.AtTheRestaurant) 51 | { 52 | _originalOut.Write(bufferText); 53 | _originalOut.Flush(); 54 | AethericRedirectionGrid.SuppressEndOfUniverseReading = true; 55 | } 56 | else 57 | { 58 | AethericRedirectionGrid.SuppressEndOfUniverseReading = false; 59 | } 60 | } 61 | else 62 | { 63 | // If original target is buffer, do not write; let outer flush handle emission 64 | AethericRedirectionGrid.SuppressEndOfUniverseReading = !AethericRedirectionGrid.AtTheRestaurant ? true : false; 65 | } 66 | 67 | Console.SetOut(_originalOut); 68 | } 69 | finally 70 | { 71 | _redirected = false; 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /QuantumSoupTester/BasisMappingTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Numerics; 4 | using NUnit.Framework; 5 | using QuantumSuperposition.QuantumSoup; 6 | using QuantumSuperposition.Systems; 7 | 8 | namespace QuantumSoupTester 9 | { 10 | public enum BitEnum { Zero = 0, One = 1 } 11 | public enum FunkyEnum { Banana = 42, Apple = 7 } 12 | 13 | [TestFixture] 14 | public class BasisMappingTests 15 | { 16 | [Test] 17 | public void SetFromTensorProduct_EnumDefaultMapper_Works() 18 | { 19 | var system = new QuantumSystem(); 20 | var q = new QuBit(new[] { BitEnum.Zero, BitEnum.One }); 21 | Assert.DoesNotThrow(() => system.SetFromTensorProduct(false, q)); 22 | var keys = system.Amplitudes.Keys.ToArray(); 23 | Assert.That(keys.Length, Is.EqualTo(2)); 24 | Assert.That(keys.Any(k => k.Length == 1 && k[0] == 0)); 25 | Assert.That(keys.Any(k => k.Length == 1 && k[0] == 1)); 26 | } 27 | 28 | [Test] 29 | public void SetFromTensorProduct_CustomMapper_Works() 30 | { 31 | var system = new QuantumSystem(); 32 | var q = new QuBit(new[] { FunkyEnum.Banana, FunkyEnum.Apple }); 33 | int Mapper(FunkyEnum v) => v == FunkyEnum.Banana ? 1 : 0; 34 | Assert.DoesNotThrow(() => system.SetFromTensorProduct(true, Mapper, q)); 35 | var keys = system.Amplitudes.Keys.ToArray(); 36 | Assert.That(keys.Length, Is.EqualTo(2)); 37 | Assert.That(keys.Any(k => k.Length == 1 && k[0] == 0)); 38 | Assert.That(keys.Any(k => k.Length == 1 && k[0] == 1)); 39 | } 40 | 41 | private readonly struct BitPair 42 | { 43 | public readonly int High; public readonly int Low; 44 | public BitPair(int h, int l){ High = h; Low = l; } 45 | } 46 | 47 | [Test] 48 | public void SetFromTensorProduct_StructCustomMapper_Works() 49 | { 50 | var system = new QuantumSystem(); 51 | int Map(BitPair bp) => (bp.High << 1) | bp.Low; 52 | var qx = new QuBit(new[] { new BitPair(0,0), new BitPair(0,1) }); 53 | var qy = new QuBit(new[] { new BitPair(1,0), new BitPair(1,1) }); 54 | system.SetFromTensorProduct(false, Map, qx, qy); 55 | Assert.That(system.Amplitudes.Count, Is.EqualTo(4)); 56 | Assert.That(system.Amplitudes.Keys.Any(k => k[0] == 0 && k[1] == 2)); 57 | } 58 | 59 | [Test] 60 | public void SetFromTensorProduct_TwoEnumQubits_BuildsFourStates() 61 | { 62 | var system = new QuantumSystem(); 63 | var qa = new QuBit(new[] { BitEnum.Zero, BitEnum.One }); 64 | var qb = new QuBit(new[] { BitEnum.Zero, BitEnum.One }); 65 | system.SetFromTensorProduct(false, qa, qb); 66 | Assert.That(system.Amplitudes.Count, Is.EqualTo(4)); 67 | Assert.That(system.Amplitudes.Keys.Any(k => k[0] == 0 && k[1] == 1)); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /QuantumSuperposition/docs/UsageExamples.md: -------------------------------------------------------------------------------- 1 | ## Usage Examples 2 | 3 | ## Required Namespaces 4 | 5 | These examples demonstrate basic and advanced usage of the `QuBit` class and related quantum simulation features. Make sure to import the correct namespaces. 6 | 7 | ```csharp 8 | using QuantumSuperposition.Core; 9 | using QuantumSuperposition.QuantumSoup; 10 | using QuantumSuperposition.Operators; 11 | ``` 12 | 13 | ### Basic Usage 14 | 15 | ```csharp 16 | using QuantumSuperposition; 17 | 18 | var qubit = new QuBit(new[] { 1, 2, 3 }); 19 | Console.WriteLine(qubit.SampleWeighted()); 20 | ``` 21 | 22 | ### Arithmetic Operations 23 | 24 | ```csharp 25 | using QuantumSuperposition; 26 | 27 | var qubit1 = new QuBit(new[] { 1, 2 }); 28 | var qubit2 = new QuBit(new[] { 3, 4 }); 29 | 30 | var result = qubit1 + qubit2; 31 | Console.WriteLine(result.SampleWeighted()); 32 | ``` 33 | 34 | ### Entanglement 35 | 36 | ```csharp 37 | using QuantumSuperposition; 38 | 39 | var qubit1 = new QuBit(new[] { 1, 2 }); 40 | var qubit2 = new QuBit(new[] { 3, 4 }); 41 | 42 | qubit1.EntangleWith(qubit2); 43 | Console.WriteLine(qubit1.SampleWeighted()); 44 | Console.WriteLine(qubit2.SampleWeighted()); 45 | ``` 46 | 47 | ### Functional Operations 48 | 49 | ```csharp 50 | using QuantumSuperposition; 51 | 52 | var qubit = new QuBit(new[] { 1, 2, 3 }); 53 | var result = qubit.Select(x => x * 2); 54 | Console.WriteLine(result.SampleWeighted()); 55 | ``` 56 | 57 | ### Working with Complex Numbers 58 | 59 | ```csharp 60 | using QuantumSuperposition; 61 | using System.Numerics; 62 | 63 | var qubit = new QuBit(new[] { new Complex(1, 1), new Complex(2, 2) }); 64 | var result = qubit.Select(x => x * new Complex(2, 0)); 65 | Console.WriteLine(result.SampleWeighted()); 66 | ``` 67 | ### Prime Detection 68 | 69 | ```csharp 70 | // For each number from 1 to 100 we test primality by creating 71 | // a superposition of all smaller potential divisors (2...n-1). 72 | // Then divide i by all at once and check if any remainder is zero. 73 | for (int i = 1; i <= 100; i++) 74 | { 75 | var divisors = new QuBit(Enumerable.Range(2, i > 2 ? i - 2 : 1), intOps); 76 | if ((i % divisors).EvaluateAll()) 77 | Console.WriteLine($"{i} is prime!"); 78 | } 79 | ``` 80 | 81 | ### Factors of 10 82 | 83 | ```csharp 84 | // Extract factors of 10 by projecting 10 % x across 1..10 and filtering for 0 results 85 | var factors = Factors(10); 86 | Console.WriteLine("Factors: " + factors.ToString()); 87 | 88 | public static Eigenstates Factors(int v) 89 | { 90 | var candidates = new Eigenstates(Enumerable.Range(1, v), x => v % x, intOps); 91 | return candidates == 0; 92 | } 93 | ``` 94 | 95 | ### Min Value 96 | 97 | ```csharp 98 | Console.WriteLine("min value of 3, 5, 8 is " + MinValue(new[] { 3, 5, 8 })); 99 | 100 | public static int MinValue(IEnumerable range) 101 | { 102 | var values = new Eigenstates(range, intOps); 103 | var filtered = values.Any() <= values.All(); 104 | return filtered.ToValues().First(); 105 | } 106 | -------------------------------------------------------------------------------- /QuantumSuperposition/Operators/StringOperators.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Core; 2 | using System.Text; 3 | 4 | namespace QuantumSuperposition.Operators 5 | { 6 | public class StringOperators : IQuantumOperators 7 | { 8 | // Define addition as string concatenation. 9 | public string Add(string a, string b) 10 | { 11 | return a + b; 12 | } 13 | 14 | // Define subtraction as removing the first occurrence of 'b' from 'a'. 15 | public string Subtract(string a, string b) 16 | { 17 | if (string.IsNullOrEmpty(b)) 18 | { 19 | return a; 20 | } 21 | 22 | int index = a.IndexOf(b, StringComparison.Ordinal); 23 | if (index < 0) 24 | { 25 | return a; // or optionally, throw an exception if subtraction should be "mandatory" 26 | } 27 | 28 | return a.Remove(index, b.Length); 29 | } 30 | 31 | public string Multiply(string a, string b) 32 | { 33 | // Cartesian product of strings 34 | if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b)) 35 | { 36 | return string.Empty; 37 | } 38 | 39 | StringBuilder result = new(); 40 | foreach (char c1 in a) 41 | { 42 | foreach (char c2 in b) 43 | { 44 | _ = result.Append(c1); 45 | _ = result.Append(c2); 46 | } 47 | } 48 | return result.ToString(); 49 | } 50 | // Opposite of multiplication 51 | public string Divide(string a, string b) 52 | { 53 | throw new NotSupportedException("Divide is not supported for strings."); 54 | } 55 | 56 | // Modulo is not applicable. 57 | public string Mod(string a, string b) 58 | { 59 | throw new NotSupportedException("Modulo is not supported for strings."); 60 | } 61 | 62 | // Comparisons: using ordinal comparison here; you may adjust for culture-specific needs. 63 | public bool GreaterThan(string a, string b) 64 | { 65 | return string.Compare(a, b, StringComparison.Ordinal) > 0; 66 | } 67 | 68 | public bool GreaterThanOrEqual(string a, string b) 69 | { 70 | return string.Compare(a, b, StringComparison.Ordinal) >= 0; 71 | } 72 | 73 | public bool LessThan(string a, string b) 74 | { 75 | return string.Compare(a, b, StringComparison.Ordinal) < 0; 76 | } 77 | 78 | public bool LessThanOrEqual(string a, string b) 79 | { 80 | return string.Compare(a, b, StringComparison.Ordinal) <= 0; 81 | } 82 | 83 | public bool Equal(string a, string b) 84 | { 85 | return a == b; 86 | } 87 | 88 | public bool NotEqual(string a, string b) 89 | { 90 | return a != b; 91 | } 92 | 93 | // String concatenation is not commutative. 94 | public bool IsAddCommutative => false; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /QuantumSoupTester/PhysicsQubitTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Numerics; 4 | using NUnit.Framework; 5 | using QuantumSuperposition.QuantumSoup; 6 | 7 | namespace QuantumSoupTester 8 | { 9 | [TestFixture] 10 | public class PhysicsQubitTests 11 | { 12 | [Test] 13 | public void Zero_And_One_Shortcuts_Work() 14 | { 15 | PhysicsQubit z = PhysicsQubit.Zero; 16 | PhysicsQubit o = PhysicsQubit.One; 17 | 18 | var zw = z.ToWeightedValues().ToDictionary(x => x.value, x => x.weight); 19 | var ow = o.ToWeightedValues().ToDictionary(x => x.value, x => x.weight); 20 | 21 | Assert.That(zw.ContainsKey(0), Is.True); 22 | Assert.That(zw.ContainsKey(1), Is.True); 23 | Assert.That(zw[0].Magnitude, Is.EqualTo(1.0).Within(1e-12)); 24 | Assert.That(zw[1].Magnitude, Is.EqualTo(0.0).Within(1e-12)); 25 | 26 | Assert.That(ow.ContainsKey(0), Is.True); 27 | Assert.That(ow.ContainsKey(1), Is.True); 28 | Assert.That(ow[0].Magnitude, Is.EqualTo(0.0).Within(1e-12)); 29 | Assert.That(ow[1].Magnitude, Is.EqualTo(1.0).Within(1e-12)); 30 | } 31 | 32 | [Test] 33 | public void Amplitude_Ctor_Normalises() 34 | { 35 | PhysicsQubit q = new(new Complex(2, 0), new Complex(0, 0)); 36 | var w = q.ToWeightedValues().ToDictionary(x => x.value, x => x.weight); 37 | 38 | Assert.That(w[0].Magnitude, Is.EqualTo(1.0).Within(1e-12)); 39 | Assert.That(w[1].Magnitude, Is.EqualTo(0.0).Within(1e-12)); 40 | } 41 | 42 | [Test] 43 | public void Components_Ctor_Works() 44 | { 45 | PhysicsQubit q = new(0.0, 0.0, 1.0, 0.0); 46 | var w = q.ToWeightedValues().ToDictionary(x => x.value, x => x.weight); 47 | Assert.That(w[1].Magnitude, Is.EqualTo(1.0).Within(1e-12)); 48 | } 49 | 50 | [Test] 51 | public void BlochSphere_Ctor_Produces_Equal_Superposition_For_Theta_PiOver2_Phi_0() 52 | { 53 | PhysicsQubit q = new(Math.PI / 2.0, 0.0); 54 | var w = q.ToWeightedValues().ToDictionary(x => x.value, x => x.weight); 55 | 56 | // |alpha| = |beta| = 1/sqrt(2) 57 | double invSqrt2 = 1.0 / Math.Sqrt(2.0); 58 | Assert.That(w[0].Magnitude, Is.EqualTo(invSqrt2).Within(1e-12)); 59 | Assert.That(w[1].Magnitude, Is.EqualTo(invSqrt2).Within(1e-12)); 60 | 61 | // Probabilities sum to 1 62 | double probSum = w.Values.Sum(c => c.Magnitude * c.Magnitude); 63 | Assert.That(probSum, Is.EqualTo(1.0).Within(1e-12)); 64 | } 65 | 66 | [Test] 67 | public void BlochSphere_Ctor_Preserves_Phase_On_Beta() 68 | { 69 | double theta = Math.PI / 2.0; 70 | double phi = Math.PI / 2.0; // 90 degrees phase 71 | PhysicsQubit q = new(theta, phi); 72 | var w = q.ToWeightedValues().ToDictionary(x => x.value, x => x.weight); 73 | 74 | Assert.That(w[0], Is.Not.EqualTo(Complex.Zero)); 75 | Assert.That(w[1].Phase, Is.EqualTo(phi).Within(1e-12)); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /PositronicVariables/Transactions/ConcurrencyGuard.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using PositronicVariables.Variables; 4 | 5 | namespace PositronicVariables.Transactions 6 | { 7 | internal static class ConcurrencyGuard 8 | { 9 | private static int _activeTransactions; 10 | private static int _coordinatorThreadId = -1; 11 | private static int _engineThreadId = -1; 12 | private static bool _allowNonTransactionalWrites; 13 | 14 | public static int ActiveTransactions => Volatile.Read(ref _activeTransactions); 15 | public static bool AllowNonTransactionalWrites 16 | { 17 | get => _allowNonTransactionalWrites; 18 | set => _allowNonTransactionalWrites = value; 19 | } 20 | public static void TransactionStarted() => Interlocked.Increment(ref _activeTransactions); 21 | public static void TransactionEnded() => Interlocked.Decrement(ref _activeTransactions); 22 | 23 | public static void RegisterCoordinatorThread() => _coordinatorThreadId = Environment.CurrentManagedThreadId; 24 | public static void RegisterEngineThread() => _engineThreadId = Environment.CurrentManagedThreadId; 25 | public static void UnregisterCoordinatorThread() => _coordinatorThreadId = -1; 26 | public static void UnregisterEngineThread() => _engineThreadId = -1; 27 | public static bool IsCoordinatorThread => Environment.CurrentManagedThreadId == _coordinatorThreadId; 28 | public static bool IsEngineThread => Environment.CurrentManagedThreadId == _engineThreadId; 29 | 30 | #if DEBUG 31 | public static void AssertConvergenceEntrySafe() 32 | { 33 | if (ActiveTransactions > 0 && !IsCoordinatorThread) 34 | { 35 | throw new InvalidOperationException("Convergence loop entered while transactions are active and caller is not coordinator thread."); 36 | } 37 | } 38 | 39 | public static void AssertTimelineMutationContext(PositronicVariable variable) where T : IComparable 40 | { 41 | var currentTx = TransactionV2.Current; 42 | bool inApply = currentTx != null && currentTx.IsApplying; 43 | bool hasLock = Monitor.IsEntered(((ITransactionalVariable)variable).TxLock); 44 | 45 | if (inApply) 46 | { 47 | if (currentTx == null || !currentTx.Contains((ITransactionalVariable)variable)) 48 | { 49 | throw new InvalidOperationException("Unsafe timeline mutation: TVar not in current transaction write set during apply."); 50 | } 51 | return; 52 | } 53 | 54 | if (hasLock) 55 | { 56 | return; 57 | } 58 | 59 | if (IsEngineThread || IsCoordinatorThread) 60 | { 61 | return; 62 | } 63 | 64 | if (ActiveTransactions == 0 || AllowNonTransactionalWrites) 65 | { 66 | return; 67 | } 68 | 69 | throw new InvalidOperationException( 70 | "Unsafe timeline mutation: must occur during TransactionV2 commit, under TVar lock, or on the engine/coordinator thread."); 71 | } 72 | #endif 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /PositronicTester/ConvergenceCoordinatorTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Hosting; 2 | using NUnit.Framework; 3 | using PositronicVariables.DependencyInjection; 4 | using PositronicVariables.Engine.Coordinator; 5 | using PositronicVariables.Runtime; 6 | using PositronicVariables.Transactions; 7 | using PositronicVariables.Variables; 8 | using System; 9 | using System.Linq; 10 | using System.Threading.Tasks; 11 | 12 | namespace PositronicVariables.Tests 13 | { 14 | [TestFixture] 15 | public class ConvergenceCoordinatorTests 16 | { 17 | private IPositronicRuntime _rt; 18 | private ConvergenceCoordinator _coord; 19 | 20 | private class SimpleWriteItem : IConvergenceWorkItem where T : IComparable 21 | { 22 | private readonly PositronicVariable _var; 23 | private readonly T _value; 24 | 25 | public SimpleWriteItem(PositronicVariable v, T value) 26 | { 27 | _var = v; 28 | _value = value; 29 | } 30 | 31 | public void BuildWrites(TransactionV2 tx) 32 | { 33 | tx.StageWrite(_var, new QuantumSuperposition.QuantumSoup.QuBit(new[] { _value }).Any()); 34 | } 35 | 36 | public System.Collections.Generic.IEnumerable BuildCommitHooks() 37 | { 38 | yield break; 39 | } 40 | 41 | public object? GetResultAfterCommit() => null; 42 | } 43 | 44 | [SetUp] 45 | public void SetUp() 46 | { 47 | var hb = new HostBuilder() 48 | .ConfigureServices(s => s.AddPositronicRuntime(b => { })); 49 | 50 | PositronicAmbient.InitialiseWith(hb); 51 | 52 | _rt = PositronicAmbient.Current; 53 | _coord = (ConvergenceCoordinator)PositronicAmbient.Services.GetService(typeof(ConvergenceCoordinator)); 54 | } 55 | 56 | [TearDown] 57 | public void TearDown() 58 | { 59 | if (PositronicAmbient.IsInitialized && PositronicAmbient.Services is IDisposable disp) 60 | disp.Dispose(); 61 | 62 | PositronicAmbient.PanicAndReset(); 63 | } 64 | 65 | [Test] 66 | public async Task Enqueue_Multiple_Writes_Serially_Applied() 67 | { 68 | var v = PositronicVariable.GetOrCreate("coord_var", 0, _rt); 69 | int count = 50; 70 | 71 | for (int i = 1; i <= count; i++) 72 | { 73 | await _coord.EnqueueAsync(new SimpleWriteItem(v, i)); 74 | } 75 | 76 | await _coord.FlushAsync(); 77 | 78 | int final = v.GetCurrentQBit().ToCollapsedValues().First(); 79 | 80 | Assert.That(final, Is.EqualTo(count)); 81 | } 82 | 83 | [Test] 84 | public async Task FlushAsync_Waits_For_All_Work() 85 | { 86 | var v = PositronicVariable.GetOrCreate("coord_flush", 0, _rt); 87 | 88 | for (int i = 1; i <= 10; i++) 89 | { 90 | await _coord.EnqueueAsync(new SimpleWriteItem(v, i)); 91 | } 92 | 93 | await _coord.FlushAsync(); 94 | 95 | Assert.That(_coord.Processed, Is.GreaterThanOrEqualTo(_coord.Enqueued)); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /PositronicVariables/Variables/Factory/ScopedPositronicVariableFactory.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using PositronicVariables.Runtime; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | 7 | namespace PositronicVariables.Variables.Factory 8 | { 9 | public class ScopedPositronicVariableFactory : IPositronicVariableFactory, IPositronicVariableRegistry 10 | { 11 | private readonly IServiceProvider _provider; 12 | private IPositronicRuntime Runtime => _provider.GetRequiredService(); 13 | 14 | private readonly Dictionary<(Type, string), IPositronicVariable> _multiverseIndex 15 | = []; 16 | 17 | public ScopedPositronicVariableFactory(IServiceProvider provider) 18 | { 19 | _provider = provider; 20 | } 21 | 22 | public PositronicVariable GetOrCreate(string id, T initialValue) 23 | where T : IComparable 24 | { 25 | (Type, string id) key = (typeof(T), id); 26 | if (_multiverseIndex.TryGetValue(key, out IPositronicVariable existing)) 27 | { 28 | return (PositronicVariable)existing; 29 | } 30 | 31 | PositronicVariable created = new(initialValue, Runtime); 32 | _multiverseIndex[key] = created; 33 | return created; 34 | } 35 | 36 | public PositronicVariable GetOrCreate(string id) 37 | where T : IComparable 38 | { 39 | (Type, string id) key = (typeof(T), id); 40 | if (_multiverseIndex.TryGetValue(key, out IPositronicVariable existing)) 41 | { 42 | return (PositronicVariable)existing; 43 | } 44 | 45 | PositronicVariable created = new(default, Runtime); 46 | _multiverseIndex[key] = created; 47 | return created; 48 | } 49 | 50 | public PositronicVariable GetOrCreate(T initialValue) 51 | where T : IComparable 52 | { 53 | (Type, string) key = (typeof(T), "default"); 54 | if (_multiverseIndex.TryGetValue(key, out IPositronicVariable existing)) 55 | { 56 | return (PositronicVariable)existing; 57 | } 58 | 59 | PositronicVariable created = new(initialValue, Runtime); 60 | _multiverseIndex[key] = created; 61 | return created; 62 | } 63 | 64 | void IPositronicVariableRegistry.Add(IPositronicVariable v) 65 | { 66 | // pry T out of PositronicVariable with reflection—a technique so eldritch even your toaster fears it 67 | Type t = v.GetType().GetGenericArguments()[0]; 68 | (Type t, string) key = (t, Guid.NewGuid().ToString()); 69 | _multiverseIndex[key] = v; 70 | } 71 | 72 | void IPositronicVariableRegistry.Clear() 73 | { 74 | _multiverseIndex.Clear(); 75 | } 76 | 77 | public IEnumerator GetEnumerator() 78 | { 79 | return _multiverseIndex.Values.GetEnumerator(); 80 | } 81 | 82 | IEnumerator IEnumerable.GetEnumerator() 83 | { 84 | return GetEnumerator(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /QuantumSuperposition/QuantumSoup/Interfaces.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | using QuantumSuperposition.Systems; 3 | 4 | namespace QuantumSuperposition.QuantumSoup 5 | { 6 | 7 | 8 | /// 9 | /// A polite interface so quantum observables can pretend to have structure. 10 | /// Think of it like customer service for probabilistic particles. 11 | /// 12 | /// 13 | public interface IQuantumObservable 14 | { 15 | /// 16 | /// Performs an observation (i.e. collapse) of the quantum state using an optional Random instance. 17 | /// 18 | T Observe(Random? rng = null); 19 | 20 | /// 21 | /// Collapses the quantum state based on weighted probabilities. 22 | /// 23 | T CollapseWeighted(); 24 | 25 | /// 26 | /// Samples the quantum state probabilistically, without collapsing it. 27 | /// 28 | T SampleWeighted(Random? rng = null); 29 | 30 | /// 31 | /// Returns the weighted values of the quantum states. 32 | /// 33 | IEnumerable<(T value, Complex weight)> ToWeightedValues(); 34 | } 35 | 36 | /// 37 | /// A common interface for all qubits that participate in an entangled system. 38 | /// It acts as a "handle" that the QuantumSystem can use to communicate with individual qubits. 39 | /// 40 | public interface IQuantumReference 41 | { 42 | /// 43 | /// Returns the indices within the global quantum system this qubit spans. 44 | /// For example, a single qubit may be index 0, or a 2-qubit register may be [0,1]. 45 | /// 46 | int[] GetQubitIndices(); 47 | 48 | /// 49 | /// Called by QuantumSystem after a collapse or update. 50 | /// Used to refresh local views, cached states, or flags like IsCollapsed. 51 | /// 52 | void NotifyWavefunctionCollapsed(Guid collapseId); 53 | 54 | /// 55 | /// Whether this reference is currently collapsed. 56 | /// 57 | bool IsCollapsed { get; } 58 | 59 | /// 60 | /// Gets the current observed value, if already collapsed. 61 | /// Otherwise throws or returns default depending on implementation. 62 | /// 63 | object? GetObservedValue(); 64 | 65 | /// 66 | /// Collapse this reference and return a value from the superposition. 67 | /// The return type is object for type-agnostic access. Use typed qubits to get T. 68 | /// 69 | object Observe(Random? rng = null); 70 | 71 | /// 72 | /// Applies a unitary gate matrix (e.g. Hadamard, Pauli-X) to the local qubit state. 73 | /// Or subspace of the global wavefunction if entangled. 74 | /// 75 | void ApplyLocalUnitary(Complex[,] gate, string gateName); 76 | 77 | /// 78 | /// Gets the owning QuantumSystem for this qubit, if applicable. 79 | /// This may be null for standalone qubits not currently assigned to a system. 80 | /// 81 | QuantumSystem? System { get; } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /PositronicVariables/Neural/NeuralNodule.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Hosting; 2 | using PositronicVariables.DependencyInjection; 3 | using PositronicVariables.Runtime; 4 | using PositronicVariables.Variables; 5 | using QuantumSuperposition.QuantumSoup; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | 10 | namespace PositronicVariables.Neural 11 | { 12 | /// 13 | /// A quantum-aware neuron that collects Positronic inputs, 14 | /// applies an activation function, and fires an output into an alternate future. 15 | /// 16 | public class NeuralNodule where T : struct, IComparable 17 | { 18 | public List> Inputs { get; } = []; 19 | public PositronicVariable Output { get; } 20 | public Func, QuBit> ActivationFunction { get; set; } 21 | 22 | private static readonly object s_initLock = new(); 23 | /// 24 | /// Ensures that the ambient Positronic runtime is initialized. 25 | /// 26 | /// 27 | private static IPositronicRuntime EnsureAmbientRuntime() 28 | { 29 | if (!PositronicAmbient.IsInitialized) 30 | { 31 | lock (s_initLock) 32 | { 33 | if (!PositronicAmbient.IsInitialized) 34 | { 35 | IHostBuilder hb = Host.CreateDefaultBuilder() 36 | .ConfigureServices(s => s.AddPositronicRuntime()); 37 | PositronicAmbient.InitialiseWith(hb); 38 | } 39 | } 40 | } 41 | return PositronicAmbient.Current; 42 | } 43 | 44 | 45 | /// 46 | /// Constructs a highly opinionated quantum neuron that fires based on arbitrary math and existential dread. 47 | /// 48 | /// 49 | public NeuralNodule(Func, QuBit> activation, IPositronicRuntime runtime) 50 | { 51 | ActivationFunction = activation; 52 | Output = new PositronicVariable(default, runtime); 53 | } 54 | 55 | /// 56 | /// Gathers quantum input states, applies a questionable function, 57 | /// and hurls the result into the multiverse, hoping for the best. 58 | /// 59 | public void Fire() 60 | { 61 | IEnumerable inputValues = Inputs.SelectMany(i => i.ToValues()); 62 | QuBit result = ActivationFunction(inputValues); 63 | _ = result.Any(); 64 | Output.Assign(result); 65 | } 66 | 67 | /// 68 | /// Fires all neural nodules in glorious unison until they stop arguing with themselves. 69 | /// Think: synchronized quantum therapy sessions. 70 | /// Side effects may include enlightenment or light smoking. 71 | /// 72 | /// 73 | public static void ConvergeNetwork(IPositronicRuntime runtime, params NeuralNodule[] nodes) 74 | { 75 | PositronicVariable.RunConvergenceLoop(runtime, () => 76 | { 77 | foreach (NeuralNodule node in nodes) 78 | { 79 | node.Fire(); 80 | } 81 | }); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /QuantumSuperposition/Utilities/GateSchedulingVisualiser.cs: -------------------------------------------------------------------------------- 1 | using QuantumSuperposition.Systems; 2 | using System.Text; 3 | 4 | namespace QuantumSuperposition.Utilities 5 | { 6 | public static class GateSchedulingVisualiser 7 | { 8 | /// 9 | /// Generates an ASCII diagram of the gate operations. 10 | /// 11 | /// A collection of gate operations (in order). 12 | /// Total number of qubits available. 13 | /// A multiline string with the diagram. 14 | public static string Visualise(IEnumerable gateOperations, int totalQubits) 15 | { 16 | // Determine how many time steps there are. 17 | List opsList = gateOperations.ToList(); 18 | int timeSteps = opsList.Count; 19 | // Create a grid with one row per qubit and one column per time step. 20 | string[,] grid = new string[totalQubits, timeSteps]; 21 | 22 | // Initialize grid cells with blanks. 23 | for (int i = 0; i < totalQubits; i++) 24 | { 25 | for (int j = 0; j < timeSteps; j++) 26 | { 27 | grid[i, j] = " "; // four spaces (adjust width as needed) 28 | } 29 | } 30 | 31 | // Fill in the grid with gate labels. 32 | int col = 0; 33 | foreach (QuantumSystem.GateOperation? op in opsList) 34 | { 35 | if (op.OperationType == QuantumSystem.GateType.SingleQubit) 36 | { 37 | // For single-qubit operations, place the label in its row. 38 | int qubit = op.TargetQubits[0]; 39 | grid[qubit, col] = $"[{op.GateName}]"; 40 | } 41 | else if (op.OperationType == QuantumSystem.GateType.TwoQubit) 42 | { 43 | // For two-qubit operations, assume TargetQubits[0] and TargetQubits[1] are the two qubit indices. 44 | int qA = op.TargetQubits[0]; 45 | int qB = op.TargetQubits[1]; 46 | // Place the label on both endpoints. 47 | grid[qA, col] = $"[{op.GateName}]"; 48 | grid[qB, col] = $"[{op.GateName}]"; 49 | // Optionally, draw a vertical connector between the two rows. 50 | int start = Math.Min(qA, qB); 51 | int end = Math.Max(qA, qB); 52 | for (int i = start + 1; i < end; i++) 53 | { 54 | grid[i, col] = " | "; 55 | } 56 | } 57 | col++; 58 | } 59 | 60 | // Build the output diagram string. 61 | StringBuilder sb = new(); 62 | for (int i = 0; i < totalQubits; i++) 63 | { 64 | _ = sb.Append($"q{i}: "); 65 | for (int j = 0; j < timeSteps; j++) 66 | { 67 | _ = sb.Append(grid[i, j]); 68 | if (j < timeSteps - 1) 69 | { 70 | _ = sb.Append("---"); 71 | } 72 | } 73 | _ = sb.AppendLine(); 74 | } 75 | return sb.ToString(); 76 | } 77 | } 78 | } --------------------------------------------------------------------------------