microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
logo

Branches

Tags

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

Clone

HTTPS

Download ZIP

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

288lines · 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
119/** Whether gate is a conditional operation. */
120isConditional?: boolean;
121/** Specify conditions on when to render operation. */
122conditionalRender?: ConditionalRender;
760216a9Mine Starks8 months ago123
124/** Not written to file */
125metadata?: Metadata;
32f9dba0Scott Carda1 years ago126}
127
128/**
129* Runtime check: is this a valid BaseOperation?
130*/
131function isBaseOperation(obj: any): obj is BaseOperation {
132return (
133obj &&
134typeof obj === "object" &&
135typeof obj.gate === "string" &&
136// args is optional, but if present must be an array of strings
137(obj.args === undefined ||
138(Array.isArray(obj.args) &&
139obj.args.every((arg: any) => typeof arg === "string"))) &&
140// params is optional, but if present must be an array of Parameter
141(obj.params === undefined ||
142(Array.isArray(obj.params) && obj.params.every(isParameter))) &&
143// children is optional, but if present must be a ComponentGrid
144(obj.children === undefined ||
145(Array.isArray(obj.children) && obj.children.every(isColumn))) &&
146// dataAttributes is optional, but if present must be an object with string values
147(obj.dataAttributes === undefined ||
148(typeof obj.dataAttributes === "object" &&
149obj.dataAttributes !== null &&
150Object.values(obj.dataAttributes).every(
151(val) => typeof val === "string",
152))) &&
153// isConditional is optional, but if present must be boolean
154(obj.isConditional === undefined ||
155typeof obj.isConditional === "boolean") &&
156// conditionalRender is optional, but if present must be a valid enum value
157(obj.conditionalRender === undefined ||
158Object.values(ConditionalRender).includes(obj.conditionalRender))
159);
160}
161
162/**
163* Represents a measurement operation and the registers it acts on.
164*/
165export interface Measurement extends BaseOperation {
166/** Discriminator for the Operation type */
167kind: "measurement";
168/** The qubit registers the gate measures. */
169qubits: Register[];
170/** The classical registers the gate writes to. */
171results: Register[];
172}
173
174/**
175* Represents a unitary operation and the registers it acts on.
176*/
177export interface Unitary extends BaseOperation {
178/** Discriminator for the Operation type */
179kind: "unitary";
180/** Target registers the gate acts on. */
181targets: Register[];
182/** Control registers the gate acts on. */
183controls?: Register[];
184/** Whether gate is an adjoint operation. */
185isAdjoint?: boolean;
186}
187
188/**
189* Represents a gate that sets its targets to a specific state.
190*/
191export interface Ket extends BaseOperation {
192/** Discriminator for the Operation type */
193kind: "ket";
194/** Target registers the gate acts on. */
195targets: Register[];
196}
197
198/**
199* Union type for operations.
200*/
201export type Operation = Unitary | Measurement | Ket;
202
203/**
204* Runtime check: is this a valid Operation?
205*/
206export function isOperation(obj: any): obj is Operation {
207if (!isBaseOperation(obj)) return false;
208// Re-cast to any so we can check discriminated fields without narrowing
209const op: any = obj;
210if (op.kind === undefined || typeof op.kind !== "string") return false;
211switch (op.kind) {
212case "unitary":
213return (
214Array.isArray(op.targets) &&
215op.targets.every(isRegister) &&
216// controls is optional
217(op.controls === undefined ||
218(Array.isArray(op.controls) && op.controls.every(isRegister))) &&
219// isAdjoint is optional
220(op.isAdjoint === undefined || typeof op.isAdjoint === "boolean")
221);
222case "measurement":
223return (
224Array.isArray(op.qubits) &&
225op.qubits.every(isRegister) &&
226Array.isArray(op.results) &&
227op.results.every(isRegister)
228);
229case "ket":
230return Array.isArray(op.targets) && op.targets.every(isRegister);
231default:
232return false;
233}
234}
235
236/**
237* A parameter for an operation.
238*/
239export interface Parameter {
240/** Parameter name. */
241name: string;
242/** Parameter's Q# type. */
243type: string;
244}
245
246/**
247* Runtime check: is this a valid Parameter?
248*/
249export function isParameter(obj: any): obj is Parameter {
250return (
251obj &&
252typeof obj === "object" &&
253typeof obj.name === "string" &&
254typeof obj.type === "string"
255);
256}
257
258/**
259* Conditions on when to render the given operation.
260*/
261export enum ConditionalRender {
262/** Always rendered. */
263Always,
264/** Render classically-controlled operation when measurement is a zero. */
265OnZero,
266/** Render classically-controlled operation when measurement is a one. */
267OnOne,
268/** Render operation as a group of its nested operations. */
269AsGroup,
270}
271
272/**
273* Custom data attributes (e.g. data-{attr}="{val}")
274*/
275export interface DataAttributes {
276[attr: string]: string;
277}
c1ca1a24Mine Starks9 months ago278
279export interface SourceLocation {
280file: string;
281line: number;
282column: number;
283}
760216a9Mine Starks8 months ago284
285export interface Metadata {
286source?: SourceLocation;
287scopeLocation?: SourceLocation;
288}