1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// This code is part of Cqlib.
//
// (C) Copyright China Telecom Quantum Group 2026
//
// This code is licensed under the Apache License, Version 2.0. You may
// obtain a copy of this license in the LICENSE.txt file in the root directory
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.
//! # QCIS Parser and Serializer
//!
//! This module converts between QCIS text and cqlib's [`Circuit`](crate::circuit::Circuit)
//! IR. It covers the circuit-level QCIS instruction set used by this crate; pulse
//! and coupling-control instructions are intentionally outside this module.
//!
//! ## Text Format
//!
//! QCIS is line oriented. Each non-empty line has an opcode, one or more qubits,
//! and optional parameters:
//!
//! ```text
//! OPCODE Q0 [Q1 ...] [param ...]
//! ```
//!
//! Qubits are written as `Q<id>` with an unsigned decimal id. Parameters are
//! parsed as cqlib parameter expressions, so numeric values and expressions such
//! as `pi`, `pi/2`, and `theta` are accepted. Lines beginning with `//` and
//! inline text after `//` are ignored.
//!
//! ## Circuit Instructions
//!
//! The QCIS instructions represented directly by this module include all
//! cqlib standard gates except identity and global phase:
//!
//! - Single-qubit gates: `H`, `S`, `SD`, `T`, `TD`, `X`, `X2P`, `X2M`, `Y`,
//! `Y2P`, `Y2M`, and `Z`.
//! - Parameterized single-qubit gates: `RX`, `RXY`, `RY`, `RZ`, `U`, `XY`,
//! `XY2P`, `XY2M`, and `PHASE`.
//! - Multi-qubit gates: `RXX`, `RYY`, `RZX`, `RZZ`, `SWAP`, `CX`, `CCX`, `CY`,
//! `CZ`, `CRX`, `CRY`, `CRZ`, and `FSIM`.
//! - `I Qn t`: delay/no-op on `Qn` for `t` ticks. In QCIS, `t` must be a fixed
//! non-negative integer count whose unit is 0.5 ns, so `t = 1` means 0.5 ns.
//! This is represented as
//! [`Instruction::Delay`](crate::circuit::gate::Instruction::Delay), not as
//! cqlib's standard identity gate.
//! - `M Qn [Qm ...]`: measurement. Loading expands multi-qubit measurement to
//! per-qubit measurement operations; dumping preserves grouped `measure_bits`
//! operations when present.
//! - `B Qn [Qm ...]` or `Barrier Qn [Qm ...]`: barrier.
//!
//! The loader accepts `SDG` and `TDG` as aliases. The dumper normalizes them to
//! `SD` and `TD`.
//!
//! QCIS `I` is not an alias for the cqlib identity gate. To emit `I Qn t`, use
//! [`Circuit::delay`](crate::circuit::Circuit::delay). A standard identity gate
//! is rejected by the QCIS dumper to avoid losing the required duration.
//! `GPHASE` and [`StandardGate::GPhase`](crate::circuit::StandardGate::GPhase)
//! are also intentionally unsupported.
//!
//! ## Entry Points and Errors
//!
//! - [`load::load`] / [`load::from_path`] reads a QCIS file and returns
//! [`load::QcisParseError`] on failure.
//! - [`load::loads`] / [`load::from_str`] reads QCIS source from a string and
//! returns [`load::QcisParseError`] on failure.
//! - [`dump::dump`] / [`dump::to_path`] writes a circuit to a QCIS file and
//! returns [`dump::QcisDumpError`] on failure.
//! - [`dump::dumps`] / [`dump::to_string`] serializes a circuit to a QCIS string
//! and returns [`dump::QcisDumpError`] on failure.
//!
//! ## Usage
//!
//! ### Loading QCIS
//!
//! ```rust
//! use cqlib_core::ir::qcis::load::loads;
//!
//! let qcis = r#"
//! H Q0
//! CZ Q0 Q1
//! M Q0 Q1
//! "#;
//!
//! let circuit = loads(qcis).unwrap();
//! ```
//!
//! ### Dumping to QCIS
//!
//! ```rust
//! use cqlib_core::ir::qcis::dump::dumps;
//! use cqlib_core::circuit::{Circuit, Qubit};
//!
//! let mut circuit = Circuit::new(2);
//! circuit.h(Qubit::new(0)).unwrap();
//! circuit.cz(Qubit::new(0), Qubit::new(1)).unwrap();
//!
//! let qcis = dumps(&circuit).unwrap();
//! // Output: "H Q0\nCZ Q0 Q1\n"
//! ```
pub use ;
pub use ;