qsharp-lang 1.0.21-dev → 1.0.23-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/debug-service/debug-service.d.ts +2 -2
- package/dist/debug-service/debug-service.js +2 -2
- package/dist/language-service/language-service.d.ts +13 -1
- package/dist/language-service/language-service.js +48 -34
- package/dist/language-service/worker-proxy.js +2 -0
- package/dist/samples.generated.js +21 -1
- package/dist/vsdiagnostic.js +2 -1
- package/lib/node/qsc_wasm.cjs +52 -16
- package/lib/node/qsc_wasm.d.cts +20 -3
- package/lib/node/qsc_wasm_bg.wasm +0 -0
- package/lib/web/qsc_wasm.d.ts +23 -4
- package/lib/web/qsc_wasm.js +51 -16
- package/lib/web/qsc_wasm_bg.wasm +0 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { IQscEventTarget } from "../compiler/events.js";
|
|
|
3
3
|
import { IServiceProxy } from "../worker-proxy.js";
|
|
4
4
|
type QscWasm = typeof import("../../lib/node/qsc_wasm.cjs");
|
|
5
5
|
export interface IDebugService {
|
|
6
|
-
loadSource(path: string, source: string, entry: string | undefined): Promise<string>;
|
|
6
|
+
loadSource(path: string, source: string, target: "base" | "full", entry: string | undefined): Promise<string>;
|
|
7
7
|
getBreakpoints(path: string): Promise<IBreakpointSpan[]>;
|
|
8
8
|
getLocalVariables(): Promise<Array<IVariable>>;
|
|
9
9
|
captureQuantumState(): Promise<Array<IQuantumState>>;
|
|
@@ -20,7 +20,7 @@ export declare class QSharpDebugService implements IDebugService {
|
|
|
20
20
|
private debugService;
|
|
21
21
|
private code;
|
|
22
22
|
constructor(wasm: QscWasm);
|
|
23
|
-
loadSource(path: string, source: string, entry: string | undefined): Promise<string>;
|
|
23
|
+
loadSource(path: string, source: string, target: "base" | "full", entry: string | undefined): Promise<string>;
|
|
24
24
|
getStackFrames(): Promise<IStackFrame[]>;
|
|
25
25
|
evalNext(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
|
|
26
26
|
evalStepIn(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
|
|
@@ -12,9 +12,9 @@ export class QSharpDebugService {
|
|
|
12
12
|
this.wasm = wasm;
|
|
13
13
|
this.debugService = new wasm.DebugService();
|
|
14
14
|
}
|
|
15
|
-
async loadSource(path, source, entry) {
|
|
15
|
+
async loadSource(path, source, target, entry) {
|
|
16
16
|
this.code[path] = source;
|
|
17
|
-
return this.debugService.load_source(path, source, entry);
|
|
17
|
+
return this.debugService.load_source(path, source, target, entry);
|
|
18
18
|
}
|
|
19
19
|
async getStackFrames() {
|
|
20
20
|
const stack_frame_list = this.debugService.get_stack_frames();
|
|
@@ -13,7 +13,13 @@ export type LanguageServiceEvent = {
|
|
|
13
13
|
export interface ILanguageService {
|
|
14
14
|
updateConfiguration(config: IWorkspaceConfiguration): Promise<void>;
|
|
15
15
|
updateDocument(uri: string, version: number, code: string): Promise<void>;
|
|
16
|
+
updateNotebookDocument(notebookUri: string, version: number, cells: {
|
|
17
|
+
uri: string;
|
|
18
|
+
version: number;
|
|
19
|
+
code: string;
|
|
20
|
+
}[]): Promise<void>;
|
|
16
21
|
closeDocument(uri: string): Promise<void>;
|
|
22
|
+
closeNotebookDocument(notebookUri: string, cellUris: string[]): Promise<void>;
|
|
17
23
|
getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
|
|
18
24
|
getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
|
|
19
25
|
getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
|
|
@@ -38,7 +44,13 @@ export declare class QSharpLanguageService implements ILanguageService {
|
|
|
38
44
|
constructor(wasm: QscWasm);
|
|
39
45
|
updateConfiguration(config: IWorkspaceConfiguration): Promise<void>;
|
|
40
46
|
updateDocument(documentUri: string, version: number, code: string): Promise<void>;
|
|
47
|
+
updateNotebookDocument(notebookUri: string, version: number, cells: {
|
|
48
|
+
uri: string;
|
|
49
|
+
version: number;
|
|
50
|
+
code: string;
|
|
51
|
+
}[]): Promise<void>;
|
|
41
52
|
closeDocument(documentUri: string): Promise<void>;
|
|
53
|
+
closeNotebookDocument(documentUri: string, cellUris: string[]): Promise<void>;
|
|
42
54
|
getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
|
|
43
55
|
getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
|
|
44
56
|
getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
|
|
@@ -53,6 +65,6 @@ export declare class QSharpLanguageService implements ILanguageService {
|
|
|
53
65
|
removeEventListener<T extends LanguageServiceEvent["type"]>(type: T, listener: (event: Extract<LanguageServiceEvent, {
|
|
54
66
|
type: T;
|
|
55
67
|
}>) => void): void;
|
|
56
|
-
onDiagnostics(uri: string, version: number, diagnostics: VSDiagnostic[]): void;
|
|
68
|
+
onDiagnostics(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]): void;
|
|
57
69
|
}
|
|
58
70
|
export {};
|
|
@@ -19,10 +19,23 @@ export class QSharpLanguageService {
|
|
|
19
19
|
this.code[documentUri] = code;
|
|
20
20
|
this.languageService.update_document(documentUri, version, code);
|
|
21
21
|
}
|
|
22
|
+
async updateNotebookDocument(notebookUri, version, cells) {
|
|
23
|
+
// Note: If a cell was deleted, its uri & contents will remain in the map.
|
|
24
|
+
// This is harmless and it keeps the code simpler to just leave it this way
|
|
25
|
+
// instead of trying to maintain a perfect map.
|
|
26
|
+
for (const cell of cells) {
|
|
27
|
+
this.code[cell.uri] = cell.code;
|
|
28
|
+
}
|
|
29
|
+
this.languageService.update_notebook_document(notebookUri, cells);
|
|
30
|
+
}
|
|
22
31
|
async closeDocument(documentUri) {
|
|
23
32
|
delete this.code[documentUri];
|
|
24
33
|
this.languageService.close_document(documentUri);
|
|
25
34
|
}
|
|
35
|
+
async closeNotebookDocument(documentUri, cellUris) {
|
|
36
|
+
cellUris.forEach((uri) => delete this.code[uri]);
|
|
37
|
+
this.languageService.close_notebook_document(documentUri, cellUris);
|
|
38
|
+
}
|
|
26
39
|
async getCompletions(documentUri, offset) {
|
|
27
40
|
const code = this.code[documentUri];
|
|
28
41
|
if (code === undefined) {
|
|
@@ -32,9 +45,7 @@ export class QSharpLanguageService {
|
|
|
32
45
|
const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
|
|
33
46
|
const result = this.languageService.get_completions(documentUri, convertedOffset);
|
|
34
47
|
result.items.forEach((item) => item.additionalTextEdits?.forEach((edit) => {
|
|
35
|
-
|
|
36
|
-
edit.range.start = mappedSpan[edit.range.start];
|
|
37
|
-
edit.range.end = mappedSpan[edit.range.end];
|
|
48
|
+
updateSpanFromUtf8ToUtf16(edit.range, code);
|
|
38
49
|
}));
|
|
39
50
|
return result;
|
|
40
51
|
}
|
|
@@ -47,35 +58,40 @@ export class QSharpLanguageService {
|
|
|
47
58
|
const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
|
|
48
59
|
const result = this.languageService.get_hover(documentUri, convertedOffset);
|
|
49
60
|
if (result) {
|
|
50
|
-
|
|
51
|
-
result.span.start = mappedSpan[result.span.start];
|
|
52
|
-
result.span.end = mappedSpan[result.span.end];
|
|
61
|
+
updateSpanFromUtf8ToUtf16(result.span, code);
|
|
53
62
|
}
|
|
54
63
|
return result;
|
|
55
64
|
}
|
|
56
65
|
async getDefinition(documentUri, offset) {
|
|
57
|
-
|
|
58
|
-
if (
|
|
66
|
+
const sourceCode = this.code[documentUri];
|
|
67
|
+
if (sourceCode === undefined) {
|
|
59
68
|
log.error(`getDefinition: expected ${documentUri} to be in the document map`);
|
|
60
69
|
return undefined;
|
|
61
70
|
}
|
|
62
|
-
const convertedOffset = mapUtf16UnitsToUtf8Units([offset],
|
|
71
|
+
const convertedOffset = mapUtf16UnitsToUtf8Units([offset], sourceCode)[offset];
|
|
63
72
|
const result = this.languageService.get_definition(documentUri, convertedOffset);
|
|
64
73
|
if (result) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
let targetCode = this.code[result.source];
|
|
75
|
+
if (targetCode === undefined) {
|
|
76
|
+
// Inspect the URL protocol (equivalent to the URI scheme + ":").
|
|
77
|
+
// If the scheme is our library scheme, we need to call the wasm to
|
|
78
|
+
// provide the library file's contents to do the utf8->utf16 mapping.
|
|
79
|
+
const url = new URL(result.source);
|
|
80
|
+
if (url.protocol === qsharpLibraryUriScheme + ":") {
|
|
81
|
+
targetCode = wasm.get_library_source_content(url.pathname);
|
|
82
|
+
if (targetCode === undefined) {
|
|
83
|
+
log.error(`getDefinition: expected ${url} to be in the library`);
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
88
|
+
if (targetCode) {
|
|
89
|
+
updateSpanFromUtf8ToUtf16(result.span, targetCode);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// https://github.com/microsoft/qsharp/issues/851
|
|
93
|
+
log.error(`cannot do utf8->utf16 mapping for ${result.source} since contents are not available`);
|
|
94
|
+
}
|
|
79
95
|
}
|
|
80
96
|
return result;
|
|
81
97
|
}
|
|
@@ -102,12 +118,11 @@ export class QSharpLanguageService {
|
|
|
102
118
|
}
|
|
103
119
|
}
|
|
104
120
|
if (resultCode) {
|
|
105
|
-
|
|
106
|
-
result.span.start = mappedSpan[result.span.start];
|
|
107
|
-
result.span.end = mappedSpan[result.span.end];
|
|
121
|
+
updateSpanFromUtf8ToUtf16(result.span, resultCode);
|
|
108
122
|
references.push(result);
|
|
109
123
|
}
|
|
110
124
|
else {
|
|
125
|
+
// https://github.com/microsoft/qsharp/issues/851
|
|
111
126
|
log.error(`cannot do utf8->utf16 mapping for ${result.source} since contents are not available`);
|
|
112
127
|
}
|
|
113
128
|
}
|
|
@@ -128,9 +143,7 @@ export class QSharpLanguageService {
|
|
|
128
143
|
if (result) {
|
|
129
144
|
result.signatures = result.signatures.map((sig) => {
|
|
130
145
|
sig.parameters = sig.parameters.map((param) => {
|
|
131
|
-
|
|
132
|
-
param.label.start = mappedSpan[param.label.start];
|
|
133
|
-
param.label.end = mappedSpan[param.label.end];
|
|
146
|
+
updateSpanFromUtf8ToUtf16(param.label, sig.label);
|
|
134
147
|
return param;
|
|
135
148
|
});
|
|
136
149
|
return sig;
|
|
@@ -151,9 +164,7 @@ export class QSharpLanguageService {
|
|
|
151
164
|
const code = this.code[uri];
|
|
152
165
|
if (code) {
|
|
153
166
|
const mappedEdits = edits.map((edit) => {
|
|
154
|
-
|
|
155
|
-
edit.range.start = mappedSpan[edit.range.start];
|
|
156
|
-
edit.range.end = mappedSpan[edit.range.end];
|
|
167
|
+
updateSpanFromUtf8ToUtf16(edit.range, code);
|
|
157
168
|
return edit;
|
|
158
169
|
});
|
|
159
170
|
mappedChanges.push([uri, mappedEdits]);
|
|
@@ -171,9 +182,7 @@ export class QSharpLanguageService {
|
|
|
171
182
|
const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
|
|
172
183
|
const result = this.languageService.prepare_rename(documentUri, convertedOffset);
|
|
173
184
|
if (result) {
|
|
174
|
-
|
|
175
|
-
result.range.start = mappedSpan[result.range.start];
|
|
176
|
-
result.range.end = mappedSpan[result.range.end];
|
|
185
|
+
updateSpanFromUtf8ToUtf16(result.range, code);
|
|
177
186
|
}
|
|
178
187
|
return result;
|
|
179
188
|
}
|
|
@@ -203,7 +212,7 @@ export class QSharpLanguageService {
|
|
|
203
212
|
const event = new Event("diagnostics");
|
|
204
213
|
event.detail = {
|
|
205
214
|
uri,
|
|
206
|
-
version,
|
|
215
|
+
version: version ?? 0,
|
|
207
216
|
diagnostics: empty ? [] : mapDiagnostics(diagnostics, code),
|
|
208
217
|
};
|
|
209
218
|
this.eventHandler.dispatchEvent(event);
|
|
@@ -213,3 +222,8 @@ export class QSharpLanguageService {
|
|
|
213
222
|
}
|
|
214
223
|
}
|
|
215
224
|
}
|
|
225
|
+
function updateSpanFromUtf8ToUtf16(span, code) {
|
|
226
|
+
const mappedSpan = mapUtf8UnitsToUtf16Units([span.start, span.end], code);
|
|
227
|
+
span.start = mappedSpan[span.start];
|
|
228
|
+
span.end = mappedSpan[span.end];
|
|
229
|
+
}
|
|
@@ -4,7 +4,9 @@ import { createDispatcher, createProxy, } from "../worker-proxy.js";
|
|
|
4
4
|
const requests = {
|
|
5
5
|
updateConfiguration: "request",
|
|
6
6
|
updateDocument: "request",
|
|
7
|
+
updateNotebookDocument: "request",
|
|
7
8
|
closeDocument: "request",
|
|
9
|
+
closeNotebookDocument: "request",
|
|
8
10
|
getCompletions: "request",
|
|
9
11
|
getHover: "request",
|
|
10
12
|
getDefinition: "request",
|
|
@@ -32,16 +32,31 @@ export default [
|
|
|
32
32
|
{
|
|
33
33
|
"title": "Random Number Generator",
|
|
34
34
|
"shots": 1000,
|
|
35
|
+
"code": "/// # Sample\n/// Quantum Random Number Generator\n///\n/// # Description\n/// This program implements a quantum ranndom number generator by setting qubits\n/// in superposition and then using the measurement results as random bits.\nnamespace Sample {\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Intrinsic;\n\n @EntryPoint()\n operation Main() : Result[] {\n // Generate 5-bit random number.\n let nBits = 5;\n return GenerateNRandomBits(nBits);\n }\n\n /// # Summary\n /// Generates N random bits.\n operation GenerateNRandomBits(nBits : Int) : Result[] {\n // Allocate N qubits.\n use register = Qubit[nBits];\n\n // Set the qubits into superposition of 0 and 1 using the Hadamard\n // operation `H`.\n for qubit in register {\n H(qubit);\n }\n\n // At this point each has 50% chance of being measured in the |0〉 state\n // and 50% chance of being measured in the |1〉 state.\n // Measure each qubit and reset them all so they can be safely\n // deallocated.\n let results = MeasureEachZ(register);\n ResetAll(register);\n return results;\n }\n}\n"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"title": "Random Number Generator (Advanced)",
|
|
39
|
+
"shots": 1000,
|
|
35
40
|
"code": "/// # Sample\n/// Quantum Random Number Generator\n///\n/// # Description\n/// This program implements a quantum ranndom number generator by setting qubits\n/// in superposition and then using the measurement results as random bits.\nnamespace Sample {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Intrinsic;\n open Microsoft.Quantum.Math;\n\n @EntryPoint()\n operation Main() : Int {\n let max = 100;\n Message($\"Sampling a random number between 0 and {max}: \");\n\n // Generate random number in the 0..max range.\n return GenerateRandomNumberInRange(max);\n }\n\n /// # Summary\n /// Generates a random number between 0 and `max`.\n operation GenerateRandomNumberInRange(max : Int) : Int {\n // Determine the number of bits needed to represent `max` and store it\n // in the `nBits` variable. Then generate `nBits` random bits which will\n // represent the generated random number.\n mutable bits = [];\n let nBits = BitSizeI(max);\n for idxBit in 1..nBits {\n set bits += [GenerateRandomBit()];\n }\n let sample = ResultArrayAsInt(bits);\n\n // Return random number if it is within the requested range.\n // Generate it again if it is outside the range.\n return sample > max ? GenerateRandomNumberInRange(max) | sample;\n }\n\n /// # Summary\n /// Generates a random bit.\n operation GenerateRandomBit() : Result {\n // Allocate a qubit.\n use q = Qubit();\n\n // Set the qubit into superposition of 0 and 1 using the Hadamard \n // operation `H`.\n H(q);\n\n // At this point the qubit `q` has 50% chance of being measured in the\n // |0〉 state and 50% chance of being measured in the |1〉 state.\n // Measure the qubit value using the `M` operation, and store the\n // measurement value in the `result` variable.\n let result = M(q);\n\n // Reset qubit to the |0〉 state.\n // Qubits must be in the |0〉 state by the time they are released.\n Reset(q);\n\n // Return the result of the measurement.\n return result;\n\n // Note that Qubit `q` is automatically released at the end of the block.\n }\n}\n"
|
|
36
41
|
},
|
|
37
42
|
{
|
|
38
43
|
"title": "Deutsch-Jozsa",
|
|
39
44
|
"shots": 1,
|
|
45
|
+
"code": "/// # Sample\n/// Deutsch–Jozsa algorithm\n///\n/// # Description\n/// Deutsch–Jozsa is a quantum algorithm that determines whether a given Boolean\n/// function 𝑓 is constant (0 on all inputs or 1 on all inputs) or balanced\n/// (1 for exactly half of the input domain and 0 for the other half).\n///\n/// This Q# program implements the Deutsch–Jozsa algorithm.\nnamespace Sample {\n\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : (Result[], Result[]) {\n // A Boolean function is a function that maps bits trings to a bit:\n // 𝑓 : {0, 1}^n → {0, 1}.\n\n // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings 𝑥⃗ and\n // 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true for exactly half of\n // its inputs.\n\n // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉 =\n // |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or is\n // balanced, then the Deutsch–Jozsa algorithm decides between these\n // cases with a single application of 𝑈.\n\n // Here, we demonstrate the use of the Deutsch-Jozsa algorithm by\n // determining the type (constant or balanced) of a couple of functions.\n let balancedResults = DeutschJozsa(SimpleBalancedBoolF, 5);\n let constantResults = DeutschJozsa(SimpleConstantBoolF, 5);\n return (balancedResults, constantResults);\n }\n\n /// # Summary\n /// This operation implements the DeutschJozsa algorithm.\n /// It returns the query register measurement results. If all the measurement\n /// results are `Zero`, the function is constant. If at least one measurement\n /// result is `One`, the function is balanced.\n /// It is assumed that the function is either constant or balanced.\n ///\n /// # Input\n /// ## Uf\n /// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, where 𝑓 is a\n /// Boolean function, 𝑥 is an 𝑛 bit register and 𝑦 is a single qubit.\n /// ## n\n /// The number of bits in the input register |𝑥〉.\n ///\n /// # Output\n /// An array of measurement results for the query reguster.\n /// All `Zero` measurement results indicate that the function is constant.\n /// At least one `One` measurement result in the array indicates that the\n /// function is balanced.\n ///\n /// # See Also\n /// - For details see Section 1.4.3 of Nielsen & Chuang.\n ///\n /// # References\n /// - [ *Michael A. Nielsen , Isaac L. Chuang*,\n /// Quantum Computation and Quantum Information ]\n /// (http://doi.org/10.1017/CBO9780511976667)\n operation DeutschJozsa(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Result[] {\n // We allocate n + 1 clean qubits. Note that the function `Uf` is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n // Now, a Hadamard transform is applied to each of the qubits.\n H(target);\n // We use a within-apply block to ensure that the Hadamard transform is\n // correctly inverted on the |𝑥〉 register.\n within {\n for q in queryRegister {\n H(q);\n }\n } apply {\n // We apply Uf to the n+1 qubits, computing |𝑥, 𝑦〉 ↦ |𝑥, 𝑦 ⊕ 𝑓(𝑥)〉.\n Uf(queryRegister, target);\n }\n\n // Measure the query register and reset all qubits so they can be safely\n // deallocated.\n let results = MeasureEachZ(queryRegister);\n ResetAll(queryRegister);\n Reset(target);\n return results;\n }\n\n // Simple constant Boolean function\n operation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n }\n\n // Simple balanced Boolean function\n operation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n }\n}\n\n"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"title": "Deutsch-Jozsa (Advanced)",
|
|
49
|
+
"shots": 1,
|
|
40
50
|
"code": "/// # Sample\n/// Deutsch–Jozsa algorithm\n///\n/// # Description\n/// Deutsch–Jozsa is a quantum algorithm that determines whether a given Boolean\n/// function 𝑓 is constant (0 on all inputs or 1 on all inputs) or balanced\n/// (1 for exactly half of the input domain and 0 for the other half).\n///\n/// This Q# program implements the Deutsch–Jozsa algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Canon;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : (String, Bool)[] {\n // A Boolean function is a function that maps bits trings to a bit:\n // 𝑓 : {0, 1}^n → {0, 1}.\n\n // We say that 𝑓 is constant if 𝑓(𝑥⃗) = 𝑓(𝑦⃗) for all bitstrings 𝑥⃗ and\n // 𝑦⃗, and that 𝑓 is balanced if 𝑓 evaluates to true for exactly half of\n // its inputs.\n\n // If we are given a function 𝑓 as a quantum operation 𝑈 |𝑥〉|𝑦〉 =\n // |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, and are promised that 𝑓 is either constant or is\n // balanced, then the Deutsch–Jozsa algorithm decides between these\n // cases with a single application of 𝑈.\n\n // Here, we demonstrate the use of the Deutsch-Jozsa algorithm by\n // determining the type (constant or balanced) of various functions.\n let nameFunctionTypeTuples = [\n (\"SimpleConstantBoolF\", SimpleConstantBoolF, true),\n (\"SimpleBalancedBoolF\", SimpleBalancedBoolF, false),\n (\"ConstantBoolF\", ConstantBoolF, true),\n (\"BalancedBoolF\", BalancedBoolF, false)\n ];\n\n mutable results = [];\n for (name, fn, shouldBeConstant) in nameFunctionTypeTuples {\n let isConstant = DeutschJozsa(fn, 5);\n if (isConstant != shouldBeConstant) {\n let shouldBeConstantStr = shouldBeConstant ?\n \"constant\" | \n \"balanced\";\n fail $\"{name} should be detected as {shouldBeConstantStr}\";\n }\n\n let isConstantStr = isConstant ? \"constant\" | \"balanced\";\n Message($\"{name} is {isConstantStr}\");\n set results += [(name, isConstant)];\n }\n\n return results;\n }\n\n /// # Summary\n /// This operation implements the DeutschJozsa algorithm.\n /// It returns the Boolean value `true` if the function is constant and\n /// `false` if it is not.\n /// It is assumed that the function is either constant or balanced.\n ///\n /// # Input\n /// ## Uf\n /// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉, where 𝑓 is a\n /// Boolean function, 𝑥 is an 𝑛 bit register and 𝑦 is a single qubit.\n /// ## n\n /// The number of bits in the input register |𝑥〉.\n ///\n /// # Output\n /// A boolean value `true` that indicates that the function is constant and\n /// `false` that indicates that the function is balanced.\n ///\n /// # See Also\n /// - For details see Section 1.4.3 of Nielsen & Chuang.\n ///\n /// # References\n /// - [ *Michael A. Nielsen , Isaac L. Chuang*,\n /// Quantum Computation and Quantum Information ]\n /// (http://doi.org/10.1017/CBO9780511976667)\n operation DeutschJozsa(Uf : ((Qubit[], Qubit) => Unit), n : Int) : Bool {\n // We allocate n + 1 clean qubits. Note that the function `Uf` is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n // Now, a Hadamard transform is applied to each of the qubits.\n H(target);\n // We use a within-apply block to ensure that the Hadamard transform is\n // correctly inverted on the |𝑥〉 register.\n within {\n for q in queryRegister {\n H(q);\n }\n } apply {\n // We apply Uf to the n+1 qubits, computing |𝑥, 𝑦〉 ↦ |𝑥, 𝑦 ⊕ 𝑓(𝑥)〉.\n Uf(queryRegister, target);\n }\n\n // The following for-loop measures all qubits and resets them to the |0〉\n // state so that they can be safely deallocated at the end of the block.\n // The loop also sets `result` to `true` if all measurement results are\n // `Zero`, i.e. if the function is a constant function, and sets\n // `result` to `false` if not, which according to the assumption on 𝑓 \n // means that it must be balanced.\n mutable result = true;\n for q in queryRegister {\n if MResetZ(q) == One {\n set result = false;\n }\n }\n\n // Finally, the last qubit, which held the 𝑦-register, is reset.\n Reset(target);\n return result;\n }\n\n // Simple constant Boolean function\n operation SimpleConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n X(target);\n }\n\n // Simple balanced Boolean function\n operation SimpleBalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n CX(args[0], target);\n }\n\n // A more complex constant Boolean function.\n // It applies X to every input basis vector.\n operation ConstantBoolF(args : Qubit[], target : Qubit) : Unit {\n for i in 0..(2^Length(args))-1 {\n ApplyControlledOnInt(i, X, args, target);\n }\n }\n\n // A more complex balanced Boolean function.\n // It applies X to half of the input basis vectors.\n operation BalancedBoolF(args : Qubit[], target : Qubit) : Unit {\n for i in 0..2..(2^Length(args))-1 {\n ApplyControlledOnInt(i, X, args, target);\n }\n }\n}\n"
|
|
41
51
|
},
|
|
42
52
|
{
|
|
43
53
|
"title": "Bernstein–Vazirani",
|
|
44
54
|
"shots": 1,
|
|
55
|
+
"code": "/// # Sample\n/// Bernstein-Vazirani algorithm\n///\n/// # Description\n/// The Bernstein-Vazirani algorithm determines the value of a bit string\n/// encoded in a function.\n///\n/// This Q# program implements the Bernstein-Vazirani algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : Result[] {\n // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the form\n // 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ\n // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bit string that determines the\n // parity of 𝑓.\n\n // The Bernstein–Vazirani algorithm allows determining 𝑟 given a\n // quantum operation that implements\n // |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n\n // This entry point function of this program, `Main`, shows how to use\n // the `BernsteinVazirani` operation to determine the value of bitstring\n // 𝑟.\n let secretBitString = SecretBitStringAsBoolArray();\n let parityOperation = EncodeBitStringAsParityOperation(secretBitString);\n let decodedBitString = BernsteinVazirani(\n parityOperation, Length(secretBitString));\n\n return decodedBitString;\n }\n\n /// # Summary\n /// This operation implements the Bernstein-Vazirani quantum algorithm.\n /// This algorithm computes for a given Boolean function that is promised to\n /// be a parity 𝑓(𝑥₀, …, 𝑥ₙ₋₁) = Σᵢ 𝑟ᵢ 𝑥ᵢ a result in the form of a bit\n /// vector (𝑟₀, …, 𝑟ₙ₋₁) corresponding to the parity function.\n /// Note that it is promised that the function is actually a parity\n /// function.\n ///\n /// # Input\n /// ## Uf\n /// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉,\n /// where 𝑓 is a Boolean function that implements a parity Σᵢ 𝑟ᵢ 𝑥ᵢ.\n /// ## n\n /// The number of bits in the input register |𝑥〉.\n ///\n /// # Output\n /// An array of type `Result[]` that contains the parity 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁).\n ///\n /// # See Also\n /// - For details see Section 1.4.3 of Nielsen & Chuang.\n ///\n /// # References\n /// - [ *Ethan Bernstein and Umesh Vazirani*,\n /// SIAM J. Comput., 26(5), 1411–1473, 1997 ]\n /// (https://doi.org/10.1137/S0097539796300921)\n operation BernsteinVazirani(Uf : ((Qubit[], Qubit) => Unit), n : Int)\n : Result[] {\n // We allocate n + 1 clean qubits. Note that the function parameter Uf is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that a relative phase is\n // introduced when we apply a Hadamard gate later on and we can use\n // phase kickback when Uf is applied.\n X(target);\n\n within {\n // Now, a Hadamard transform is applied to each of the qubits. As\n // the last step before the measurement, a Hadamard transform is\n // applied to all qubits except the last one. We could also\n // transform the last qubit, but this would not affect the\n // final outcome.\n // We use a within-apply block to ensure that the Hadamard transform\n // is correctly inverted.\n ApplyToEachA(H, queryRegister);\n } apply {\n H(target);\n // We now apply Uf to the n+1 qubits, computing\n // |x, y〉 ↦ |x, y ⊕ f(x)〉.\n Uf(queryRegister, target);\n }\n\n // Measure all qubits and reset them to the |0〉 state so that they can\n // be safely deallocated at the end of the block.\n let resultArray = ForEach(MResetZ, queryRegister);\n\n // Finally, the last qubit, which held the y-register, is reset.\n Reset(target);\n\n // The result is already contained in resultArray so no further\n // post-processing is necessary.\n return resultArray;\n }\n\n /// # Summary\n /// Given bit string 𝑟⃗ = (r₀, …, rₙ₋₁), represented as an array of Booleans,\n /// this operation applies a unitary 𝑈 that acts on 𝑛 + 1 qubits as:\n /// 𝑈 |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉\n /// where 𝑓(𝑥) = Σᵢ 𝑥ᵢ 𝑟ᵢ mod 2.\n ///\n /// # Input\n /// ## bitStringAsBoolArray\n /// A bit string 𝑟⃗, represented as an array of Booleans, used to define the\n /// function 𝑓.\n /// ## xRegister\n /// Represents the |𝑥〉 register that 𝑈 acts on.\n /// ## yQubit\n /// Represents the |𝑦〉 qubit that 𝑈 acts on.\n operation ApplyParityOperation(\n bitStringAsBoolArray : Bool[],\n xRegister : Qubit[],\n yQubit : Qubit)\n : Unit {\n // `xRegister` muts have enough qubits to represent the integer.\n let requiredBits = Length(bitStringAsBoolArray);\n let availableQubits = Length(xRegister);\n Fact(\n availableQubits >= requiredBits,\n $\"The bitstring has {requiredBits} bits but the quantum register \" +\n $\"only has {availableQubits} qubits\");\n\n // Apply the quantum operations that encode the bit string.\n for (index, bit) in Enumerated(bitStringAsBoolArray) {\n if bit {\n CNOT(xRegister[index], yQubit);\n }\n }\n }\n\n /// # Summary\n /// This is a higher-order operation which returns an operation (Qubit[], Qubit) => () of the form\n /// U_f |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n /// We define 𝑓 by providing the bit string 𝑟⃗ as an integer.\n operation EncodeBitStringAsParityOperation(bitStringAsBoolArray : Bool[])\n : (Qubit[], Qubit) => Unit {\n return ApplyParityOperation(bitStringAsBoolArray, _, _);\n }\n\n /// # Summary\n /// Returns a particular bit string as an array of Booleans.\n function SecretBitStringAsBoolArray() : Bool[] {\n return [true, false, true, false, true];\n }\n}\n"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"title": "Bernstein–Vazirani (Advanced)",
|
|
59
|
+
"shots": 1,
|
|
45
60
|
"code": "/// # Sample\n/// Bernstein-Vazirani algorithm\n///\n/// # Description\n/// The Bernstein-Vazirani algorithm determines the value of a bit string\n/// encoded in a function.\n///\n/// This Q# program implements the Bernstein-Vazirani algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : Int[] {\n // Consider a function 𝑓(𝑥⃗) on bitstrings 𝑥⃗ = (𝑥₀, …, 𝑥ₙ₋₁) of the form\n // 𝑓(𝑥⃗) ≔ Σᵢ 𝑥ᵢ 𝑟ᵢ\n // where 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁) is an unknown bitstring that determines the\n // parity of 𝑓.\n\n // The Bernstein–Vazirani algorithm allows determining 𝑟 given a\n // quantum operation that implements\n // |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n\n // The entry point function of this program, `Main`, shows how to use\n // the `BernsteinVazirani` operation to determine the value of various\n // integers whose bits describe 𝑟.\n let nQubits = 10;\n\n // Use the Bernstein–Vazirani algorithm to determine the bit strings\n // that various integers represent.\n let integers = [127, 238, 512];\n mutable decodedIntegers = [];\n for integer in integers {\n // Create an operation that encodes a bit string represented by an\n // integer as a parity operation.\n let parityOperation = EncodeIntegerAsParityOperation(integer);\n\n // Use the parity operation as input to the Bernstein-Vazirani\n // algorithm to determine the bit string.\n let decodedBitString = BernsteinVazirani(parityOperation, nQubits);\n let decodedInteger = ResultArrayAsInt(decodedBitString);\n Fact(\n decodedInteger == integer,\n $\"Decoded integer {decodedInteger}, but expected {integer}.\");\n\n Message($\"Successfully decoded bit string as int: {decodedInteger}\");\n set decodedIntegers += [decodedInteger];\n }\n\n return decodedIntegers;\n }\n\n /// # Summary\n /// This operation implements the Bernstein-Vazirani quantum algorithm.\n /// This algorithm computes for a given Boolean function that is promised to\n /// be a parity 𝑓(𝑥₀, …, 𝑥ₙ₋₁) = Σᵢ 𝑟ᵢ 𝑥ᵢ a result in the form of a bit\n /// vector (𝑟₀, …, 𝑟ₙ₋₁) corresponding to the parity function.\n /// Note that it is promised that the function is actually a parity\n /// function.\n ///\n /// # Input\n /// ## Uf\n /// A quantum operation that implements |𝑥〉|𝑦〉 ↦ |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉,\n /// where 𝑓 is a Boolean function that implements a parity Σᵢ 𝑟ᵢ 𝑥ᵢ.\n /// ## n\n /// The number of bits in the input register |𝑥〉.\n ///\n /// # Output\n /// An array of type `Result[]` that contains the parity 𝑟⃗ = (𝑟₀, …, 𝑟ₙ₋₁).\n ///\n /// # See Also\n /// - For details see Section 1.4.3 of Nielsen & Chuang.\n ///\n /// # References\n /// - [ *Ethan Bernstein and Umesh Vazirani*,\n /// SIAM J. Comput., 26(5), 1411–1473, 1997 ]\n /// (https://doi.org/10.1137/S0097539796300921)\n operation BernsteinVazirani(Uf : ((Qubit[], Qubit) => Unit), n : Int)\n : Result[] {\n // We allocate n + 1 clean qubits. Note that the function Uf is defined\n // on inputs of the form (x, y), where x has n bits and y has 1 bit.\n use queryRegister = Qubit[n];\n use target = Qubit();\n\n // The last qubit needs to be flipped so that the function will actually\n // be computed into the phase when Uf is applied.\n X(target);\n\n within {\n // Now, a Hadamard transform is applied to each of the qubits. As\n // the last step before the measurement, a Hadamard transform is\n // applied to all qubits except last one. We could apply the\n // transform to the last qubit also, but this would not affect the\n // final outcome.\n // We use a within-apply block to ensure that the Hadamard transform\n // is correctly inverted.\n ApplyToEachA(H, queryRegister);\n } apply {\n H(target);\n // We now apply Uf to the n+1 qubits, computing\n // |x, y〉 ↦ |x, y ⊕ f(x)〉.\n Uf(queryRegister, target);\n }\n\n // Measure all qubits and reset them to the |0〉 state so that they can\n // be safely deallocated at the end of the block.\n let resultArray = ForEach(MResetZ, queryRegister);\n\n // Finally, the last qubit, which held the y-register, is reset.\n Reset(target);\n\n // The result is already contained in resultArray so no further\n // post-processing is necessary.\n return resultArray;\n }\n\n /// # Summary\n /// Given an integer that can be represented as a bit string\n /// 𝑟⃗ = (r₀, …, rₙ₋₁), this operation applies a unitary 𝑈 that acts on 𝑛 + 1\n /// qubits as:\n /// 𝑈 |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉\n /// where 𝑓(𝑥) = Σᵢ 𝑥ᵢ 𝑟ᵢ mod 2.\n ///\n /// # Input\n /// ## bitStringAsInt\n /// An integer that can be represented as a bit string 𝑟⃗ used to define the\n /// function 𝑓.\n /// ## xRegister\n /// Represents the |𝑥〉 register that 𝑈 acts on.\n /// ## yQubit\n /// Represents the |𝑦〉 qubit that 𝑈 acts on.\n operation ApplyParityOperation(\n bitStringAsInt : Int,\n xRegister : Qubit[],\n yQubit : Qubit)\n : Unit {\n // `xRegister` muts have enough qubits to represent the integer.\n let requiredBits = BitSizeI(bitStringAsInt);\n let availableQubits = Length(xRegister);\n Fact(\n availableQubits >= requiredBits,\n $\"Integer value {bitStringAsInt} requires {requiredBits} bits to \" +\n $\"be represented but the quantum register only has \" +\n $\"{availableQubits} qubits\");\n\n // Apply the quantum operations that encode the bit string.\n for index in IndexRange(xRegister) {\n if ((bitStringAsInt &&& 2^index) != 0) {\n CNOT(xRegister[index], yQubit);\n }\n }\n }\n\n /// # Summary\n /// Returns black-box operations (Qubit[], Qubit) => () of the form\n /// U_f |𝑥〉|𝑦〉 = |𝑥〉|𝑦 ⊕ 𝑓(𝑥)〉.\n /// We define 𝑓 by providing the bit string 𝑟⃗ as an integer.\n operation EncodeIntegerAsParityOperation(bitStringAsInt : Int)\n : (Qubit[], Qubit) => Unit {\n return ApplyParityOperation(bitStringAsInt, _, _);\n }\n}\n"
|
|
46
61
|
},
|
|
47
62
|
{
|
|
@@ -50,7 +65,12 @@ export default [
|
|
|
50
65
|
"code": "/// # Sample\n/// Grover's search algorithm\n///\n/// # Description\n/// Grover's search algorithm is a quantum algorithm that finds with high\n/// probability the unique input to a black box function that produces a\n/// particular output value.\n///\n/// This Q# program implements the Grover's search algorithm.\nnamespace Sample {\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Math;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Measurement;\n open Microsoft.Quantum.Diagnostics;\n\n @EntryPoint()\n operation Main() : Result[] {\n let nQubits = 5;\n\n // Grover's algorithm relies on performing a \"Grover iteration\" an\n // optimal number of times to maximize the probability of finding the\n // value we are searching for.\n // You can set the number iterations to a value lower than optimal to\n // intentionally reduce precision.\n let iterations = CalculateOptimalIterations(nQubits);\n Message($\"Number of iterations: {iterations}\");\n\n // Use Grover's algorithm to find a particular marked state.\n let results = GroverSearch(nQubits, iterations, ReflectAboutMarked);\n return results;\n }\n\n /// # Summary\n /// Implements Grover's algorithm, which searches all possible inputs to an\n /// operation to find a particular marked state.\n operation GroverSearch(\n nQubits : Int,\n iterations : Int,\n phaseOracle : Qubit[] => Unit) : Result[] {\n\n use qubits = Qubit[nQubits];\n\n // Initialize a uniform superposition over all possible inputs.\n PrepareUniform(qubits);\n\n // The search itself consists of repeatedly reflecting about the marked\n // state and our start state, which we can write out in Q# as a for loop.\n for _ in 1..iterations {\n phaseOracle(qubits);\n ReflectAboutUniform(qubits);\n }\n\n // Measure and return the answer.\n return MResetEachZ(qubits);\n }\n\n /// # Summary\n /// Returns the optimal number of Grover iterations needed to find a marked\n /// item, given the number of qubits in a register.\n function CalculateOptimalIterations(nQubits : Int) : Int {\n let nItems = 1 <<< nQubits; // 2^nQubits\n let angle = ArcSin(1. / Sqrt(IntAsDouble(nItems)));\n let iterations = Round(0.25 * PI() / angle - 0.5);\n return iterations;\n }\n\n /// # Summary\n /// Reflects about the basis state marked by alternating zeros and ones.\n /// This operation defines what input we are trying to find in the search.\n operation ReflectAboutMarked(inputQubits : Qubit[]) : Unit {\n Message(\"Reflecting about marked state...\");\n use outputQubit = Qubit();\n within {\n // We initialize the outputQubit to (|0⟩ - |1⟩) / √2, so that\n // toggling it results in a (-1) phase.\n X(outputQubit);\n H(outputQubit);\n // Flip the outputQubit for marked states.\n // Here, we get the state with alternating 0s and 1s by using the X\n // operation on every other qubit.\n for q in inputQubits[...2...] {\n X(q);\n }\n } apply {\n Controlled X(inputQubits, outputQubit);\n }\n }\n\n /// # Summary\n /// Given a register in the all-zeros state, prepares a uniform\n /// superposition over all basis states.\n operation PrepareUniform(inputQubits : Qubit[]) : Unit is Adj + Ctl {\n for q in inputQubits {\n H(q);\n }\n }\n\n /// # Summary\n /// Reflects about the all-ones state.\n operation ReflectAboutAllOnes(inputQubits : Qubit[]) : Unit {\n Controlled Z(Most(inputQubits), Tail(inputQubits));\n }\n\n /// # Summary\n /// Reflects about the uniform superposition state.\n operation ReflectAboutUniform(inputQubits : Qubit[]) : Unit {\n within {\n // Transform the uniform superposition to all-zero.\n Adjoint PrepareUniform(inputQubits);\n // Transform the all-zero state to all-ones\n for q in inputQubits {\n X(q);\n }\n } apply {\n // Now that we've transformed the uniform superposition to the\n // all-ones state, reflect about the all-ones state, then let the\n // within/apply block transform us back.\n ReflectAboutAllOnes(inputQubits);\n }\n }\n}\n"
|
|
51
66
|
},
|
|
52
67
|
{
|
|
53
|
-
"title": "Hidden
|
|
68
|
+
"title": "Hidden Shift",
|
|
69
|
+
"shots": 1,
|
|
70
|
+
"code": "/// # Sample\n/// Hidden shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nnamespace Sample {\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : Result[] {\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift encoded in the following array of\n // Booleans.\n let shiftAsBoolArray = [true, false, false, false, false, true];\n let shiftAsInt = BoolArrayAsInt(shiftAsBoolArray);\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shiftAsInt, register),\n Length(shiftAsBoolArray));\n\n return hiddenShiftBitString;\n }\n\n /// # Summary\n /// Implements a correlation-based algorithm to solve the hidden shift\n /// problem for bent functions.\n ///\n /// # Description\n /// Implements a solution for the hidden shift problem, which is to identify\n /// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n /// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n ///\n /// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n /// it is as far from linear as possible. In particular, bent functions have\n /// flat Fourier (Walsh–Hadamard) spectra.\n ///\n /// In this case, the Roetteler algorithm (see References, below) uses\n /// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n /// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n ///\n /// # Input\n /// ## Ufstar\n /// A quantum operation that implements\n /// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n /// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n /// ## Ug\n /// A quantum operation that implements\n /// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n /// where 𝑔 is a Boolean function that is shifted by unknown\n /// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n /// ## n\n /// The number of bits of the input register |𝑥〉.\n ///\n /// # Output\n /// An array of type `Result[]` which encodes the bit representation\n /// of the hidden shift.\n ///\n /// # References\n /// - [*Martin Roetteler*,\n /// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n /// (https://doi.org/10.1137/1.9781611973075.37)\n operation FindHiddenShift (\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int)\n : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return ForEach(MResetZ, qubits);\n }\n\n /// # Summary\n /// Implements an oracle for a bent function constructed from the inner\n /// product of Boolean functions.\n ///\n /// # Description\n /// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n /// is computed into the phase, i.e., a diagonal operator that maps\n /// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n /// the x_i are binary. The IP function is defined as\n /// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n /// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n /// of length u. Notice that the function IP is a Boolean function on n = 2u\n /// bits. IP is a special case of bent function. These are functions for\n /// which the Walsh-Hadamard transform is perfectly flat (in absolute\n /// value).\n /// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n /// function defines a +1/-1 function, i.e., gives rise to another Boolean\n /// function, called the dual bent function. Moreover, for the case of the\n /// IP function it can be shown that IP is equal to its own dual bent\n /// function.\n ///\n /// # Remarks\n /// Notice that a diagonal operator implementing IP between 2 variables y_0\n /// and z_0 is nothing but the AND function between those variables, i.e.,\n /// in phase encoding it is computed by a Controlled-Z gate.\n /// Extending this to an XOR of the AND of more variables, as required in\n /// the definition of the IP function can then be accomplished by applying\n /// several Controlled-Z gates between the respective inputs.\n operation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0 .. u - 1];\n let ys = register[u...];\n for index in 0..u-1 {\n CZ(xs[index], ys[index]);\n }\n }\n\n /// # Summary\n /// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n ///\n /// # Description\n /// For the hidden shift problem we need another function g which is related\n /// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n /// IP function by a given shift. Notice that the '+' operation here is the\n /// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n /// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n /// shifted version by applying a bit flip to the |x〉 register first, then\n /// applying the diagonal operation, and then undoing the bit flips to the\n /// |x〉 register. We use this principle to define shifted versions of the IP\n /// operation.\n operation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n }\n}\n"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"title": "Hidden Shift (Advanced)",
|
|
54
74
|
"shots": 1,
|
|
55
75
|
"code": "/// # Sample\n/// Hidden shift\n///\n/// # Description\n/// There is a family of problems known as hidden shift problems, in which it\n/// is given that two Boolean functions 𝑓 and 𝑔 satisfy the relation\n/// 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥\n/// where 𝑠 is a hidden bit string that we would like to find.\n///\n/// This Q# program implements an algorithm to solve the hidden shift problem.\nnamespace Sample {\n open Microsoft.Quantum.Arithmetic;\n open Microsoft.Quantum.Arrays;\n open Microsoft.Quantum.Convert;\n open Microsoft.Quantum.Diagnostics;\n open Microsoft.Quantum.Measurement;\n\n @EntryPoint()\n operation Main() : Int[] {\n let nQubits = 10;\n\n // Consider the case of finding a hidden shift 𝑠 between two Boolean\n // functions 𝑓(𝑥) and 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n // This problem can be solved on a quantum computer with one call to\n // each of 𝑓 and 𝑔 in the special case that both functions are bent;\n // that is, that they are as far from linear as possible.\n\n // Here, we find the hidden shift for various pairs of bent functions.\n let shifts = [170, 512, 999];\n mutable hiddenShifts = [];\n for shift in shifts {\n let hiddenShiftBitString = FindHiddenShift(\n BentFunction,\n register => ShiftedBentFunction(shift, register),\n nQubits);\n let hiddenShift = ResultArrayAsInt(hiddenShiftBitString);\n Fact(\n hiddenShift == shift,\n $\"Found shift {hiddenShift}, but expected {shift}.\");\n Message($\"Found {shift} successfully!\");\n set hiddenShifts += [hiddenShift];\n }\n\n return hiddenShifts;\n }\n\n /// # Summary\n /// Implements a correlation-based algorithm to solve the hidden shift\n /// problem for bent functions.\n ///\n /// # Description\n /// Implements a solution for the hidden shift problem, which is to identify\n /// an unknown shift 𝑠 of the arguments of two Boolean functions 𝑓 and 𝑔\n /// that are promised to satisfy the relation 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠) for all 𝑥.\n ///\n /// 𝑓 and 𝑔 are assumed to be bent functions. A Boolean function is bent if\n /// it is as far from linear as possible. In particular, bent functions have\n /// flat Fourier (Walsh–Hadamard) spectra.\n ///\n /// In this case, the Roetteler algorithm (see References, below) uses\n /// black-box oracles for 𝑓^* and 𝑔, where 𝑓^* is the dual bent function to\n /// 𝑓, and computes the hidden shift 𝑠 between 𝑓 and 𝑔.\n ///\n /// # Input\n /// ## Ufstar\n /// A quantum operation that implements\n /// $U_f^*: |𝑥〉 ↦ (-1)^{f^*(x)} |𝑥〉$,\n /// where $f^*$ is a Boolean function, 𝑥 is an $n$ bit register\n /// ## Ug\n /// A quantum operation that implements\n /// $U_g:|𝑥〉 ↦ (-1)^{g(x)} |𝑥〉$,\n /// where 𝑔 is a Boolean function that is shifted by unknown\n /// 𝑠 from 𝑓, and 𝑥 is an $n$ bit register.\n /// ## n\n /// The number of bits of the input register |𝑥〉.\n ///\n /// # Output\n /// An array of type `Result[]` which encodes the bit representation\n /// of the hidden shift.\n ///\n /// # References\n /// - [*Martin Roetteler*,\n /// Proc. SODA 2010, ACM, pp. 448-457, 2010]\n /// (https://doi.org/10.1137/1.9781611973075.37)\n operation FindHiddenShift (\n Ufstar : (Qubit[] => Unit),\n Ug : (Qubit[] => Unit),\n n : Int)\n : Result[] {\n // We allocate n clean qubits. Note that the function Ufstar and Ug are\n // unitary operations on n qubits defined via phase encoding.\n use qubits = Qubit[n];\n\n // First, a Hadamard transform is applied to each of the qubits.\n ApplyToEach(H, qubits);\n\n // We now apply the shifted function Ug to the n qubits, computing\n // |x〉 -> (-1)^{g(x)} |x〉.\n Ug(qubits);\n\n within {\n // A Hadamard transform is applied to each of the n qubits.\n ApplyToEachA(H, qubits);\n } apply {\n // we now apply the dual function of the unshifted function, i.e.,\n // Ufstar, to the n qubits, computing |x〉 -> (-1)^{fstar(x)} |x〉.\n Ufstar(qubits);\n }\n\n // Measure the n qubits and reset them to zero so that they can be\n // safely deallocated at the end of the block.\n return ForEach(MResetZ, qubits);\n }\n\n /// # Summary\n /// Implements an oracle for a bent function constructed from the inner\n /// product of Boolean functions.\n ///\n /// # Description\n /// This operation defines the Boolean function IP(x_0, ..., x_{n-1}) which\n /// is computed into the phase, i.e., a diagonal operator that maps\n /// |x〉 -> (-1)^{IP(x)} |x〉, where x stands for x=(x_0, ..., x_{n-1}) and all\n /// the x_i are binary. The IP function is defined as\n /// IP(y, z) = y_0 z_0 + y_1 z_1 + ... y_{u-1} z_{u-1} where\n /// y = (y_0, ..., y_{u-1}) and z = (z_0, ..., z_{u-1}) are two bit vectors\n /// of length u. Notice that the function IP is a Boolean function on n = 2u\n /// bits. IP is a special case of bent function. These are functions for\n /// which the Walsh-Hadamard transform is perfectly flat (in absolute\n /// value).\n /// Because of this flatness, the Walsh-Hadamard spectrum of any bent\n /// function defines a +1/-1 function, i.e., gives rise to another Boolean\n /// function, called the dual bent function. Moreover, for the case of the\n /// IP function it can be shown that IP is equal to its own dual bent\n /// function.\n ///\n /// # Remarks\n /// Notice that a diagonal operator implementing IP between 2 variables y_0\n /// and z_0 is nothing but the AND function between those variables, i.e.,\n /// in phase encoding it is computed by a Controlled-Z gate.\n /// Extending this to an XOR of the AND of more variables, as required in\n /// the definition of the IP function can then be accomplished by applying\n /// several Controlled-Z gates between the respective inputs.\n operation BentFunction(register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n let xs = register[0 .. u - 1];\n let ys = register[u...];\n for index in 0..u-1 {\n CZ(xs[index], ys[index]);\n }\n }\n\n /// # Summary\n /// Implements a shifted bend function 𝑔(𝑥) = 𝑓(𝑥 ⊕ 𝑠).\n ///\n /// # Description\n /// For the hidden shift problem we need another function g which is related\n /// to IP via g(x) = IP(x + s), i.e., we have to shift the argument of the\n /// IP function by a given shift. Notice that the '+' operation here is the\n /// Boolean addition, i.e., a bit-wise operation. Notice further, that in\n /// general a diagonal operation |x〉 -> (-1)^{f(x)} can be turned into a\n /// shifted version by applying a bit flip to the |x〉 register first, then\n /// applying the diagonal operation, and then undoing the bit flips to the\n /// |x〉 register. We use this principle to define shifted versions of the IP\n /// operation.\n operation ShiftedBentFunction(shift : Int, register : Qubit[]) : Unit {\n Fact(Length(register) % 2 == 0, \"Length of register must be even.\");\n let u = Length(register) / 2;\n within {\n // Flips the bits in shift.\n ApplyXorInPlace(shift, register);\n } apply {\n // Compute the IP function into the phase.\n BentFunction(register);\n }\n }\n}\n"
|
|
56
76
|
},
|
package/dist/vsdiagnostic.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
|
+
import { log } from "./log.js";
|
|
3
4
|
// The QSharp compiler returns positions in utf-8 code unit positions (basically a byte[]
|
|
4
5
|
// index), however VS Code and Monaco handle positions as utf-16 code unit positions
|
|
5
6
|
// (basically JavaScript string index positions). Thus the positions returned from the
|
|
@@ -94,7 +95,7 @@ function mapStringIndexes(buffer, indexes, sourceIndexType) {
|
|
|
94
95
|
// TODO: May want to have a more configurable error reporting at some point. Avoid throwing here,
|
|
95
96
|
// and just report and continue.
|
|
96
97
|
if (posArrayIndex < sortedIndexes.length) {
|
|
97
|
-
|
|
98
|
+
log.error(`Failed to map all ${sourceIndexType} indexes. Remaining indexes are: ${sortedIndexes.slice(posArrayIndex)}`);
|
|
98
99
|
}
|
|
99
100
|
return result;
|
|
100
101
|
}
|
package/lib/node/qsc_wasm.cjs
CHANGED
|
@@ -216,6 +216,16 @@ function passArray32ToWasm0(arg, malloc) {
|
|
|
216
216
|
return ptr;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
function passArrayJsValueToWasm0(array, malloc) {
|
|
220
|
+
const ptr = malloc(array.length * 4, 4) >>> 0;
|
|
221
|
+
const mem = getUint32Memory0();
|
|
222
|
+
for (let i = 0; i < array.length; i++) {
|
|
223
|
+
mem[ptr / 4 + i] = addHeapObject(array[i]);
|
|
224
|
+
}
|
|
225
|
+
WASM_VECTOR_LEN = array.length;
|
|
226
|
+
return ptr;
|
|
227
|
+
}
|
|
228
|
+
|
|
219
229
|
function getArrayJsValueFromWasm0(ptr, len) {
|
|
220
230
|
ptr = ptr >>> 0;
|
|
221
231
|
const mem = getUint32Memory0();
|
|
@@ -435,29 +445,32 @@ class DebugService {
|
|
|
435
445
|
/**
|
|
436
446
|
* @param {string} path
|
|
437
447
|
* @param {string} source
|
|
448
|
+
* @param {string} target_profile
|
|
438
449
|
* @param {string | undefined} entry
|
|
439
450
|
* @returns {string}
|
|
440
451
|
*/
|
|
441
|
-
load_source(path, source, entry) {
|
|
442
|
-
let
|
|
443
|
-
let
|
|
452
|
+
load_source(path, source, target_profile, entry) {
|
|
453
|
+
let deferred5_0;
|
|
454
|
+
let deferred5_1;
|
|
444
455
|
try {
|
|
445
456
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
446
457
|
const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
447
458
|
const len0 = WASM_VECTOR_LEN;
|
|
448
459
|
const ptr1 = passStringToWasm0(source, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
449
460
|
const len1 = WASM_VECTOR_LEN;
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
461
|
+
const ptr2 = passStringToWasm0(target_profile, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
462
|
+
const len2 = WASM_VECTOR_LEN;
|
|
463
|
+
var ptr3 = isLikeNone(entry) ? 0 : passStringToWasm0(entry, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
464
|
+
var len3 = WASM_VECTOR_LEN;
|
|
465
|
+
wasm.debugservice_load_source(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
|
453
466
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
|
454
467
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
|
455
|
-
|
|
456
|
-
|
|
468
|
+
deferred5_0 = r0;
|
|
469
|
+
deferred5_1 = r1;
|
|
457
470
|
return getStringFromWasm0(r0, r1);
|
|
458
471
|
} finally {
|
|
459
472
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
460
|
-
wasm.__wbindgen_export_2(
|
|
473
|
+
wasm.__wbindgen_export_2(deferred5_0, deferred5_1, 1);
|
|
461
474
|
}
|
|
462
475
|
}
|
|
463
476
|
/**
|
|
@@ -609,15 +622,11 @@ class LanguageService {
|
|
|
609
622
|
wasm.__wbg_languageservice_free(ptr);
|
|
610
623
|
}
|
|
611
624
|
/**
|
|
612
|
-
* @param {
|
|
625
|
+
* @param {(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]) => void} diagnostics_callback
|
|
613
626
|
*/
|
|
614
627
|
constructor(diagnostics_callback) {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
return LanguageService.__wrap(ret);
|
|
618
|
-
} finally {
|
|
619
|
-
heap[stack_pointer++] = undefined;
|
|
620
|
-
}
|
|
628
|
+
const ret = wasm.languageservice_new(addHeapObject(diagnostics_callback));
|
|
629
|
+
return LanguageService.__wrap(ret);
|
|
621
630
|
}
|
|
622
631
|
/**
|
|
623
632
|
* @param {IWorkspaceConfiguration} config
|
|
@@ -646,6 +655,28 @@ class LanguageService {
|
|
|
646
655
|
wasm.languageservice_close_document(this.__wbg_ptr, ptr0, len0);
|
|
647
656
|
}
|
|
648
657
|
/**
|
|
658
|
+
* @param {string} notebook_uri
|
|
659
|
+
* @param {(ICell)[]} cells
|
|
660
|
+
*/
|
|
661
|
+
update_notebook_document(notebook_uri, cells) {
|
|
662
|
+
const ptr0 = passStringToWasm0(notebook_uri, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
663
|
+
const len0 = WASM_VECTOR_LEN;
|
|
664
|
+
const ptr1 = passArrayJsValueToWasm0(cells, wasm.__wbindgen_export_0);
|
|
665
|
+
const len1 = WASM_VECTOR_LEN;
|
|
666
|
+
wasm.languageservice_update_notebook_document(this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* @param {string} notebook_uri
|
|
670
|
+
* @param {(string)[]} cell_uris
|
|
671
|
+
*/
|
|
672
|
+
close_notebook_document(notebook_uri, cell_uris) {
|
|
673
|
+
const ptr0 = passStringToWasm0(notebook_uri, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
674
|
+
const len0 = WASM_VECTOR_LEN;
|
|
675
|
+
const ptr1 = passArrayJsValueToWasm0(cell_uris, wasm.__wbindgen_export_0);
|
|
676
|
+
const len1 = WASM_VECTOR_LEN;
|
|
677
|
+
wasm.languageservice_close_notebook_document(this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
649
680
|
* @param {string} uri
|
|
650
681
|
* @param {number} offset
|
|
651
682
|
* @returns {ICompletionList}
|
|
@@ -970,6 +1001,11 @@ module.exports.__wbg_call_776890ca77946e2f = function() { return handleError(fun
|
|
|
970
1001
|
return addHeapObject(ret);
|
|
971
1002
|
}, arguments) };
|
|
972
1003
|
|
|
1004
|
+
module.exports.__wbg_isSafeInteger_bb8e18dd21c97288 = function(arg0) {
|
|
1005
|
+
const ret = Number.isSafeInteger(getObject(arg0));
|
|
1006
|
+
return ret;
|
|
1007
|
+
};
|
|
1008
|
+
|
|
973
1009
|
module.exports.__wbg_buffer_085ec1f694018c4f = function(arg0) {
|
|
974
1010
|
const ret = getObject(arg0).buffer;
|
|
975
1011
|
return addHeapObject(ret);
|
package/lib/node/qsc_wasm.d.cts
CHANGED
|
@@ -185,6 +185,12 @@ export interface ISpan {
|
|
|
185
185
|
end: number;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
export interface ICell {
|
|
189
|
+
uri: string;
|
|
190
|
+
version: number;
|
|
191
|
+
code: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
188
194
|
/**
|
|
189
195
|
*/
|
|
190
196
|
export class DebugService {
|
|
@@ -195,10 +201,11 @@ export class DebugService {
|
|
|
195
201
|
/**
|
|
196
202
|
* @param {string} path
|
|
197
203
|
* @param {string} source
|
|
204
|
+
* @param {string} target_profile
|
|
198
205
|
* @param {string | undefined} entry
|
|
199
206
|
* @returns {string}
|
|
200
207
|
*/
|
|
201
|
-
load_source(path: string, source: string, entry?: string): string;
|
|
208
|
+
load_source(path: string, source: string, target_profile: string, entry?: string): string;
|
|
202
209
|
/**
|
|
203
210
|
* @returns {IQuantumStateList}
|
|
204
211
|
*/
|
|
@@ -246,9 +253,9 @@ export class DebugService {
|
|
|
246
253
|
export class LanguageService {
|
|
247
254
|
free(): void;
|
|
248
255
|
/**
|
|
249
|
-
* @param {
|
|
256
|
+
* @param {(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]) => void} diagnostics_callback
|
|
250
257
|
*/
|
|
251
|
-
constructor(diagnostics_callback:
|
|
258
|
+
constructor(diagnostics_callback: (uri: string, version: number | undefined, diagnostics: VSDiagnostic[]) => void);
|
|
252
259
|
/**
|
|
253
260
|
* @param {IWorkspaceConfiguration} config
|
|
254
261
|
*/
|
|
@@ -264,6 +271,16 @@ export class LanguageService {
|
|
|
264
271
|
*/
|
|
265
272
|
close_document(uri: string): void;
|
|
266
273
|
/**
|
|
274
|
+
* @param {string} notebook_uri
|
|
275
|
+
* @param {(ICell)[]} cells
|
|
276
|
+
*/
|
|
277
|
+
update_notebook_document(notebook_uri: string, cells: (ICell)[]): void;
|
|
278
|
+
/**
|
|
279
|
+
* @param {string} notebook_uri
|
|
280
|
+
* @param {(string)[]} cell_uris
|
|
281
|
+
*/
|
|
282
|
+
close_notebook_document(notebook_uri: string, cell_uris: (string)[]): void;
|
|
283
|
+
/**
|
|
267
284
|
* @param {string} uri
|
|
268
285
|
* @param {number} offset
|
|
269
286
|
* @returns {ICompletionList}
|
|
Binary file
|
package/lib/web/qsc_wasm.d.ts
CHANGED
|
@@ -185,6 +185,12 @@ export interface ISpan {
|
|
|
185
185
|
end: number;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
export interface ICell {
|
|
189
|
+
uri: string;
|
|
190
|
+
version: number;
|
|
191
|
+
code: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
188
194
|
/**
|
|
189
195
|
*/
|
|
190
196
|
export class DebugService {
|
|
@@ -195,10 +201,11 @@ export class DebugService {
|
|
|
195
201
|
/**
|
|
196
202
|
* @param {string} path
|
|
197
203
|
* @param {string} source
|
|
204
|
+
* @param {string} target_profile
|
|
198
205
|
* @param {string | undefined} entry
|
|
199
206
|
* @returns {string}
|
|
200
207
|
*/
|
|
201
|
-
load_source(path: string, source: string, entry?: string): string;
|
|
208
|
+
load_source(path: string, source: string, target_profile: string, entry?: string): string;
|
|
202
209
|
/**
|
|
203
210
|
* @returns {IQuantumStateList}
|
|
204
211
|
*/
|
|
@@ -246,9 +253,9 @@ export class DebugService {
|
|
|
246
253
|
export class LanguageService {
|
|
247
254
|
free(): void;
|
|
248
255
|
/**
|
|
249
|
-
* @param {
|
|
256
|
+
* @param {(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]) => void} diagnostics_callback
|
|
250
257
|
*/
|
|
251
|
-
constructor(diagnostics_callback:
|
|
258
|
+
constructor(diagnostics_callback: (uri: string, version: number | undefined, diagnostics: VSDiagnostic[]) => void);
|
|
252
259
|
/**
|
|
253
260
|
* @param {IWorkspaceConfiguration} config
|
|
254
261
|
*/
|
|
@@ -264,6 +271,16 @@ export class LanguageService {
|
|
|
264
271
|
*/
|
|
265
272
|
close_document(uri: string): void;
|
|
266
273
|
/**
|
|
274
|
+
* @param {string} notebook_uri
|
|
275
|
+
* @param {(ICell)[]} cells
|
|
276
|
+
*/
|
|
277
|
+
update_notebook_document(notebook_uri: string, cells: (ICell)[]): void;
|
|
278
|
+
/**
|
|
279
|
+
* @param {string} notebook_uri
|
|
280
|
+
* @param {(string)[]} cell_uris
|
|
281
|
+
*/
|
|
282
|
+
close_notebook_document(notebook_uri: string, cell_uris: (string)[]): void;
|
|
283
|
+
/**
|
|
267
284
|
* @param {string} uri
|
|
268
285
|
* @param {number} offset
|
|
269
286
|
* @returns {ICompletionList}
|
|
@@ -315,7 +332,7 @@ export interface InitOutput {
|
|
|
315
332
|
readonly memory: WebAssembly.Memory;
|
|
316
333
|
readonly __wbg_debugservice_free: (a: number) => void;
|
|
317
334
|
readonly debugservice_new: () => number;
|
|
318
|
-
readonly debugservice_load_source: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
|
|
335
|
+
readonly debugservice_load_source: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void;
|
|
319
336
|
readonly debugservice_capture_quantum_state: (a: number) => number;
|
|
320
337
|
readonly debugservice_get_stack_frames: (a: number) => number;
|
|
321
338
|
readonly debugservice_eval_next: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
@@ -329,6 +346,8 @@ export interface InitOutput {
|
|
|
329
346
|
readonly languageservice_update_configuration: (a: number, b: number) => void;
|
|
330
347
|
readonly languageservice_update_document: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
|
331
348
|
readonly languageservice_close_document: (a: number, b: number, c: number) => void;
|
|
349
|
+
readonly languageservice_update_notebook_document: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
350
|
+
readonly languageservice_close_notebook_document: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
332
351
|
readonly languageservice_get_completions: (a: number, b: number, c: number, d: number) => number;
|
|
333
352
|
readonly languageservice_get_definition: (a: number, b: number, c: number, d: number) => number;
|
|
334
353
|
readonly languageservice_get_references: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
package/lib/web/qsc_wasm.js
CHANGED
|
@@ -213,6 +213,16 @@ function passArray32ToWasm0(arg, malloc) {
|
|
|
213
213
|
return ptr;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
function passArrayJsValueToWasm0(array, malloc) {
|
|
217
|
+
const ptr = malloc(array.length * 4, 4) >>> 0;
|
|
218
|
+
const mem = getUint32Memory0();
|
|
219
|
+
for (let i = 0; i < array.length; i++) {
|
|
220
|
+
mem[ptr / 4 + i] = addHeapObject(array[i]);
|
|
221
|
+
}
|
|
222
|
+
WASM_VECTOR_LEN = array.length;
|
|
223
|
+
return ptr;
|
|
224
|
+
}
|
|
225
|
+
|
|
216
226
|
function getArrayJsValueFromWasm0(ptr, len) {
|
|
217
227
|
ptr = ptr >>> 0;
|
|
218
228
|
const mem = getUint32Memory0();
|
|
@@ -432,29 +442,32 @@ export class DebugService {
|
|
|
432
442
|
/**
|
|
433
443
|
* @param {string} path
|
|
434
444
|
* @param {string} source
|
|
445
|
+
* @param {string} target_profile
|
|
435
446
|
* @param {string | undefined} entry
|
|
436
447
|
* @returns {string}
|
|
437
448
|
*/
|
|
438
|
-
load_source(path, source, entry) {
|
|
439
|
-
let
|
|
440
|
-
let
|
|
449
|
+
load_source(path, source, target_profile, entry) {
|
|
450
|
+
let deferred5_0;
|
|
451
|
+
let deferred5_1;
|
|
441
452
|
try {
|
|
442
453
|
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
443
454
|
const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
444
455
|
const len0 = WASM_VECTOR_LEN;
|
|
445
456
|
const ptr1 = passStringToWasm0(source, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
446
457
|
const len1 = WASM_VECTOR_LEN;
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
458
|
+
const ptr2 = passStringToWasm0(target_profile, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
459
|
+
const len2 = WASM_VECTOR_LEN;
|
|
460
|
+
var ptr3 = isLikeNone(entry) ? 0 : passStringToWasm0(entry, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
461
|
+
var len3 = WASM_VECTOR_LEN;
|
|
462
|
+
wasm.debugservice_load_source(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
|
450
463
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
|
451
464
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
|
452
|
-
|
|
453
|
-
|
|
465
|
+
deferred5_0 = r0;
|
|
466
|
+
deferred5_1 = r1;
|
|
454
467
|
return getStringFromWasm0(r0, r1);
|
|
455
468
|
} finally {
|
|
456
469
|
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
457
|
-
wasm.__wbindgen_export_2(
|
|
470
|
+
wasm.__wbindgen_export_2(deferred5_0, deferred5_1, 1);
|
|
458
471
|
}
|
|
459
472
|
}
|
|
460
473
|
/**
|
|
@@ -605,15 +618,11 @@ export class LanguageService {
|
|
|
605
618
|
wasm.__wbg_languageservice_free(ptr);
|
|
606
619
|
}
|
|
607
620
|
/**
|
|
608
|
-
* @param {
|
|
621
|
+
* @param {(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]) => void} diagnostics_callback
|
|
609
622
|
*/
|
|
610
623
|
constructor(diagnostics_callback) {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
return LanguageService.__wrap(ret);
|
|
614
|
-
} finally {
|
|
615
|
-
heap[stack_pointer++] = undefined;
|
|
616
|
-
}
|
|
624
|
+
const ret = wasm.languageservice_new(addHeapObject(diagnostics_callback));
|
|
625
|
+
return LanguageService.__wrap(ret);
|
|
617
626
|
}
|
|
618
627
|
/**
|
|
619
628
|
* @param {IWorkspaceConfiguration} config
|
|
@@ -642,6 +651,28 @@ export class LanguageService {
|
|
|
642
651
|
wasm.languageservice_close_document(this.__wbg_ptr, ptr0, len0);
|
|
643
652
|
}
|
|
644
653
|
/**
|
|
654
|
+
* @param {string} notebook_uri
|
|
655
|
+
* @param {(ICell)[]} cells
|
|
656
|
+
*/
|
|
657
|
+
update_notebook_document(notebook_uri, cells) {
|
|
658
|
+
const ptr0 = passStringToWasm0(notebook_uri, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
659
|
+
const len0 = WASM_VECTOR_LEN;
|
|
660
|
+
const ptr1 = passArrayJsValueToWasm0(cells, wasm.__wbindgen_export_0);
|
|
661
|
+
const len1 = WASM_VECTOR_LEN;
|
|
662
|
+
wasm.languageservice_update_notebook_document(this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* @param {string} notebook_uri
|
|
666
|
+
* @param {(string)[]} cell_uris
|
|
667
|
+
*/
|
|
668
|
+
close_notebook_document(notebook_uri, cell_uris) {
|
|
669
|
+
const ptr0 = passStringToWasm0(notebook_uri, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
|
670
|
+
const len0 = WASM_VECTOR_LEN;
|
|
671
|
+
const ptr1 = passArrayJsValueToWasm0(cell_uris, wasm.__wbindgen_export_0);
|
|
672
|
+
const len1 = WASM_VECTOR_LEN;
|
|
673
|
+
wasm.languageservice_close_notebook_document(this.__wbg_ptr, ptr0, len0, ptr1, len1);
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
645
676
|
* @param {string} uri
|
|
646
677
|
* @param {number} offset
|
|
647
678
|
* @returns {ICompletionList}
|
|
@@ -955,6 +986,10 @@ function __wbg_get_imports() {
|
|
|
955
986
|
const ret = getObject(arg0).call(getObject(arg1), getObject(arg2), getObject(arg3), getObject(arg4));
|
|
956
987
|
return addHeapObject(ret);
|
|
957
988
|
}, arguments) };
|
|
989
|
+
imports.wbg.__wbg_isSafeInteger_bb8e18dd21c97288 = function(arg0) {
|
|
990
|
+
const ret = Number.isSafeInteger(getObject(arg0));
|
|
991
|
+
return ret;
|
|
992
|
+
};
|
|
958
993
|
imports.wbg.__wbg_buffer_085ec1f694018c4f = function(arg0) {
|
|
959
994
|
const ret = getObject(arg0).buffer;
|
|
960
995
|
return addHeapObject(ret);
|
package/lib/web/qsc_wasm_bg.wasm
CHANGED
|
Binary file
|