microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.27.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/npm/qsharp/src/data-structures/circuit.ts

275lines · modeblame

32f9dba0Scott Carda1 years ago1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT license.
3
4import { isRegister, Register } from "./register.js";
5
6/**
7* Current format version.
8*/
9export const CURRENT_VERSION = 1;
10
11export interface CircuitGroup {
12circuits: Circuit[];
13version: number;
14}
15
16/**
17* Runtime check: is this a valid CircuitGroup?
18*/
19export function isCircuitGroup(obj: any): obj is CircuitGroup {
20return (
21obj &&
22typeof obj === "object" &&
23typeof obj.version === "number" &&
24Array.isArray(obj.circuits) &&
25obj.circuits.length > 0 &&
26obj.circuits.every(isCircuit)
27);
28}
29
30/**
31* Circuit to be visualized.
32*/
33export interface Circuit {
34/** Array of qubit resources. */
35qubits: Qubit[];
36componentGrid: ComponentGrid;
37}
38
39/**
40* Runtime check: is this a valid Circuit?
41*/
42export function isCircuit(obj: any): obj is Circuit {
43return (
44obj &&
45typeof obj === "object" &&
46Array.isArray(obj.qubits) &&
47obj.qubits.every(isQubit) &&
48Array.isArray(obj.componentGrid) &&
49obj.componentGrid.every(isColumn)
50);
51}
52
53export type ComponentGrid = Column[];
54
55export interface Column {
56components: Component[];
57}
58
59/**
60* Runtime check: is this a valid Column?
61*/
62export function isColumn(obj: any): obj is Column {
63return (
64obj &&
65typeof obj === "object" &&
66Array.isArray(obj.components) &&
67obj.components.every(isOperation)
68);
69}
70
71/**
72* Represents a component of a circuit. Currently, the only component is an operation.
73* In the future, this may be extended to include other components.
74*/
75export type Component = Operation;
76
77/**
78* Represents a unique qubit resource bit.
79*/
80export interface Qubit {
81/** Qubit ID. */
82id: number;
83/** Number of measurement results associated to the qubit. */
84numResults?: number;
c1ca1a24Mine Starks9 months ago85/** Declaration locations in the source code. */
86declarations?: SourceLocation[];
32f9dba0Scott Carda1 years ago87}
88
89/**
90* Runtime check: is this a valid Qubit?
91*/
92export function isQubit(obj: any): obj is Qubit {
93return (
94obj &&
95typeof obj === "object" &&
96typeof obj.id === "number" &&
97// numResults is optional, but if present must be a number
98(obj.numResults === undefined || typeof obj.numResults === "number")
99);
100}
101
102/**
103* Base type for operations.
104*/
105export interface BaseOperation {
106/** Gate label. */
107gate: string;
108/** Formatted gate arguments. */
109args?: string[];
110/** The parameters expected for the operation. */
111params?: Parameter[];
112/** Nested operations within this operation. */
113children?: ComponentGrid;
114
115/** Custom data attributes to attach to gate element.
116Note that this is never written to file, so it is not part of the circuit schema */
117dataAttributes?: DataAttributes;
118
4b8065afMine Starks5 months ago119/** Whether gate is a classically controlled operation. */
32f9dba0Scott Carda1 years ago120isConditional?: boolean;
760216a9Mine Starks8 months ago121
122/** Not written to file */
123metadata?: Metadata;
32f9dba0Scott Carda1 years ago124}
125
126/**
127* Runtime check: is this a valid BaseOperation?
128*/
129function isBaseOperation(obj: any): obj is BaseOperation {
130return (
131obj &&
132typeof obj === "object" &&
133typeof obj.gate === "string" &&
134// args is optional, but if present must be an array of strings
135(obj.args === undefined ||
136(Array.isArray(obj.args) &&
137obj.args.every((arg: any) => typeof arg === "string"))) &&
138// params is optional, but if present must be an array of Parameter
139(obj.params === undefined ||
140(Array.isArray(obj.params) && obj.params.every(isParameter))) &&
141// children is optional, but if present must be a ComponentGrid
142(obj.children === undefined ||
143(Array.isArray(obj.children) && obj.children.every(isColumn))) &&
144// dataAttributes is optional, but if present must be an object with string values
145(obj.dataAttributes === undefined ||
146(typeof obj.dataAttributes === "object" &&
147obj.dataAttributes !== null &&
148Object.values(obj.dataAttributes).every(
149(val) => typeof val === "string",
150))) &&
151// isConditional is optional, but if present must be boolean
579fb3b8Scott Carda5 months ago152(obj.isConditional === undefined || typeof obj.isConditional === "boolean")
32f9dba0Scott Carda1 years ago153);
154}
155
156/**
157* Represents a measurement operation and the registers it acts on.
158*/
159export interface Measurement extends BaseOperation {
160/** Discriminator for the Operation type */
161kind: "measurement";
162/** The qubit registers the gate measures. */
163qubits: Register[];
164/** The classical registers the gate writes to. */
165results: Register[];
166}
167
168/**
169* Represents a unitary operation and the registers it acts on.
170*/
171export interface Unitary extends BaseOperation {
172/** Discriminator for the Operation type */
173kind: "unitary";
174/** Target registers the gate acts on. */
175targets: Register[];
176/** Control registers the gate acts on. */
177controls?: Register[];
178/** Whether gate is an adjoint operation. */
179isAdjoint?: boolean;
180}
181
182/**
183* Represents a gate that sets its targets to a specific state.
184*/
185export interface Ket extends BaseOperation {
186/** Discriminator for the Operation type */
187kind: "ket";
188/** Target registers the gate acts on. */
189targets: Register[];
190}
191
192/**
193* Union type for operations.
194*/
195export type Operation = Unitary | Measurement | Ket;
196
197/**
198* Runtime check: is this a valid Operation?
199*/
200export function isOperation(obj: any): obj is Operation {
201if (!isBaseOperation(obj)) return false;
202// Re-cast to any so we can check discriminated fields without narrowing
203const op: any = obj;
204if (op.kind === undefined || typeof op.kind !== "string") return false;
205switch (op.kind) {
206case "unitary":
207return (
208Array.isArray(op.targets) &&
209op.targets.every(isRegister) &&
210// controls is optional
211(op.controls === undefined ||
212(Array.isArray(op.controls) && op.controls.every(isRegister))) &&
213// isAdjoint is optional
214(op.isAdjoint === undefined || typeof op.isAdjoint === "boolean")
215);
216case "measurement":
217return (
218Array.isArray(op.qubits) &&
219op.qubits.every(isRegister) &&
220Array.isArray(op.results) &&
221op.results.every(isRegister)
222);
223case "ket":
224return Array.isArray(op.targets) && op.targets.every(isRegister);
225default:
226return false;
227}
228}
229
230/**
231* A parameter for an operation.
232*/
233export interface Parameter {
234/** Parameter name. */
235name: string;
236/** Parameter's Q# type. */
237type: string;
238}
239
240/**
241* Runtime check: is this a valid Parameter?
242*/
243export function isParameter(obj: any): obj is Parameter {
244return (
245obj &&
246typeof obj === "object" &&
247typeof obj.name === "string" &&
248typeof obj.type === "string"
249);
250}
251
252/**
253* Custom data attributes (e.g. data-{attr}="{val}")
254*/
255export interface DataAttributes {
256[attr: string]: string;
257}
c1ca1a24Mine Starks9 months ago258
259export interface SourceLocation {
260file: string;
261line: number;
262column: number;
263}
760216a9Mine Starks8 months ago264
265export interface Metadata {
266source?: SourceLocation;
267scopeLocation?: SourceLocation;
4b8065afMine Starks5 months ago268/**
269* For a classically controlled operation,
270* this maps control registers to the measurement result
271* IDs. Unlike the `result` field in `Register`, which are
272* specific to the qubit, these IDs are global across the circuit.
273*/
274controlResultIds?: [Register, number][];
760216a9Mine Starks8 months ago275}