"""
模块: Circuit
生成stabilizer code的测试线路
"""
from clifforder.Code.FermionicLatticeSurgery import FermionicLatticeSurgery
from clifforder.Circuit.Circuit import Circuit
from clifforder.Code.QuantumCode import MajoranaCSSCode, PauliCSSCode, MajoranaCode, PauliCode
from clifforder.Code.Operator import MajoranaOperator, PauliOperator
import numpy as np


##  CHAPTER：====入口函数====
def Code2Circuit(code: MajoranaCSSCode | PauliCSSCode | FermionicLatticeSurgery, noise_model: str, cycle_number: int) -> Circuit | tuple[Circuit, Circuit]:
    """
    input.code: 待转换的code
    input.noise_model: 噪声模型，可选值为'phenomenological'或'circuit-level'
    input.cycle_number: 循环次数
    input.pre_circuit: 待追加的前电路
    output: 转换后的电路
    influence: None
    """

    ##  PART：----输入检查----
    try:
        cycle_number = int(cycle_number)
        assert cycle_number > 0,"检错周期至少为1"
        assert isinstance(code, MajoranaCode) or isinstance(code, PauliCode) or isinstance(code, FermionicLatticeSurgery), "code必须是MajoranaCode、PauliCode或FermionicLatticeSurgery"
    except Exception as e:
        raise ValueError('转换不合法') from e

    ##  PART：----根据噪声模型选择转换函数----
    ##  现象级噪声模拟
    if noise_model == 'phenomenological':
        if isinstance(code, MajoranaCSSCode):
            return _MajoranaCSSCode2PhenomenologicalCircuit(code, cycle_number)
        elif isinstance(code, PauliCSSCode):
            return _PauliCSSCode2PhenomenologicalCircuit(code, cycle_number)
        else:
            raise NotImplementedError

    ##  线路级噪声模拟
    elif noise_model == 'circuit-level':
        if isinstance(code, MajoranaCSSCode):
            return _MajoranaCSSCode2CircuitLevelCircuit(code, cycle_number)
        elif isinstance(code, PauliCSSCode):
            return _PauliCSSCode2CircuitLevelCircuit(code, cycle_number)
        elif isinstance(code, FermionicLatticeSurgery):
            return _FermionicLatticeSurgery2CircuitLevelCircuit(code, cycle_number)
        else:
            raise NotImplementedError

    ##  代码容量级噪声模拟
    elif noise_model == 'code-capacity':
        if isinstance(code, MajoranaCSSCode):
            return _MajoranaCSSCode2CodeCapacityCircuit(code)
        else:
            raise _PauliCSSCode2CodeCapacityCircuit(code)

    ##  其他情况抛出错误
    else:
        raise ValueError('当前版本支持的模拟种类有限')


##  CHAPTER：====Code-capacity error model下的Majorana测试电路====
def _MajoranaCSSCode2CodeCapacityCircuit(code: MajoranaCSSCode) -> Circuit:
    """
    input.code：某个MajoranaCSSCode.
    output: 转换后的电路
    """

    ##  PART：----准备材料----
    stabilizers_x = code.generators_x
    stabilizers_n = []
    for i in range(len(code.generators_z)):
        stabilizers_n.append(code.generators_x[i] @ code.generators_z[i])
    logical_x = code.logical_operators_x
    logical_z = code.logical_operators_z
    logical_occupy = [1j * logical_x[temp] @ logical_z[temp] for temp in range(len(logical_x))]  # Particle number operator set as logical operator set
    majorana_number = code.physical_number  # Fermionic sites数目
    stabilizer_number = len(stabilizers_x) + len(stabilizers_n)  # Checker数目
    circuit = Circuit()

    ##  PART：----电路构造----
    ##  初始化
    circuit.append({'name': 'TICK'})
    circuit.append({'name': 'TRAP', 'majorana_number': majorana_number, 'pauli_number': 0})
    circuit.append({'name': 'TICK'})

    ##  测量可观测量
    observable_include = []
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        observable_include.append(len(circuit._measurements) - 1)

    ##  一开始测量稳定子
    for i, stabilizer in enumerate(stabilizers_x):
        circuit.append({"name": "MPP", "target": stabilizer})
    for i, stabilizer in enumerate(stabilizers_n):
        circuit.append({"name": "MPP", "target": stabilizer})

    ##  添加一轮均匀的噪声
    for i in range(majorana_number):
        circuit.append({"name": "FDEPOLARIZE1", "target": i, "p": 0})

    ##  噪声后测量稳定子
    for i, stabilizer in enumerate(stabilizers_x):
        circuit.append({"name": "MPP", "target": stabilizer, 'p': 0})
    for i, stabilizer in enumerate(stabilizers_n):
        circuit.append({"name": "MPP", "target": stabilizer, 'p': 0})

    ##  添加对应的检测器
    for i in range(stabilizer_number):
        circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - 2 * stabilizer_number]})

    ##  测量逻辑算符并比较
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        circuit.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit._measurements) - 1, observable_include[i]]})

    ##  PART：----返回结果----
    return circuit


##  CHAPTER：====Phenomenological error model下的Majorana测试电路====
def _MajoranaCSSCode2PhenomenologicalCircuit(code: MajoranaCSSCode, cycle_number: int) -> Circuit:
    """
    input.code：某个MajoranaCSSCode
    input.cycle_number: 循环次数
    output: 转换后的电路
    """

    ##  PART：----准备材料----
    stabilizers_x = code.generators_x
    stabilizers_n = []
    for i in range(len(code.generators_z)):
        stabilizers_n.append(code.generators_x[i] @ code.generators_z[i])
    logical_x = code.logical_operators_x
    logical_z = code.logical_operators_z
    logical_occupy = [1j * logical_x[temp] @ logical_z[temp] for temp in range(len(logical_x))]  # Particle number operator set as logical operator set
    majorana_number = code.physical_number  # Fermionic sites数量
    stabilizer_number = len(stabilizers_x) + len(stabilizers_n)  # Checker数目
    circuit = Circuit()

    ##  PART：----生成线路----
    ##  线路初始化
    circuit.append({'name': 'TICK'})
    circuit.append({'name': 'TRAP', 'majorana_number': majorana_number, 'pauli_number': 0})
    circuit.append({'name': 'TICK'})

    ##  首先测量所有可观测量，投射到一个空间内
    observable_include = []
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        observable_include.append(len(circuit._measurements) - 1)

    ##  测量所有的N算符备用，对实际状态没有影响
    for i, stabilizer in enumerate(stabilizers_n):
        circuit.append({"name": "MPP", "target": stabilizer})

    ##  按照要求执行d轮循环
    for _ in range(cycle_number):

        ##  一轮开始的时候先添加一轮均匀去极化噪声
        for i in range(majorana_number):
            circuit.append({"name": "FDEPOLARIZE1", "target": i, "p": 0})

        ##  测量稳定子
        for i, stabilizer in enumerate(stabilizers_x):
            circuit.append({"name": "MPP", "target": stabilizer, 'p': 0})
        for i, stabilizer in enumerate(stabilizers_n):
            circuit.append({"name": "MPP", "target": stabilizer, 'p': 0})

        ##  第一轮只有N稳定子可以与初始化的情况比较
        if _ == 0:
            for i in range(stabilizer_number // 2):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number // 2, i - stabilizer_number - stabilizer_number // 2]})

        ##  其他轮次可以比较所有的稳定子
        else:
            for i in range(stabilizer_number):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - 2 * stabilizer_number]})

    ##  最后做一次横向测量
    for i in range(code.physical_number):
        circuit.append({"name": "MN", "target": i, 'p': 0})

    ##  计算N稳定子与横向测量结果的关系
    for i, stabilizer in enumerate(stabilizers_n):
        target = []  # Determine the N measurement and previous measurement to detect
        stabilizer_now = MajoranaOperator([], [], 1)  # Record the operator corresponding to the actual measurement product
        for index in stabilizer.occupy_x:
            target.append(-code.physical_number + index)
            stabilizer_now = stabilizer_now @ MajoranaOperator([index], [index], 1j)
        target.append(-code.physical_number - stabilizer_number // 2 + i)  # Add previous N measurement
        if stabilizer_now.coff != stabilizer.coff:
            target.append('negative')
        circuit.append({'name': 'DETECTOR', 'target': target})

    ##  生成逻辑可观测量
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        circuit.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit._measurements) - 1, observable_include[i]]})

    ##  PART：----返回结果----
    return circuit


##  CHAPTER：====Circuit-level error model下的Majorana测试电路====
def _MajoranaCSSCode2CircuitLevelCircuit(code: MajoranaCSSCode, cycle_number: int) -> Circuit:
    """
    input.code：某个MajoranaCSSCode
    input.cycle_number: 循环次数
    input.pre_circuit: 前置电路
    output: 转换后的电路
    """

    ##  PART：----准备材料----
    stabilizers_x = code.generators_x
    stabilizers_z = code.generators_z
    stabilizers_n = []
    for i in range(len(code.generators_z)):
        stabilizers_n.append(code.generators_x[i] @ code.generators_z[i])
    logical_x = code.logical_operators_x
    logical_z = code.logical_operators_z
    logical_occupy = [1j * logical_x[temp] @ logical_z[temp] for temp in range(len(logical_x))]  # Particle number operator set as logical operator set
    majorana_number = code.physical_number
    stabilizer_number = len(stabilizers_x) + len(stabilizers_z)
    pauli_number = stabilizer_number
    circuit = Circuit()

    ##  PART：----生成线路----
    ##  线路初始化
    circuit.append({'name': 'TRAP', 'majorana_number': majorana_number, 'pauli_number': pauli_number})
    circuit.append({'name': 'TICK'})

    ##  测量所有的逻辑算符
    observable_include = []
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        observable_include.append(len(circuit._measurements) - 1)

    ##  测量所有的N稳定子备用，对实际状态没有影响
    for i, stabilizer in enumerate(stabilizers_n):
        circuit.append({"name": "MPP", "target": stabilizer})
    circuit.append({'name': 'TICK'})

    ##  一开始对所有的位置都添加一轮均匀的噪声
    for i in range(majorana_number):
        circuit.append({"name": "FDEPOLARIZE1", "target": i, "p": 0})
    for i in range(pauli_number):
        circuit.append({"name": "DEPOLARIZE1", "target": i, "p": 0})
    circuit.append({'name': 'TICK'})

    ##  循环多轮错误提取线路
    for _ in range(cycle_number):

        ##  测量所有的稳定子
        for i, stabilizer in enumerate(stabilizers_x):
            sequence_temp = _syndrome_majorana_css_measurement_circuit(stabilizer, i, 'x')
            for temp in sequence_temp:
                circuit.append(temp)
            circuit.append({'name': 'TICK'})
        for i, stabilizer in enumerate(stabilizers_z):
            sequence_temp = _syndrome_majorana_css_measurement_circuit(stabilizer, i + len(stabilizers_x), 'z')
            for temp in sequence_temp:
                circuit.append(temp)
            circuit.append({'name': 'TICK'})

        ##  对于第一轮只有N稳定子可以参与比较
        if _ == 0:
            for i in range(stabilizer_number // 2):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - stabilizer_number // 2, i - 3 * stabilizer_number // 2]})

        ##  对于后续轮，所有的稳定子都可以参与比较
        else:
            for i in range(stabilizer_number // 2):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - 2 * stabilizer_number]})
            for i in range(stabilizer_number // 2):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - stabilizer_number // 2, i - 3 * stabilizer_number // 2, i - 2 * stabilizer_number]})

    ##  最后是一轮横向测量
    for i in range(code.physical_number):
        circuit.append({"name": "MN", "target": i, 'p': 0})

    ##  计算横向测量与N稳定子之间的关系
    for i, stabilizer in enumerate(stabilizers_n):
        target = []
        stabilizer_now = MajoranaOperator([], [], 1)
        for index in stabilizer.occupy_x:
            target.append(-code.physical_number + index)
            stabilizer_now = stabilizer_now @ MajoranaOperator([index], [index], 1j)
        target.append(-code.physical_number - stabilizer_number // 2 + i)
        target.append(-code.physical_number - stabilizer_number + i)
        if stabilizer_now.coff != stabilizer.coff:
            target.append('negative')
        circuit.append({'name': 'DETECTOR', 'target': target})

    ##  生成逻辑可观测量
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        circuit.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit._measurements) - 1, observable_include[i]]})

    ##  SECTION：----Details----
    return circuit


##  CHAPTER：====Circuit-level error model下的fermionic lattice surgery测试电路====
def _FermionicLatticeSurgery2CircuitLevelCircuit(lattice_surgery: FermionicLatticeSurgery, cycle_number: int) -> Circuit:
    """
    input.lattice_surgery：某个FermionicLatticeSurgery
    input.cycle_number: 循环次数
    output: 转换后的电路
    """

    ##  PART：----预处理----
    ##  提取需要测量的稳定子
    irrelated_A_x = lattice_surgery.irrelated_stabilizers_A_x
    irrelated_A_z = lattice_surgery.irrelated_stabilizers_A_z
    irrelated_B_x = lattice_surgery.irrelated_stabilizers_B_x
    irrelated_B_z = lattice_surgery.irrelated_stabilizers_B_z
    related_A_z = lattice_surgery.related_stabilizers_A_z
    related_B_z = lattice_surgery.related_stabilizers_B_z
    modified_A_x = lattice_surgery.modify_stabilizers_A
    modified_B_x = lattice_surgery.modify_stabilizers_B
    gauge = lattice_surgery.gauge_stabilizers
    stabilizers_n = ([irrelated_A_x[temp] @ irrelated_A_z[temp] for temp in range(len(irrelated_A_x))] +
                     [irrelated_B_x[temp] @ irrelated_B_z[temp] for temp in range(len(irrelated_B_x))] +
                     [modified_A_x[temp] @ related_A_z[temp] for temp in range(len(modified_A_x))] +
                     [modified_B_x[temp] @ related_B_z[temp] for temp in range(len(modified_B_x))] +
                     gauge)
    stabilizers_z = irrelated_A_z + irrelated_B_z + related_A_z + related_B_z

    ##  提取逻辑算符
    logicals = lattice_surgery.bare_logical_operators_z
    logical_occupy = [
        MajoranaOperator.HermitianOperatorFromOccupy(np.concatenate((temp.occupy_x, temp.occupy_z)), np.concatenate((temp.occupy_x, temp.occupy_z)))
        for temp in logicals]

    ##  提取site个数
    majorana_number = lattice_surgery.physical_number
    stabilizer_number_z = len(stabilizers_z)
    stabilizer_number_n = len(stabilizers_n)
    pauli_number = stabilizer_number_z + stabilizer_number_n
    circuit = Circuit()

    ##  PART：----电路生成----
    ##  生成电路头
    circuit.append({'name': 'TRAP', 'majorana_number': majorana_number, 'pauli_number': pauli_number})
    circuit.append({'name': 'TICK'})

    ##  先测量所有的逻辑算符
    observable_include = []
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        observable_include.append(len(circuit._measurements) - 1)

    ##  添加一轮均匀的去极化噪声
    for i in range(majorana_number):
        circuit.append({"name": "FDEPOLARIZE1", "target": i, "p": 0})
    for i in range(pauli_number):
        circuit.append({"name": "DEPOLARIZE1", "target": i, "p": 0})
    circuit.append({'name': 'TICK'})

    ##  执行d轮错误提取线路
    for _ in range(cycle_number):

        ##  测量所有的稳定子
        for i, stabilizer in enumerate(stabilizers_z):
            sequence_temp = _syndrome_majorana_css_measurement_circuit(stabilizer, i, 'z')
            for temp in sequence_temp:
                circuit.append(temp)
            circuit.append({'name': 'TICK'})
        for i, stabilizer in enumerate(stabilizers_n):
            sequence_temp = _syndrome_majorana_css_measurement_circuit(stabilizer, i + len(stabilizers_z), 'n')
            for temp in sequence_temp:
                circuit.append(temp)
            circuit.append({'name': 'TICK'})

        ##  对于第一轮，只能比较N稳定子
        if _ == 0:
            for i in range(stabilizer_number_n):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number_n]})

        ##  对于后续轮可以比较所有的稳定子
        else:
            for i in range(stabilizer_number_z):
                circuit.append({"name": "DETECTOR","target": [i - stabilizer_number_n - stabilizer_number_z, i - 2 * (stabilizer_number_z + stabilizer_number_n)]})
            for i in range(stabilizer_number_n):
                circuit.append({"name": "DETECTOR", "target": [i - stabilizer_number_n, i - 2 * stabilizer_number_n - stabilizer_number_z]})

    ##  添加横向测量
    for i in range(lattice_surgery.physical_number):
        circuit.append({"name": "MN", "target": i, 'p': 0})

    ##  计算N稳定子与横向测量的关系
    for i, stabilizer in enumerate(stabilizers_n):
        target = []
        for index in stabilizer.occupy_x:
            target.append(-lattice_surgery.physical_number + index)
        target.append(-lattice_surgery.physical_number - stabilizer_number_n + i)
        circuit.append({'name': 'DETECTOR', 'target': target})

    ##  比较逻辑可观测量
    for i, logical_operator in enumerate(logical_occupy):
        circuit.append({"name": "MPP", "target": logical_operator})
        circuit.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit._measurements) - 1, observable_include[i]]})

    ##  PART：----返回结果----
    return circuit


##  CHAPTER：====Code-capacity error model下的Majorana测试电路====
def _PauliCSSCode2CodeCapacityCircuit(code: PauliCSSCode) -> tuple[Circuit, Circuit]:
    """
    input.code：某个PauliCSSCode.
    output: 转换后的电路
    """

    ##  PART：----准备材料----
    stabilizers_x = code.generators_x
    stabilizers_z = code.generators_z
    logical_x = code.logical_operators_x
    logical_z = code.logical_operators_z
    stabilizer_number = len(stabilizers_x) + len(stabilizers_z)  # Checker数目
    pauli_number = code.physical_number  # Qubits数目
    circuit_x = Circuit()
    circuit_z = Circuit()
    circuit_x.append({'name': 'TRAP', 'majorana_number': 0, 'pauli_number': pauli_number})
    circuit_x.append({'name': 'H', 'target': range(pauli_number)})
    circuit_z.append({'name': 'TRAP', 'majorana_number': 0, 'pauli_number': pauli_number})
    observable_include_x = []  # Record indices of observables
    observable_include_z = []  # Record indices of observables

    ##  PART：----生成线路----
    ##  一开始先测量可观测量
    for i, logical_operator in enumerate(logical_x):
        circuit_x.append({"name": "MPP", "target": logical_operator})
        observable_include_x.append(len(circuit_x._measurements) - 1)
    for i, logical_operator in enumerate(logical_z):
        circuit_z.append({"name": "MPP", "target": logical_operator})
        observable_include_z.append(len(circuit_z._measurements) - 1)

    ##  对X和Z stabilizer做一开始的稳定子测量
    for i, stabilizer in enumerate(stabilizers_x):
        circuit_x.append({"name": "MPP", "target": stabilizer})
        circuit_z.append({"name": "MPP", "target": stabilizer})
    for i, stabilizer in enumerate(stabilizers_z):
        circuit_x.append({"name": "MPP", "target": stabilizer})
        circuit_z.append({"name": "MPP", "target": stabilizer})

    for i in range(pauli_number):
        circuit_x.append({"name": "DEPOLARIZE1", "target": i, "p": 0})
        circuit_z.append({"name": "DEPOLARIZE1", "target": i, "p": 0})

    ##  对X和Z stabilizer做噪声后的稳定子测量
    for i, stabilizer in enumerate(stabilizers_x):
        circuit_x.append({"name": "MPP", "target": stabilizer, 'p': 0})
        circuit_z.append({"name": "MPP", "target": stabilizer, 'p': 0})
    for i, stabilizer in enumerate(stabilizers_z):
        circuit_x.append({"name": "MPP", "target": stabilizer, 'p': 0})
        circuit_z.append({"name": "MPP", "target": stabilizer, 'p': 0})

    ##  添加检测器
    for i in range(stabilizer_number):
        circuit_x.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - 2 * stabilizer_number]})
        circuit_z.append({"name": "DETECTOR", "target": [i - stabilizer_number, i - 2 * stabilizer_number]})

    ##  测量可观测量
    for i, logical_operator in enumerate(logical_x):
        circuit_x.append({"name": "MPP", "target": logical_operator})
        circuit_x.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit_x._measurements) - 1, observable_include_x[i]]})
    for i, logical_operator in enumerate(logical_z):
        circuit_z.append({"name": "MPP", "target": logical_operator})
        circuit_z.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit_z._measurements) - 1, observable_include_z[i]]})

    ##  PART：----返回结果----
    return circuit_x, circuit_z


##  CHAPTER：====Details====
def _PauliCSSCode2PhenomenologicalCircuit(code: PauliCSSCode, cycle_number: int) -> tuple[Circuit, Circuit]:
    """
    input.code：任意PauliCSSCode.
    input.cycle_number：症状提取线路循环次数
    output：X和Z两种测试线路
    """

    ##  PART：----准备材料----
    stabilizers_x = code.generators_x
    stabilizers_z = code.generators_z
    logical_x = code.logical_operators_x
    logical_z = code.logical_operators_z
    stabilizer_number_x = len(stabilizers_x)
    stabilizer_number_z = len(stabilizers_z)
    pauli_number = code.physical_number

    ##  PART：----生成线路----
    ##  线路初始化
    circuit_x = Circuit()
    circuit_z = Circuit()
    circuit_x.append({'name': 'TRAP', 'majorana_number': 0, 'pauli_number': pauli_number})
    circuit_x.append({'name': 'H', 'target': range(pauli_number)})
    circuit_z.append({'name': 'TRAP', 'majorana_number': 0, 'pauli_number': pauli_number})

    ##  按要求执行d轮提取
    for _ in range(cycle_number):

        ##  先添加一轮均匀去极化噪声
        for i in range(pauli_number):
            circuit_x.append({"name": "DEPOLARIZE1", "target": i, "p": 0})
            circuit_z.append({"name": "DEPOLARIZE1", "target": i, "p": 0})

        ##  测量所有的稳定子
        for i, stabilizer in enumerate(stabilizers_x):
            circuit_x.append({"name": "MPP", "target": stabilizer, 'p': 0})
            circuit_z.append({"name": "MPP", "target": stabilizer, 'p': 0})
        for i, stabilizer in enumerate(stabilizers_z):
            circuit_z.append({"name": "MPP", "target": stabilizer, 'p': 0})
            circuit_x.append({"name": "MPP", "target": stabilizer, 'p': 0})

        ##  在第一轮提取只能比较其中一种稳定子
        if _ == 0:
            for i in range(stabilizer_number_z):
                circuit_z.append({"name": "DETECTOR", "target": [-stabilizer_number_z + i]})
            for i in range(stabilizer_number_x):
                circuit_x.append({"name": "DETECTOR", "target": [-stabilizer_number_z-stabilizer_number_x + i]})

        ##  其他轮可以比较所有的稳定子
        else:
            for i in range(stabilizer_number_x+stabilizer_number_z):
                circuit_z.append({"name": "DETECTOR", "target": [-i - 1, -i - stabilizer_number_x-stabilizer_number_z - 1]})
                circuit_x.append({"name": "DETECTOR", "target": [-i - 1, -i - stabilizer_number_x-stabilizer_number_z - 1]})

    ##  执行横向测量
    for i in range(code.physical_number):
        circuit_x.append({"name": "MPP", "target": PauliOperator([i], [], 1), 'p': 0})
        circuit_z.append({"name": "MPP", "target": PauliOperator([], [i], 1), 'p': 0})

    ##  计算X稳定子与横向测量的关系
    for i, stabilizer in enumerate(stabilizers_x):
        target = []
        for index in stabilizer.occupy_x:
            target.append(-code.physical_number + index)
        target.append(-code.physical_number - stabilizer_number_x-stabilizer_number_z + i)
        circuit_x.append({'name': 'DETECTOR', 'target': target})

    ##  计算Z稳定子与横向测量的关系
    for i, stabilizer in enumerate(stabilizers_z):
        target = []
        for index in stabilizer.occupy_z:
            target.append(-code.physical_number + index)
        target.append(-code.physical_number - stabilizer_number_z + i)
        circuit_z.append({'name': 'DETECTOR', 'target': target})

    ##  生成逻辑可观测量
    for i in range(len(logical_x)):
        circuit_z.append({"name": "MPP", "target": logical_z[i]})
        circuit_x.append({"name": "MPP", "target": logical_x[i]})
        circuit_z.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit_z._measurements) - 1]})
        circuit_x.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit_x._measurements) - 1]})

    ##  PART：----返回结果----
    return circuit_x, circuit_z


##  CHAPTER：====Details====
def _PauliCSSCode2CircuitLevelCircuit(code: PauliCSSCode, cycle_number: int) -> tuple[Circuit, Circuit]:
    """
    input.code: 某个PauliCSSCode.
    input.cycle_number: Syndrome measurements circuit轮次
    output：X和Z两种测试线路
    """

    ##  PART：----准备材料----
    stabilizers_x = code.generators_x
    stabilizers_z = code.generators_z
    logical_x = code.logical_operators_x
    logical_z = code.logical_operators_z
    stabilizer_number_x = len(stabilizers_x)
    stabilizer_number_z = len(stabilizers_z)
    data_number = code.physical_number
    pauli_number = data_number + stabilizer_number_x + stabilizer_number_z

    ##  PART：----生成线路----
    ##  线路初始化
    circuit_x = Circuit()
    circuit_z = Circuit()
    circuit_x.append({'name': 'TRAP', 'majorana_number': 0, 'pauli_number': pauli_number})
    circuit_z.append({'name': 'TRAP', 'majorana_number': 0, 'pauli_number': pauli_number})
    circuit_z.append({'name': 'TICK'})
    circuit_x.append({'name': 'TICK'})
    circuit_x.append({'name': 'H', 'target': list(range(data_number))})

    ##  添加均匀的去极化噪声
    for i in range(pauli_number):
        circuit_z.append({"name": "DEPOLARIZE1", "target": i, "p": 0})
        circuit_x.append({"name": "DEPOLARIZE1", "target": i, "p": 0})
    circuit_z.append({'name': 'TICK'})
    circuit_x.append({'name': 'TICK'})

    ##  生成d轮syndrome测量线路
    for _ in range(cycle_number):

        ##  测量所有的稳定子
        for i, stabilizer in enumerate(stabilizers_x):
            sequence_temp = _syndrome_pauli_css_measurement_circuit(stabilizer, i + data_number, 'x')
            for temp in sequence_temp:
                circuit_z.append(temp)
                circuit_x.append(temp)
            circuit_z.append({'name': 'TICK'})
            circuit_x.append({'name': 'TICK'})
        for i, stabilizer in enumerate(stabilizers_z):
            sequence_temp = _syndrome_pauli_css_measurement_circuit(stabilizer, i + data_number + len(stabilizers_x), 'z')
            for temp in sequence_temp:
                circuit_z.append(temp)
                circuit_x.append(temp)
            circuit_z.append({'name': 'TICK'})
            circuit_x.append({'name': 'TICK'})

        ##  第一轮只能比较一半
        if _ == 0:
            for i in range(stabilizer_number_z):
                circuit_z.append({"name": "DETECTOR", "target": [-stabilizer_number_z + i]})
            for i in range(stabilizer_number_x):
                circuit_x.append({"name": "DETECTOR", "target": [-stabilizer_number_x-stabilizer_number_z + i]})

        ##  后续轮可以比较所有的稳定子
        else:
            for i in range(stabilizer_number_x+stabilizer_number_z):
                circuit_z.append({"name": "DETECTOR", "target": [-i - 1, -i - stabilizer_number_x-stabilizer_number_z - 1]})
                circuit_x.append({"name": "DETECTOR", "target": [-i - 1, -i - stabilizer_number_x-stabilizer_number_z - 1]})

    ##  横向测量
    for i in range(code.physical_number):
        circuit_x.append({"name": "MPP", "target": PauliOperator([i], [], 1), 'p': 0})
        circuit_z.append({"name": "MPP", "target": PauliOperator([], [i], 1), 'p': 0})

    ##  计算X稳定子和横向测量的关系
    for i, stabilizer in enumerate(stabilizers_x):
        target = []
        for index in stabilizer.occupy_x:
            target.append(-code.physical_number + index)
        target.append(-code.physical_number - stabilizer_number_x-stabilizer_number_z + i)
        circuit_x.append({'name': 'DETECTOR', 'target': target})

    ##  计算Z稳定子和横向测量的关系
    for i, stabilizer in enumerate(stabilizers_z):
        target = []
        for index in stabilizer.occupy_z:
            target.append(-code.physical_number + index)
        target.append(-code.physical_number - stabilizer_number_z + i)
        circuit_z.append({'name': 'DETECTOR', 'target': target})

    ##  生成逻辑可观测量
    for i in range(len(logical_x)):
        circuit_z.append({"name": "MPP", "target": logical_z[i]})
        circuit_x.append({"name": "MPP", "target": logical_x[i]})
        circuit_z.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit_z._measurements) - 1]})
        circuit_x.append({"name": "OBSERVABLE_INCLUDE", "target": [len(circuit_x._measurements) - 1]})

    ##  PART：----返回结果----
    return circuit_x, circuit_z


##  CHAPTER：====Majorana stabilizer测量线路====
def _syndrome_majorana_css_measurement_circuit(stabilizer: MajoranaOperator, qubit_index: int, type: str) -> list[dict]:
    """
    input.stabilizer: 代表Majorana stabilizer的Majorana operator.
    input.qubit_index: 代表提取到的qubit的位置
    input.type: 代表测量类型的字符串，只能是'x', 'X', 'z', 'Z', 'n', 'N'.
    output: 测量线路的Circuit sequence.
    """

    ##  PART：----准备工作----
    sequence = []
    flag = True
    if type == 'x' or type == 'X':
        occupy = stabilizer.occupy_x
    elif type == 'z' or type == 'Z':
        occupy = stabilizer.occupy_z
    elif type == 'n' or type == 'N':
        assert np.all(stabilizer.occupy_z == stabilizer.occupy_x)
        occupy = stabilizer.occupy_x
    else:
        raise ValueError

    ##  PART：----Majorana stabilizer测量线路：对于N的----
    if type == 'n' or type == 'N':
        for j in range(len(occupy)):
            majorana_index_now = occupy[j]
            sequence.append({'name': 'CNX', 'target': [majorana_index_now, qubit_index], })
            sequence.append({'name': 'MIXTURE', 'target': [majorana_index_now, qubit_index], 'p': 0})

    ##  PART：----Majorana stabilizer测量线路：对于X和Z的----
    elif type == 'x' or type == 'X' or type == 'z' or type == 'Z':

        ##  对齐qubit
        sequence.append({'name': 'X', 'target': qubit_index})
        sequence.append({'name': 'DEPOLARIZE1', 'target': qubit_index, 'p': 0})

        ##  添加下阶梯线路
        for j in range(len(occupy)):
            majorana_index_now = occupy[j]  # 当前所在的fermionic site

            ##  执行fermionic site到qubit的桥接
            if j == len(occupy) - 1:
                sequence.append({'name': 'CNX', 'target': [majorana_index_now, qubit_index], })
                sequence.append({'name': 'MIXTURE', 'target': [majorana_index_now, qubit_index], 'p': 0})
                break

            ##  添加fermionic sites之间的纠缠
            majorana_index_down = occupy[j + 1]
            if flag:
                if type == 'x' or type == 'X':
                    order_target = [majorana_index_down, majorana_index_now]
                elif type == 'z' or type == 'Z':
                    order_target = [majorana_index_now, majorana_index_down]
                else:
                    raise ValueError
                sequence.append({"name": "BRAID", "target": order_target,})
                sequence.append({'name': 'FDEPOLARIZE2', 'target': order_target, 'p': 0})
                flag = False
            else:
                sequence.append({'name': 'CNN', 'target': [majorana_index_now, majorana_index_down], })
                sequence.append({'name': 'FDEPOLARIZE2', 'target': [majorana_index_now, majorana_index_down], 'p': 0})
                flag = True

        ##  添加上阶梯线路
        flag = True
        for j in range(len(occupy) - 1):
            majorana_index_now = occupy[-1 - j]  # Current fermionic site
            majorana_index_up = occupy[-1 - j - 1]  # Previous fermionic site
            if flag:
                if type == 'x' or type == 'X':
                    order_target = [majorana_index_now, majorana_index_up]
                elif type == 'z' or type == 'Z':
                    order_target = [majorana_index_up, majorana_index_now]
                else:
                    raise ValueError
                sequence.append({'name': 'N', 'target': [majorana_index_now]})
                sequence.append({'name': 'BRAID', 'target': order_target})
                sequence.append({'name': 'N', 'target': [majorana_index_now]})
                sequence.append({'name': 'FDEPOLARIZE2', 'target': order_target, 'p': 0})
                flag = False
            else:
                sequence.append({'name': 'CNN', 'target': [majorana_index_now, majorana_index_up]})
                sequence.append({'name': 'FDEPOLARIZE2', 'target': [majorana_index_now, majorana_index_up], 'p': 0})
                flag = True

    ##  在qubit上提取syndrome
    sequence.append({'name': 'MZ', 'target': qubit_index, 'p': 0})
    sequence.append({'name': 'R', 'target': qubit_index})
    sequence.append({'name': 'DEPOLARIZE1', 'target': qubit_index, 'p': 0})

    ##  PART：----返回线路----
    return sequence


##  CHAPTER：====Details====
def _syndrome_pauli_css_measurement_circuit(stabilizer: PauliOperator, qubit_index: int, type: str) -> list[dict]:
    """
    input.stabilizer：代表stabilizer的Pauli operator
    input.qubit_index：代表测量的qubit索引
    input.type：代表测量类型，只能是'x'、'X'、'z'或'Z'
    output：测量线路的circuit sequence
    """

    ##  PART：----准备工作----
    sequence = []
    if type == 'x' or type == 'X':
        occupy = stabilizer.occupy_x
    elif type == 'z' or type == 'Z':
        occupy = stabilizer.occupy_z
    else:
        raise ValueError

    ##  PART：----添加CNOT门将错误综合----
    if type == 'X' or type == 'x':
        sequence.append({'name': 'H', 'target': qubit_index})
        sequence.append({'name': 'DEPOLARIZE1', 'target': qubit_index, 'p': 0})
    for j in range(len(occupy)):
        if type == 'Z' or type == 'z':
            sequence.append({'name': 'CX', 'target': [occupy[j], qubit_index]})
            sequence.append({'name': 'DEPOLARIZE2', 'target': [occupy[j], qubit_index], 'p': 0})
        elif type == 'X' or type == 'x':
            sequence.append({'name': 'CX', 'target': [qubit_index, occupy[j]]})
            sequence.append({'name': 'DEPOLARIZE2', 'target': [occupy[j], qubit_index], 'p': 0})
        else:
            raise ValueError
    if type == 'X' or type == 'x':
        sequence.append({'name': 'H', 'target': qubit_index})
        sequence.append({'name': 'DEPOLARIZE1', 'target': qubit_index, 'p': 0})

    ##  在ancilla qubit上提取syndrome
    sequence.append({'name': 'MZ', 'target': qubit_index, 'p': 0})
    sequence.append({'name': 'R', 'target': qubit_index})
    sequence.append({'name': 'DEPOLARIZE1', 'target': qubit_index, 'p': 0})

    ##  PART：----返回线路----
    return sequence
