UNPKG

@sschepis/resolang

Version:

ResoLang - Core quantum resonance computation library

236 lines (204 loc) 9.08 kB
// operators.ts // This file implements the core operators defined in the ResoLang syntax. import { ResonantFragment, EntangledNode, Phase, Entropy, Prime, Amplitude, PI } from "./resolang"; import { toFixed } from "./utils"; // 3.2 Operators /** * Tensor (⊗) operator: Simulates field interaction between two ResonantFragments. * This operation conceptually merges their coefficients, combines entropy, and finds a new center. * @param fragmentA The first ResonantFragment. * @param fragmentB The second ResonantFragment. * @returns A new ResonantFragment representing the tensored result. */ export function tensor(fragmentA: ResonantFragment, fragmentB: ResonantFragment): ResonantFragment { const newCoeffs = new Map<Prime, Amplitude>(); let totalAmplitudeSq: f64 = 0.0; const keysA = fragmentA.coeffs.keys(); for (let i = 0; i < keysA.length; i++) { const key = keysA[i]; const amp = fragmentA.coeffs.get(key); newCoeffs.set(key, amp); totalAmplitudeSq += amp * amp; } const keysB = fragmentB.coeffs.keys(); for (let i = 0; i < keysB.length; i++) { const key = keysB[i]; const amp = fragmentB.coeffs.get(key); if (newCoeffs.has(key)) { const existingAmp = newCoeffs.get(key); totalAmplitudeSq -= existingAmp * existingAmp; newCoeffs.set(key, existingAmp + amp); } else { newCoeffs.set(key, amp); } const newAmp = newCoeffs.get(key); totalAmplitudeSq += newAmp * newAmp; } // Normalize the new fragment const normalizationFactor = Math.sqrt(totalAmplitudeSq); if (normalizationFactor > 0) { const keys = newCoeffs.keys(); for (let i = 0; i < keys.length; i++) { const key = keys[i]; newCoeffs.set(key, newCoeffs.get(key) / normalizationFactor); } } // Recalculate entropy let newEntropy: f64 = 0.0; const values = newCoeffs.values(); for (let i = 0; i < values.length; i++) { const p = values[i] * values[i]; if (p > 0) { newEntropy -= p * Math.log(p); } } // Weighted average for the new center const totalEntropy = fragmentA.entropy + fragmentB.entropy; const weightA = totalEntropy > 0 ? fragmentA.entropy / totalEntropy : 0.5; const weightB = totalEntropy > 0 ? fragmentB.entropy / totalEntropy : 0.5; const newCenterX = fragmentA.center[0] * weightA + fragmentB.center[0] * weightB; const newCenterY = fragmentA.center[1] * weightA + fragmentB.center[1] * weightB; return new ResonantFragment(newCoeffs, newCenterX, newCenterY, newEntropy); } /** * Collapse (⇝) operator: Simulates observation and entropy lock on a ResonantFragment. * This operation conceptually finalizes the fragment's state, reducing its entropy. * @param fragment The ResonantFragment to collapse. * @returns A new ResonantFragment with reduced entropy, representing the collapsed state. */ export function collapse(fragment: ResonantFragment): ResonantFragment { // In a quantum system, measurement collapses a superposition to a single state. // We'll simulate this by choosing one prime based on the probabilities |α_p|². const probabilities = new Map<Prime, f64>(); const keys = fragment.coeffs.keys(); let totalProbability: f64 = 0.0; for (let i = 0; i < keys.length; i++) { const key = keys[i]; const amp = fragment.coeffs.get(key); const p = amp * amp; probabilities.set(key, p); totalProbability += p; } // Select a prime based on the probability distribution const rand = Math.random() * totalProbability; let cumulativeProbability: f64 = 0.0; let selectedPrime: Prime = 0; for (let i = 0; i < keys.length; i++) { const key = keys[i]; cumulativeProbability += probabilities.get(key); if (rand < cumulativeProbability) { selectedPrime = key; break; } } // The collapsed state has only one prime with amplitude 1.0 const newCoeffs = new Map<Prime, Amplitude>(); if (selectedPrime > 0) { newCoeffs.set(selectedPrime, 1.0); } // The entropy of a pure state is 0 const collapsedEntropy = 0.0; return new ResonantFragment(newCoeffs, fragment.center[0], fragment.center[1], collapsedEntropy); } /** * Phase Modulation (⟳) operator: Applies a phase shift to an EntangledNode's phase ring. * This modifies the phases within the node's phase ring and can affect its coherence. * @param node The EntangledNode whose phase ring will be modulated. * @param phaseShift The amount of phase to shift by, in radians. */ export function rotatePhase(node: EntangledNode, phaseShift: Phase): void { for (let i = 0; i < node.phaseRing.length; i++) { node.phaseRing[i] = (node.phaseRing[i] + phaseShift) % (2 * PI); // Ensure the phase remains positive (between 0 and 2*PI) if (node.phaseRing[i] < 0) { node.phaseRing[i] += 2 * PI; } } // Phase modulation might subtly affect coherence; here, a small reduction. node.coherence = Math.max(0.0, node.coherence - Math.abs(phaseShift) / (2 * PI * 10.0)); } /** * Entanglement Link (≡) operator: Attempts to entangle two EntangledNodes. * This operation conceptually links nodes if their mutual coherence is high enough. * @param nodeA The first EntangledNode. * @param nodeB The second EntangledNode. */ export function linkEntanglement(nodeA: EntangledNode, nodeB: EntangledNode): void { // Entanglement should depend on both coherence and phase alignment. const avgCoherence = (nodeA.coherence + nodeB.coherence) / 2.0; // Calculate phase difference between the nodes' phase rings let phaseDifference: f64 = 0.0; const len = Math.min(nodeA.phaseRing.length, nodeB.phaseRing.length); for (let i = 0; i < len; i++) { phaseDifference += Math.abs(nodeA.phaseRing[i] - nodeB.phaseRing[i]); } if (len > 0) { phaseDifference /= len; } // Entanglement is more likely with high coherence and low phase difference. const entanglementProbability = avgCoherence * (1.0 - phaseDifference / (2 * PI)); if (entanglementProbability > 0.75) { // Threshold for entanglement const entanglementFactor = (entanglementProbability - 0.75) / 5.0; // Small increase nodeA.coherence = Math.min(1.0, nodeA.coherence + entanglementFactor); nodeB.coherence = Math.min(1.0, nodeB.coherence + entanglementFactor); console.log(`[OPERATOR] Nodes ${nodeA.id} and ${nodeB.id} are entangled. New coherence: A=${toFixed(nodeA.coherence, 4)}, B=${toFixed(nodeB.coherence, 4)}`); } else { console.log(`[OPERATOR] Nodes ${nodeA.id} and ${nodeB.id} cannot entangle. Probability too low: ${toFixed(entanglementProbability, 4)}`); } } /** * Route Selection (→) operator: Simulates resonance path routing between nodes. * This function checks if a conceptual route can be established via intermediate nodes, * based on their coherence. * @param source The source EntangledNode. * @param target The target EntangledNode. * @param viaNodes An array of intermediate EntangledNodes to route through. * @returns True if routing is conceptually successful, false otherwise. */ export function route(source: EntangledNode, target: EntangledNode, viaNodes: Array<EntangledNode>): boolean { console.log(`[OPERATOR] Attempting to route from ${source.id} to ${target.id} via [${viaNodes.map<string>(n => n.id).join(", ")}]`); // This is a simplified routing simulation. A real implementation would use a // graph traversal algorithm (like Dijkstra's) to find the optimal path. let totalCost: f64 = 0; const beta = 0.5; // Weighting factor for entropy vs. coherence let currentNode = source; const path = viaNodes.slice(); path.push(target); for (let i = 0; i < path.length; i++) { const nextNode = path[i]; const avgCoherence = (currentNode.coherence + nextNode.coherence) / 2.0; if (avgCoherence < 0.5) { console.log(`[OPERATOR] Routing failed: Coherence too low between ${currentNode.id} and ${nextNode.id}.`); return false; } // Cost function from entropy-coherence.md: Cost = Σ (1/C_ij + β * S_i) // We don't have entropy on nodes, so we'll use (1 - coherence) as a proxy. const cost = (1.0 / avgCoherence) + beta * (1.0 - currentNode.coherence); totalCost += cost; currentNode = nextNode; } // Arbitrary cost threshold for success if (totalCost < path.length * 2.5) { console.log(`[OPERATOR] Routing successful with a total cost of ${toFixed(totalCost, 4)}.`); return true; } else { console.log(`[OPERATOR] Routing failed: Total cost of ${toFixed(totalCost, 4)} exceeds threshold.`); return false; } } /** * Helper function to retrieve the coherence of an EntangledNode. * @param node The EntangledNode to query. * @returns The coherence value of the node. */ export function coherence(node: EntangledNode): f64 { return node.coherence; } /** * Helper function to retrieve the entropy of a ResonantFragment. * @param fragment The ResonantFragment to query. * @returns The entropy value of the fragment. */ export function entropy(fragment: ResonantFragment): Entropy { return fragment.entropy; }