cpsc-qft / qsharp /Lemmas.qs
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub
eef9104 verified
Raw History Blame Contribute Delete
3.74 kB
// *******************************************************************************
// Copyright (c) 2026 Ahmad Ali Parr and others.
//
// SPDX-License-Identifier: LicenseRef-CPSC-ESCL-1.0 OR AGPL-3.0-only
// *******************************************************************************
namespace ConservationPreservingScattering {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Canon;
// Lemmas as total functions and interpreting operations.
// Each one is the Q# image of a theorem in lean/CPSC/Lemmas.lean.
function Lemma_NilAdmitted() : Bool {
return true;
}
function Lemma_ConsAdmitted(mode : Int, head : GateKind, tailOk : Bool) : Bool {
return Axiom_Preserves(mode, head) and tailOk;
}
function Lemma_AllAdmitted(mode : Int, schedule : GateKind[]) : Bool {
mutable ok = true;
for g in schedule {
if not Axiom_Preserves(mode, g) {
set ok = false;
}
}
return ok;
}
function Lemma_AppendAdmitted(left : Bool, right : Bool) : Bool {
return left and right;
}
function Lemma_TransverseBreaksIsing(q : Int) : Bool {
return not Axiom_PreservesMagnetization(TransverseFlip(q));
}
function Lemma_LoneZBreaksSpinFlip(q : Int) : Bool {
return not Axiom_PreservesSpinFlip(LoneZ(q));
}
operation Lemma_ApplyAdmitted(
register : Qubit[],
g : GateKind,
angle : Double
) : Unit is Adj + Ctl {
let n = Length(register);
let q0 = g::Q0;
let q1 = g::Q1;
if q0 < 0 or q0 >= n or (q1 >= n) {
fail "CPSC lemma: qubit outside the register";
}
if g::Tag == 0 {
if q1 < 0 {
fail "CPSC lemma: ZZ is missing its second qubit";
}
Axiom_ApplyZZ(register[q0], register[q1], angle);
} elif g::Tag == 1 {
if q1 < 0 {
fail "CPSC lemma: pair is missing its second qubit";
}
Axiom_ApplyPair(register[q0], register[q1], angle);
} elif g::Tag == 2 {
Axiom_ApplyFlip(register[q0], angle);
} elif g::Tag == 3 {
Axiom_ApplyZ(register[q0], angle);
} else {
fail "CPSC lemma: unknown gate tag";
}
}
// circuit_comm_*: interpret only an admitted schedule. A rejected head fails closed.
operation Lemma_Interpret(
register : Qubit[],
mode : Int,
schedule : GateKind[],
angle : Double
) : Unit is Adj + Ctl {
if not Lemma_AllAdmitted(mode, schedule) {
fail "CPSC rejected the schedule: a factor breaks the active invariant";
}
for g in schedule {
Lemma_ApplyAdmitted(register, g, angle);
}
}
function Lemma_BondOrbit(n : Int) : GateKind[] {
mutable gates = [];
for i in 0 .. n - 1 {
set gates += [ZZ(i, (i + 1) % n)];
}
return gates;
}
function Lemma_TransverseOrbit(n : Int) : GateKind[] {
mutable gates = [];
for i in 0 .. n - 1 {
set gates += [TransverseFlip(i)];
}
return gates;
}
operation Lemma_IsingCircuit(register : Qubit[], angle : Double) : Unit is Adj + Ctl {
let schedule = Lemma_BondOrbit(Length(register));
Lemma_Interpret(register, 0, schedule, angle);
}
operation Lemma_SpinFlipCircuit(register : Qubit[], angle : Double) : Unit is Adj + Ctl {
let n = Length(register);
let schedule = Lemma_BondOrbit(n) + Lemma_TransverseOrbit(n);
Lemma_Interpret(register, 1, schedule, angle);
}
}