qsharp-lang 1.0.33 → 1.1.0-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.
Files changed (41) hide show
  1. package/dist/browser.d.ts +2 -2
  2. package/dist/browser.js +1 -0
  3. package/dist/compiler/common.d.ts +1 -1
  4. package/dist/compiler/compiler.d.ts +1 -1
  5. package/dist/compiler/compiler.js +1 -2
  6. package/dist/debug-service/debug-service.d.ts +0 -1
  7. package/dist/debug-service/debug-service.js +2 -44
  8. package/dist/katas-content.generated.js +13 -13
  9. package/dist/language-service/language-service.d.ts +15 -18
  10. package/dist/language-service/language-service.js +17 -189
  11. package/dist/log.js +2 -3
  12. package/dist/main.d.ts +1 -0
  13. package/dist/main.js +1 -0
  14. package/dist/samples.generated.d.ts +8 -2
  15. package/dist/samples.generated.js +18 -0
  16. package/dist/utils.d.ts +24 -0
  17. package/dist/utils.js +148 -0
  18. package/lib/node/qsc_wasm.cjs +106 -113
  19. package/lib/node/qsc_wasm.d.cts +37 -37
  20. package/lib/node/qsc_wasm_bg.wasm +0 -0
  21. package/lib/web/qsc_wasm.d.ts +37 -37
  22. package/lib/web/qsc_wasm.js +101 -111
  23. package/lib/web/qsc_wasm_bg.wasm +0 -0
  24. package/package.json +1 -1
  25. package/ux/colormap.ts +51 -0
  26. package/ux/data.ts +65 -0
  27. package/ux/estimatesOverview.tsx +305 -0
  28. package/ux/estimatesPanel.tsx +94 -0
  29. package/ux/generate_report_code.py +243 -0
  30. package/ux/histogram.tsx +0 -1
  31. package/ux/index.ts +5 -2
  32. package/ux/output_data.md +537 -0
  33. package/ux/qsharp-ux.css +88 -8
  34. package/ux/reTable.tsx +7 -28
  35. package/ux/report.ts +591 -0
  36. package/ux/resultsTable.tsx +76 -67
  37. package/ux/scatterChart.tsx +300 -0
  38. package/ux/spaceChart.tsx +2 -2
  39. package/ux/tsconfig.json +0 -1
  40. package/dist/vsdiagnostic.d.ts +0 -19
  41. package/dist/vsdiagnostic.js +0 -127
package/dist/browser.d.ts CHANGED
@@ -23,11 +23,11 @@ export { type CompilerState } from "./compiler/compiler.js";
23
23
  export { QscEventTarget } from "./compiler/events.js";
24
24
  export { getAllKatas, getExerciseSources, getKata, type ContentItem, type Example, type Exercise, type ExplainedSolution, type ExplainedSolutionItem, type Kata, type KataSection, type Lesson, type LessonItem, type Question, } from "./katas.js";
25
25
  export { default as samples } from "./samples.generated.js";
26
- export { type VSDiagnostic } from "./vsdiagnostic.js";
27
26
  export { log, type LogLevel, type TargetProfile };
28
27
  export type { ICompilerWorker, ICompiler };
29
28
  export type { ILanguageServiceWorker, ILanguageService };
30
29
  export type { IDebugServiceWorker, IDebugService };
31
- export type { IBreakpointSpan, IStackFrame } from "../lib/web/qsc_wasm.js";
30
+ export type { IBreakpointSpan, IStackFrame, IPosition, IRange, ILocation, VSDiagnostic, } from "../lib/web/qsc_wasm.js";
32
31
  export { type IStructStepResult, StepResultId } from "../lib/web/qsc_wasm.js";
33
32
  export { type LanguageServiceEvent } from "./language-service/language-service.js";
33
+ export * as utils from "./utils.js";
package/dist/browser.js CHANGED
@@ -158,3 +158,4 @@ export { getAllKatas, getExerciseSources, getKata, } from "./katas.js";
158
158
  export { default as samples } from "./samples.generated.js";
159
159
  export { log };
160
160
  export { StepResultId } from "../lib/web/qsc_wasm.js";
161
+ export * as utils from "./utils.js";
@@ -1,4 +1,4 @@
1
- import { VSDiagnostic } from "../vsdiagnostic.js";
1
+ import { type VSDiagnostic } from "../../lib/web/qsc_wasm.js";
2
2
  export type Dump = {
3
3
  [index: string]: [number, number];
4
4
  };
@@ -1,4 +1,4 @@
1
- import { VSDiagnostic } from "../vsdiagnostic.js";
1
+ import { type VSDiagnostic } from "../../lib/web/qsc_wasm.js";
2
2
  import { IServiceProxy, ServiceState } from "../worker-proxy.js";
3
3
  import { IQscEventTarget } from "./events.js";
4
4
  type Wasm = typeof import("../../lib/node/qsc_wasm.cjs");
@@ -1,7 +1,6 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
  import { log } from "../log.js";
4
- import { mapDiagnostics } from "../vsdiagnostic.js";
5
4
  import { eventStringToMsg } from "./common.js";
6
5
  import { makeEvent } from "./events.js";
7
6
  export class Compiler {
@@ -24,7 +23,7 @@ export class Compiler {
24
23
  languageService.stop_background_work();
25
24
  await work;
26
25
  languageService.free();
27
- return mapDiagnostics(diags, code);
26
+ return diags;
28
27
  }
29
28
  async getQir(sources) {
30
29
  return this.wasm.get_qir(sources);
@@ -19,7 +19,6 @@ export type IDebugServiceWorker = IDebugService & IServiceProxy;
19
19
  export declare class QSharpDebugService implements IDebugService {
20
20
  private wasm;
21
21
  private debugService;
22
- private code;
23
22
  constructor(wasm: QscWasm);
24
23
  loadSource(sources: [string, string][], target: TargetProfile, entry: string | undefined): Promise<string>;
25
24
  getStackFrames(): Promise<IStackFrame[]>;
@@ -3,46 +3,17 @@
3
3
  import { eventStringToMsg } from "../compiler/common.js";
4
4
  import { makeEvent } from "../compiler/events.js";
5
5
  import { log } from "../log.js";
6
- import { mapUtf8UnitsToUtf16Units } from "../vsdiagnostic.js";
7
6
  export class QSharpDebugService {
8
7
  constructor(wasm) {
9
- // We need to keep a copy of the code for mapping diagnostics to utf16 offsets
10
- this.code = {};
11
8
  log.info("Constructing a QSharpDebugService instance");
12
9
  this.wasm = wasm;
13
10
  this.debugService = new wasm.DebugService();
14
11
  }
15
12
  async loadSource(sources, target, entry) {
16
- for (const [path, source] of sources) {
17
- this.code[path] = source;
18
- }
19
13
  return this.debugService.load_source(sources, target, entry);
20
14
  }
21
15
  async getStackFrames() {
22
- const stack_frame_list = this.debugService.get_stack_frames();
23
- const stack_frames = await Promise.all(stack_frame_list.frames.map(async (frame) => {
24
- // get any missing sources if possible
25
- if (!(frame.path in this.code)) {
26
- const content = await this.wasm.get_library_source_content(frame.path);
27
- if (content) {
28
- this.code[frame.path] = content;
29
- }
30
- }
31
- if (frame.path in this.code) {
32
- const mappedSpan = mapUtf8UnitsToUtf16Units([frame.lo, frame.hi], this.code[frame.path]);
33
- return {
34
- ...frame,
35
- lo: mappedSpan[frame.lo],
36
- hi: mappedSpan[frame.hi],
37
- };
38
- }
39
- else {
40
- // We don't have a source file for this frame,
41
- // and we couldn't load it, so just return it as-is
42
- return frame;
43
- }
44
- }));
45
- return stack_frames;
16
+ return this.debugService.get_stack_frames().frames;
46
17
  }
47
18
  async evalNext(bps, eventHandler) {
48
19
  const event_cb = (msg) => onCompilerEvent(msg, eventHandler);
@@ -65,20 +36,7 @@ export class QSharpDebugService {
65
36
  return this.debugService.eval_continue(event_cb, ids);
66
37
  }
67
38
  async getBreakpoints(path) {
68
- const breakpoint_list = this.debugService.get_breakpoints(path);
69
- // Get a map of the Rust source positions to the JavaScript source positions
70
- const positions = [];
71
- breakpoint_list.spans.forEach((span) => {
72
- positions.push(span.lo);
73
- positions.push(span.hi);
74
- });
75
- const positionMap = mapUtf8UnitsToUtf16Units(positions, this.code[path]);
76
- const breakpoint_spans = breakpoint_list.spans.map((span) => ({
77
- id: span.id,
78
- lo: positionMap[span.lo],
79
- hi: positionMap[span.hi],
80
- }));
81
- return breakpoint_spans;
39
+ return this.debugService.get_breakpoints(path).spans;
82
40
  }
83
41
  async captureQuantumState() {
84
42
  const state = this.debugService.capture_quantum_state();
@@ -71,8 +71,8 @@ export default {
71
71
  "items": [
72
72
  {
73
73
  "type": "text-content",
74
- "asHtml": "<p>The basic building block of a classical computer is the bit - a single memory cell that is either in state $0$ or in state $1$. Similarly, the basic building block of a quantum computer is the quantum bit, or <strong>qubit</strong>. Like the classical bit, a qubit can be in state $0$ or in state $1$. Unlike the classical bit, however, the qubit isn&#39;t limited to just those two states - it may also be in a combination, or <strong>superposition</strong> of those states.</p>\n<blockquote>\n<p>A common misconception about quantum computing is that a qubit is always in state $1$ or state $0$, we just don&#39;t know which one until we &quot;measure&quot; it. That is not the case. A qubit in a superposition is in a linear combination of the states 0 and 1. When a qubit is measured, it is forced to collapse into one state or the other - in other words, measuring a qubit is a drastic process that changes its initial state.</p>\n</blockquote>\n<h2>Matrix Representation</h2>\n<p>The state of a qubit is represented by a complex vector of size 2:</p>\n<p>$$\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix}$$</p>\n<p>Here $\\alpha$ and $\\beta$ are complex numbers. $\\alpha$ represents how &quot;close&quot; the qubit is to state $0$, and $\\beta$ represents how &quot;close&quot; the qubit is to state $1$. This vector is normalized: $|\\alpha|^2 + |\\beta|^2 = 1$.\nα and β are known as the probability amplitudes of states 0 and 1, respectively.</p>\n<p>$\\alpha$ and $\\beta$ are known as the probability amplitudes of states $0$ and $1$, respectively.</p>\n<h2>Basis States</h2>\n<p>A qubit in state $0$ would be represented by the following vector:</p>\n<p>$$\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}$$</p>\n<p>Likewise, a qubit in state $1$ would be represented by this vector:</p>\n<p>$$\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}$$</p>\n<p>Note that you can use scalar multiplication and vector addition to express any qubit state $\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix}$ as a sum of these two vectors with certain probability amplitudes $\\alpha$ and $\\beta$, known as linear combination.</p>\n<p>$$\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\ 0 \\end{bmatrix} + \\begin{bmatrix} 0 \\\\ \\beta \\end{bmatrix} =\n\\alpha \\cdot \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} + \\beta \\cdot \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}\n$$</p>\n<p>Because of this, qubit states $0$ and $1$ are known as basis states. These two vectors have two properties.</p>\n<ol>\n<li>They are normalized.</li>\n</ol>\n<p>$$\n\\langle \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\rangle = 1\n$$</p>\n<ol start=\"2\">\n<li>They are orthogonal to each other.</li>\n</ol>\n<p>$$\n\\langle \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\rangle = 0\n$$</p>\n<blockquote>\n<p>As a reminder, $\\langle V , W \\rangle$ is the inner product of $V$ and $W$.</p>\n</blockquote>\n<p>This means that these vectors form an <strong>orthonormal basis</strong>. The basis of $\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}$ and $\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}$ is called the <strong>computational basis</strong>, also known as the <strong>canonical basis</strong>.</p>\n<blockquote>\n<p>There exist other orthonormal bases, for example, the <strong>Hadamard basis</strong>, formed by the vectors</p>\n<p>$$\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\text{ and } \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}$$</p>\n<p>You can check that these vectors are normalized, and orthogonal to each other. Any qubit state can be expressed as a linear combination of these vectors:</p>\n<p>$$\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\frac{\\alpha + \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} +\n\\frac{\\alpha - \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}\n$$</p>\n<p>The Hadamard basis is widely used in quantum computing, for example, in the <a href=\"https://en.wikipedia.org/wiki/BB84\" target=\"_blank\">BB84 quantum key distribution protocol</a>.</p>\n</blockquote>\n",
75
- "asMarkdown": "\nThe basic building block of a classical computer is the bit - a single memory cell that is either in state $0$ or in state $1$. Similarly, the basic building block of a quantum computer is the quantum bit, or **qubit**. Like the classical bit, a qubit can be in state $0$ or in state $1$. Unlike the classical bit, however, the qubit isn't limited to just those two states - it may also be in a combination, or **superposition** of those states.\n\n> A common misconception about quantum computing is that a qubit is always in state $1$ or state $0$, we just don't know which one until we \"measure\" it. That is not the case. A qubit in a superposition is in a linear combination of the states 0 and 1. When a qubit is measured, it is forced to collapse into one state or the other - in other words, measuring a qubit is a drastic process that changes its initial state.\n\n## Matrix Representation\n\nThe state of a qubit is represented by a complex vector of size 2:\n\n$$\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$$\n\nHere $\\alpha$ and $\\beta$ are complex numbers. $\\alpha$ represents how \"close\" the qubit is to state $0$, and $\\beta$ represents how \"close\" the qubit is to state $1$. This vector is normalized: $|\\alpha|^2 + |\\beta|^2 = 1$.\nα and β are known as the probability amplitudes of states 0 and 1, respectively.\n\n$\\alpha$ and $\\beta$ are known as the probability amplitudes of states $0$ and $1$, respectively.\n\n## Basis States\n\nA qubit in state $0$ would be represented by the following vector:\n\n$$\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$$\n\nLikewise, a qubit in state $1$ would be represented by this vector:\n\n$$\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$$\n\nNote that you can use scalar multiplication and vector addition to express any qubit state $\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$ as a sum of these two vectors with certain probability amplitudes $\\alpha$ and $\\beta$, known as linear combination.\n\n$$\n\\begin{bmatrix} \\alpha \\\\\\ \\beta \\\\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\\\ 0 \\end{bmatrix} + \\begin{bmatrix} 0 \\\\\\ \\beta \\\\end{bmatrix} =\n\\alpha \\cdot \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} + \\beta \\cdot \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}\n$$\n\nBecause of this, qubit states $0$ and $1$ are known as basis states. These two vectors have two properties.\n\n1. They are normalized.\n\n$$\n\\langle \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\rangle = 1\n$$\n\n2. They are orthogonal to each other.\n\n$$\n\\langle \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\\\rangle = 0\n$$\n\n> As a reminder, $\\langle V , W \\rangle$ is the inner product of $V$ and $W$.\n\nThis means that these vectors form an **orthonormal basis**. The basis of $\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$ and $\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$ is called the **computational basis**, also known as the **canonical basis**.\n\n> There exist other orthonormal bases, for example, the **Hadamard basis**, formed by the vectors\n>\n> $$\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\text{ and } \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}$$\n>\n> You can check that these vectors are normalized, and orthogonal to each other. Any qubit state can be expressed as a linear combination of these vectors:\n>\n> $$\n> \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} =\n> \\frac{\\alpha + \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} +\n> \\frac{\\alpha - \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}\n> $$\n>\n> The Hadamard basis is widely used in quantum computing, for example, in the <a href=\"https://en.wikipedia.org/wiki/BB84\" target=\"_blank\">BB84 quantum key distribution protocol</a>."
74
+ "asHtml": "<p>The basic building block of a classical computer is the bit - a single memory cell that is either in state $0$ or in state $1$. Similarly, the basic building block of a quantum computer is the quantum bit, or <strong>qubit</strong>. Like the classical bit, a qubit can be in state $0$ or in state $1$. Unlike the classical bit, however, the qubit isn&#39;t limited to just those two states - it may also be in a combination, or <strong>superposition</strong> of those states.</p>\n<blockquote>\n<p>A common misconception about quantum computing is that a qubit is always in state $1$ or state $0$, we just don&#39;t know which one until we &quot;measure&quot; it. That is not the case. A qubit in a superposition is in a linear combination of the states 0 and 1. When a qubit is measured, it is forced to collapse into one state or the other - in other words, measuring a qubit is a drastic process that changes its initial state.</p>\n</blockquote>\n<h2>Matrix Representation</h2>\n<p>The state of a qubit is represented by a complex vector of size 2:</p>\n<p>$$\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix}$$</p>\n<p>Here $\\alpha$ and $\\beta$ are complex numbers. $\\alpha$ represents how &quot;close&quot; the qubit is to state $0$, and $\\beta$ represents how &quot;close&quot; the qubit is to state $1$. This vector is normalized: $|\\alpha|^2 + |\\beta|^2 = 1$.\n$\\alpha$ and $\\beta$ are known as the probability amplitudes of states $0$ and $1$, respectively.</p>\n<h2>Basis States</h2>\n<p>A qubit in state $0$ would be represented by the following vector:</p>\n<p>$$\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}$$</p>\n<p>Likewise, a qubit in state $1$ would be represented by this vector:</p>\n<p>$$\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}$$</p>\n<p>Note that you can use scalar multiplication and vector addition to express any qubit state $\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix}$ as a sum of these two vectors with certain probability amplitudes $\\alpha$ and $\\beta$, known as linear combination.</p>\n<p>$$\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\ 0 \\end{bmatrix} + \\begin{bmatrix} 0 \\\\ \\beta \\end{bmatrix} =\n\\alpha \\cdot \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} + \\beta \\cdot \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}\n$$</p>\n<p>Because of this, qubit states $0$ and $1$ are known as basis states. These two vectors have two properties.</p>\n<ol>\n<li>They are normalized.</li>\n</ol>\n<p>$$\n\\langle \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\rangle = 1\n$$</p>\n<ol start=\"2\">\n<li>They are orthogonal to each other.</li>\n</ol>\n<p>$$\n\\langle \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\rangle = 0\n$$</p>\n<blockquote>\n<p>As a reminder, $\\langle V , W \\rangle$ is the inner product of $V$ and $W$.</p>\n</blockquote>\n<p>This means that these vectors form an <strong>orthonormal basis</strong>. The basis of $\\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix}$ and $\\begin{bmatrix} 0 \\\\ 1 \\end{bmatrix}$ is called the <strong>computational basis</strong>, also known as the <strong>canonical basis</strong>.</p>\n<blockquote>\n<p>There exist other orthonormal bases, for example, the <strong>Hadamard basis</strong>, formed by the vectors</p>\n<p>$$\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\text{ and } \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}$$</p>\n<p>You can check that these vectors are normalized, and orthogonal to each other. Any qubit state can be expressed as a linear combination of these vectors:</p>\n<p>$$\n\\begin{bmatrix} \\alpha \\\\ \\beta \\end{bmatrix} =\n\\frac{\\alpha + \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} +\n\\frac{\\alpha - \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}\n$$</p>\n<p>The Hadamard basis is widely used in quantum computing, for example, in the <a href=\"https://en.wikipedia.org/wiki/BB84\" target=\"_blank\">BB84 quantum key distribution protocol</a>.</p>\n</blockquote>\n",
75
+ "asMarkdown": "\nThe basic building block of a classical computer is the bit - a single memory cell that is either in state $0$ or in state $1$. Similarly, the basic building block of a quantum computer is the quantum bit, or **qubit**. Like the classical bit, a qubit can be in state $0$ or in state $1$. Unlike the classical bit, however, the qubit isn't limited to just those two states - it may also be in a combination, or **superposition** of those states.\n\n> A common misconception about quantum computing is that a qubit is always in state $1$ or state $0$, we just don't know which one until we \"measure\" it. That is not the case. A qubit in a superposition is in a linear combination of the states 0 and 1. When a qubit is measured, it is forced to collapse into one state or the other - in other words, measuring a qubit is a drastic process that changes its initial state.\n\n## Matrix Representation\n\nThe state of a qubit is represented by a complex vector of size 2:\n\n$$\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$$\n\nHere $\\alpha$ and $\\beta$ are complex numbers. $\\alpha$ represents how \"close\" the qubit is to state $0$, and $\\beta$ represents how \"close\" the qubit is to state $1$. This vector is normalized: $|\\alpha|^2 + |\\beta|^2 = 1$.\n$\\alpha$ and $\\beta$ are known as the probability amplitudes of states $0$ and $1$, respectively.\n\n## Basis States\n\nA qubit in state $0$ would be represented by the following vector:\n\n$$\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$$\n\nLikewise, a qubit in state $1$ would be represented by this vector:\n\n$$\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$$\n\nNote that you can use scalar multiplication and vector addition to express any qubit state $\\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix}$ as a sum of these two vectors with certain probability amplitudes $\\alpha$ and $\\beta$, known as linear combination.\n\n$$\n\\begin{bmatrix} \\alpha \\\\\\ \\beta \\\\end{bmatrix} =\n\\begin{bmatrix} \\alpha \\\\\\ 0 \\end{bmatrix} + \\begin{bmatrix} 0 \\\\\\ \\beta \\\\end{bmatrix} =\n\\alpha \\cdot \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} + \\beta \\cdot \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}\n$$\n\nBecause of this, qubit states $0$ and $1$ are known as basis states. These two vectors have two properties.\n\n1. They are normalized.\n\n$$\n\\langle \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\rangle = 1\n$$\n\n2. They are orthogonal to each other.\n\n$$\n\\langle \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} , \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} \\rangle =\n\\langle \\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix} , \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\\\rangle = 0\n$$\n\n> As a reminder, $\\langle V , W \\rangle$ is the inner product of $V$ and $W$.\n\nThis means that these vectors form an **orthonormal basis**. The basis of $\\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix}$ and $\\begin{bmatrix} 0 \\\\\\ 1 \\end{bmatrix}$ is called the **computational basis**, also known as the **canonical basis**.\n\n> There exist other orthonormal bases, for example, the **Hadamard basis**, formed by the vectors\n>\n> $$\\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} \\text{ and } \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}$$\n>\n> You can check that these vectors are normalized, and orthogonal to each other. Any qubit state can be expressed as a linear combination of these vectors:\n>\n> $$\n> \\begin{bmatrix} \\alpha \\\\\\ \\beta \\end{bmatrix} =\n> \\frac{\\alpha + \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ \\frac{1}{\\sqrt{2}} \\end{bmatrix} +\n> \\frac{\\alpha - \\beta}{\\sqrt{2}} \\begin{bmatrix} \\frac{1}{\\sqrt{2}} \\\\\\ -\\frac{1}{\\sqrt{2}} \\end{bmatrix}\n> $$\n>\n> The Hadamard basis is widely used in quantum computing, for example, in the <a href=\"https://en.wikipedia.org/wiki/BB84\" target=\"_blank\">BB84 quantum key distribution protocol</a>."
76
76
  }
77
77
  ]
78
78
  },
@@ -117,8 +117,8 @@ export default {
117
117
  },
118
118
  {
119
119
  "type": "text-content",
120
- "asHtml": "<p>The exact behavior of this operation called <code>RunExample</code> depends on the quantum simulator or processor you are using.</p>\n<p>On the simulator used in these demos, this function prints the information on each basis state that has a non-zero amplitude, one basis state per row.\nThis includes information about the amplitude of the state, the probability of measuring that state, and the phase of the state.</p>\n<p>Note that each row has the following format:</p>\n<table>\n <thead>\n <tr>\n <th>Basis State<br>(|𝜓ₙ…𝜓₁⟩)</th>\n <th>Amplitude</th>\n <th>Measurement Probability</th>\n <th>Phase</th>\n </tr>\n </thead>\n</table>\n\n<p>For example, the state $|0\\rangle$ would be represented as follows:</p>\n<table>\n <tbody>\n <tr>\n <td>|0⟩</td>\n <td>1.0000+0.0000𝑖</td>\n <td>100.0000%</td>\n <td>↑ 0.0000</td></tr>\n </tbody>\n</table>\n\n<blockquote>\n<p>It is important to note that although we reason about quantum systems in terms of their state, Q# does not have any representation of the quantum state in the language. Instead, state is an internal property of the quantum system, modified using gates. For more information, see <a href=\"https://docs.microsoft.com/azure/quantum/concepts-dirac-notation#q-gate-sequences-equivalent-to-quantum-states\" target=\"_blank\">Q# documentation on quantum states</a>.</p>\n</blockquote>\n",
121
- "asMarkdown": "\nThe exact behavior of this operation called `RunExample` depends on the quantum simulator or processor you are using.\n\nOn the simulator used in these demos, this function prints the information on each basis state that has a non-zero amplitude, one basis state per row.\nThis includes information about the amplitude of the state, the probability of measuring that state, and the phase of the state.\n\nNote that each row has the following format:\n\n<table>\n <thead>\n <tr>\n <th>Basis State<br>(|𝜓ₙ…𝜓₁⟩)</th>\n <th>Amplitude</th>\n <th>Measurement Probability</th>\n <th>Phase</th>\n </tr>\n </thead>\n</table>\n\nFor example, the state $|0\\rangle$ would be represented as follows:\n\n<table>\n <tbody>\n <tr>\n <td>|0⟩</td>\n <td>1.0000+0.0000𝑖</td>\n <td>100.0000%</td>\n <td>↑ 0.0000</td></tr>\n </tbody>\n</table>\n\n> It is important to note that although we reason about quantum systems in terms of their state, Q# does not have any representation of the quantum state in the language. Instead, state is an internal property of the quantum system, modified using gates. For more information, see <a href=\"https://docs.microsoft.com/azure/quantum/concepts-dirac-notation#q-gate-sequences-equivalent-to-quantum-states\" target=\"_blank\">Q# documentation on quantum states</a>."
120
+ "asHtml": "<p>The exact behavior of this operation called <code>RunExample</code> depends on the quantum simulator or processor you are using.</p>\n<p>On the simulator used in these demos, this function prints the information on each basis state that has a non-zero amplitude, one basis state per row.\nThis includes information about the amplitude of the state, the probability of measuring that state, and the phase of the state.</p>\n<p>Note that each row has the following format:</p>\n<table>\n <thead>\n <tr>\n <th>Basis State<br>(|𝜓₁…𝜓ₙ⟩)</th>\n <th>Amplitude</th>\n <th>Measurement Probability</th>\n <th>Phase</th>\n </tr>\n </thead>\n</table>\n\n<p>For example, the state $|0\\rangle$ would be represented as follows:</p>\n<table>\n <tbody>\n <tr>\n <td>|0⟩</td>\n <td>1.0000+0.0000𝑖</td>\n <td>100.0000%</td>\n <td>↑ 0.0000</td></tr>\n </tbody>\n</table>\n\n<blockquote>\n<p>It is important to note that although we reason about quantum systems in terms of their state, Q# does not have any representation of the quantum state in the language. Instead, state is an internal property of the quantum system, modified using gates. For more information, see <a href=\"https://docs.microsoft.com/azure/quantum/concepts-dirac-notation#q-gate-sequences-equivalent-to-quantum-states\" target=\"_blank\">Q# documentation on quantum states</a>.</p>\n</blockquote>\n",
121
+ "asMarkdown": "\nThe exact behavior of this operation called `RunExample` depends on the quantum simulator or processor you are using.\n\nOn the simulator used in these demos, this function prints the information on each basis state that has a non-zero amplitude, one basis state per row.\nThis includes information about the amplitude of the state, the probability of measuring that state, and the phase of the state.\n\nNote that each row has the following format:\n\n<table>\n <thead>\n <tr>\n <th>Basis State<br>(|𝜓₁…𝜓ₙ⟩)</th>\n <th>Amplitude</th>\n <th>Measurement Probability</th>\n <th>Phase</th>\n </tr>\n </thead>\n</table>\n\nFor example, the state $|0\\rangle$ would be represented as follows:\n\n<table>\n <tbody>\n <tr>\n <td>|0⟩</td>\n <td>1.0000+0.0000𝑖</td>\n <td>100.0000%</td>\n <td>↑ 0.0000</td></tr>\n </tbody>\n</table>\n\n> It is important to note that although we reason about quantum systems in terms of their state, Q# does not have any representation of the quantum state in the language. Instead, state is an internal property of the quantum system, modified using gates. For more information, see <a href=\"https://docs.microsoft.com/azure/quantum/concepts-dirac-notation#q-gate-sequences-equivalent-to-quantum-states\" target=\"_blank\">Q# documentation on quantum states</a>."
122
122
  }
123
123
  ]
124
124
  },
@@ -741,8 +741,8 @@ export default {
741
741
  "items": [
742
742
  {
743
743
  "type": "text-content",
744
- "asHtml": "<p>The start state is the same as the previous exercises:\n$$ \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$</p>\n<p>The goal state, factored as a tensor product, looks like this (remember that $e^{3i\\pi/4} = e^{i\\pi/4} e^{i\\pi/2}$):</p>\n<p>$$\n\\frac{1}{2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\\\ e^{i\\pi/2} \\\\ e^{3i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) $$</p>\n<p>We will again need to adjust the states of both qubits independently.</p>\n<p>For the first qubit, we&#39;ll start by applying the <strong>H</strong> gate, getting the state $\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix}$, as we&#39;ve seen in the previous task. Afterwards we&#39;ll apply the <strong>S</strong> gate with the following result:</p>\n<p>$$ \\begin{bmatrix} 1 &amp; 0 \\\\ 0 &amp; i \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ i \\end{bmatrix}$$</p>\n<p>If we recall that $i = e^{i\\pi/2}$, we can write the final state of the second qubit as:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/2} \\end{bmatrix} $$</p>\n<p>For the second qubit. we&#39;ll apply the <strong>H</strong> gate, followed by the <strong>T</strong> gate, with the following result:\n$$ \\begin{bmatrix} 1 &amp; 0 \\\\ 0 &amp; e^{i\\pi/4} \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\end{bmatrix} $$</p>\n",
745
- "asMarkdown": "\nThe start state is the same as the previous exercises:\n$$ \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$\n\nThe goal state, factored as a tensor product, looks like this (remember that $e^{3i\\pi/4} = e^{i\\pi/4} e^{i\\pi/2}$):\n\n$$\n\\frac{1}{2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\\\\\ e^{i\\pi/2} \\\\\\ e^{3i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) $$\n\nWe will again need to adjust the states of both qubits independently.\n\nFor the first qubit, we'll start by applying the **H** gate, getting the state $\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix}$, as we've seen in the previous task. Afterwards we'll apply the **S** gate with the following result:\n\n$$ \\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ i \\end{bmatrix}$$\n\nIf we recall that $i = e^{i\\pi/2}$, we can write the final state of the second qubit as:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} $$\n\nFor the second qubit. we'll apply the **H** gate, followed by the **T** gate, with the following result:\n$$ \\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix} $$"
744
+ "asHtml": "<p>The start state is the same as the previous exercises:\n$$ \\begin{bmatrix} 1 \\\\ 0 \\\\ 0 \\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$</p>\n<p>The goal state, factored as a tensor product, looks like this (remember that $e^{3i\\pi/4} = e^{i\\pi/4} e^{i\\pi/2}$):</p>\n<p>$$\n\\frac{1}{2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\\\ e^{i\\pi/2} \\\\ e^{3i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) $$</p>\n<p>We will again need to adjust the states of both qubits independently.</p>\n<p>For the first qubit, we&#39;ll start by applying the <strong>H</strong> gate, getting the state $\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix}$, as we&#39;ve seen in the previous task. Afterwards we&#39;ll apply the <strong>S</strong> gate with the following result:</p>\n<p>$$ \\begin{bmatrix} 1 &amp; 0 \\\\ 0 &amp; i \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ i \\end{bmatrix}$$</p>\n<p>If we recall that $i = e^{i\\pi/2}$, we can write the final state of the first qubit as:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/2} \\end{bmatrix} $$</p>\n<p>For the second qubit. we&#39;ll apply the <strong>H</strong> gate, followed by the <strong>T</strong> gate, with the following result:\n$$ \\begin{bmatrix} 1 &amp; 0 \\\\ 0 &amp; e^{i\\pi/4} \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\ e^{i\\pi/4} \\end{bmatrix} $$</p>\n",
745
+ "asMarkdown": "\nThe start state is the same as the previous exercises:\n$$ \\begin{bmatrix} 1 \\\\\\ 0 \\\\\\ 0 \\\\\\ 0 \\end{bmatrix} = \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} \\otimes \\begin{bmatrix} 1 \\\\\\ 0 \\end{bmatrix} = |0\\rangle \\otimes |0\\rangle $$\n\nThe goal state, factored as a tensor product, looks like this (remember that $e^{3i\\pi/4} = e^{i\\pi/4} e^{i\\pi/2}$):\n\n$$\n\\frac{1}{2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\\\\\ e^{i\\pi/2} \\\\\\ e^{3i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} \\otimes \\frac{1}{\\sqrt2}\\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix} =\n\\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/2}|1\\rangle\\big) \\otimes \\frac{1}{\\sqrt2}\\big(|0\\rangle + e^{i\\pi/4}|1\\rangle\\big) $$\n\nWe will again need to adjust the states of both qubits independently.\n\nFor the first qubit, we'll start by applying the **H** gate, getting the state $\\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix}$, as we've seen in the previous task. Afterwards we'll apply the **S** gate with the following result:\n\n$$ \\begin{bmatrix} 1 & 0 \\\\\\ 0 & i \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ i \\end{bmatrix}$$\n\nIf we recall that $i = e^{i\\pi/2}$, we can write the final state of the first qubit as:\n$$ \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/2} \\end{bmatrix} $$\n\nFor the second qubit. we'll apply the **H** gate, followed by the **T** gate, with the following result:\n$$ \\begin{bmatrix} 1 & 0 \\\\\\ 0 & e^{i\\pi/4} \\end{bmatrix} \\cdot \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ 1 \\end{bmatrix} = \\frac{1}{\\sqrt2} \\begin{bmatrix} 1 \\\\\\ e^{i\\pi/4} \\end{bmatrix} $$"
746
746
  },
747
747
  {
748
748
  "type": "solution",
@@ -1751,8 +1751,8 @@ export default {
1751
1751
  "title": "Generate a Number of Arbitrary Size",
1752
1752
  "description": {
1753
1753
  "type": "text-content",
1754
- "asHtml": "<p>Let&#39;s take it a step further and generate an $N$-bit number. </p>\n<p><strong>Input:</strong> An integer $N$ ($1 \\le N \\le 10$).</p>\n<p><strong>Goal:</strong> Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.</p>\n<blockquote>\n<p>Useful Q# documentation: </p>\n<ul>\n<li><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations\" target=\"_blank\">for` loops</a></li>\n<li><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability\" target=\"_blank\">mutable variables</a></li>\n<li><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi\" target=\"_blank\">exponents</a></li>\n</ul>\n</blockquote>\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n",
1755
- "asMarkdown": "Let's take it a step further and generate an $N$-bit number. \n\n**Input:** An integer $N$ ($1 \\le N \\le 10$).\n\n**Goal:** Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.\n\n> Useful Q# documentation: \n> * <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations\" target=\"_blank\">for` loops</a>\n> * <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability\" target=\"_blank\">mutable variables</a>\n> * <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi\" target=\"_blank\">exponents</a>\n\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n"
1754
+ "asHtml": "<p>Let&#39;s take it a step further and generate an $N$-bit number.</p>\n<p><strong>Input:</strong> An integer $N$ ($1 \\le N \\le 10$).</p>\n<p><strong>Goal:</strong> Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.</p>\n<blockquote>\n<p>Useful Q# documentation:</p>\n<ul>\n<li><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations\" target=\"_blank\">for loops</a></li>\n<li><a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability\" target=\"_blank\">mutable variables</a></li>\n<li><a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi\" target=\"_blank\">exponents</a></li>\n</ul>\n</blockquote>\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n",
1755
+ "asMarkdown": "Let's take it a step further and generate an $N$-bit number.\n\n**Input:** An integer $N$ ($1 \\le N \\le 10$).\n\n**Goal:** Generate a random number in the range $[0, 2^N - 1]$ with an equal probability of getting each of the numbers in this range.\n\n> Useful Q# documentation:\n>\n> * <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/statements/iterations\" target=\"_blank\">for loops</a>\n> * <a href=\"https://docs.microsoft.com/azure/quantum/user-guide/language/typesystem/immutability\" target=\"_blank\">mutable variables</a>\n> * <a href=\"https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.math.powi\" target=\"_blank\">exponents</a>\n\n<details>\n <summary><b>Need a hint?</b></summary>\n Remember that you can use previously defined operations to implement your solution. For convenience, the <b>RandomBit</b> operation is already available for you to use in this exercise.\n</details>\n"
1756
1756
  },
1757
1757
  "sourceIds": [
1758
1758
  "random_numbers__random_n_bits__verification.qs",
@@ -2341,23 +2341,23 @@ export default {
2341
2341
  },
2342
2342
  {
2343
2343
  "id": "multi_qubit_systems__common.qs",
2344
- "code": "namespace Kata.Verification {\n open Microsoft.Quantum.Diagnostics;\n\n operation AssertEqualOnZeroState(\n testImpl : (Qubit[] => Unit is Ctl),\n refImpl : (Qubit[] => Unit is Adj+Ctl)) : Bool {\n\n use qs = Qubit[3];\n within {\n H(qs[0]);\n }\n apply {\n // apply operation that needs to be tested\n Controlled testImpl([qs[0]], qs[1..2]);\n\n // apply adjoint reference operation\n Adjoint Controlled refImpl([qs[0]], qs[1..2]);\n }\n\n // Implementation is correct when all qubits end up in |0⟩ state\n let isCorrect = CheckAllZero(qs);\n if not isCorrect {\n Message(\"The prepared state is not the same as reference state.\");\n }\n ResetAll(qs);\n isCorrect\n }\n\n}\n"
2344
+ "code": "namespace Kata.Verification {\n open Microsoft.Quantum.Katas;\n\n operation CheckEqualOnZeroState(\n testImpl : (Qubit[] => Unit is Adj + Ctl),\n refImpl : (Qubit[] => Unit is Adj + Ctl)) : Bool {\n\n let isCorrect = CheckOperationsEquivalenceOnZeroStateStrict(testImpl, refImpl, 2);\n\n // Output different feedback to the user depending on whether the exercise was correct.\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n use target = Qubit[2]; // |00〉\n ShowQuantumStateComparison(target, testImpl, refImpl);\n ResetAll(target);\n }\n isCorrect\n }\n\n}\n"
2345
2345
  },
2346
2346
  {
2347
2347
  "id": "multi_qubit_systems__prepare_basis_state__verification.qs",
2348
- "code": "namespace Kata.Verification {\n operation PrepareBasisState_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[0]);\n X(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareBasisState, PrepareBasisState_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}"
2348
+ "code": "namespace Kata.Verification {\n open Microsoft.Quantum.Katas;\n\n operation PrepareBasisState_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[0]);\n X(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n CheckEqualOnZeroState(Kata.PrepareBasisState, PrepareBasisState_Reference)\n }\n}\n"
2349
2349
  },
2350
2350
  {
2351
2351
  "id": "multi_qubit_systems__prepare_superposition__verification.qs",
2352
- "code": "namespace Kata.Verification {\n operation PrepareSuperposition_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareSuperposition, PrepareSuperposition_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}\n"
2352
+ "code": "namespace Kata.Verification {\n open Microsoft.Quantum.Katas;\n\n operation PrepareSuperposition_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n CheckEqualOnZeroState(Kata.PrepareSuperposition, PrepareSuperposition_Reference)\n }\n}\n"
2353
2353
  },
2354
2354
  {
2355
2355
  "id": "multi_qubit_systems__prepare_with_real__verification.qs",
2356
- "code": "namespace Kata.Verification {\n operation PrepareWithReal_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithReal, PrepareWithReal_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}\n"
2356
+ "code": "namespace Kata.Verification {\n open Microsoft.Quantum.Katas;\n\n operation PrepareWithReal_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n X(qs[1]);\n H(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n CheckEqualOnZeroState(Kata.PrepareWithReal, PrepareWithReal_Reference)\n }\n}\n"
2357
2357
  },
2358
2358
  {
2359
2359
  "id": "multi_qubit_systems__prepare_with_complex__verification.qs",
2360
- "code": "namespace Kata.Verification {\n operation PrepareWithComplex_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n S(qs[0]);\n T(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n let isCorrect = AssertEqualOnZeroState(Kata.PrepareWithComplex, PrepareWithComplex_Reference);\n if isCorrect {\n Message(\"Correct!\");\n } else {\n Message(\"Incorrect.\");\n }\n return isCorrect;\n }\n}\n"
2360
+ "code": "namespace Kata.Verification {\n open Microsoft.Quantum.Katas;\n\n operation PrepareWithComplex_Reference(qs : Qubit[]) : Unit is Adj + Ctl {\n H(qs[0]);\n H(qs[1]);\n S(qs[0]);\n T(qs[1]);\n }\n\n @EntryPoint()\n operation CheckSolution() : Bool {\n CheckEqualOnZeroState(Kata.PrepareWithComplex, PrepareWithComplex_Reference)\n }\n}\n"
2361
2361
  },
2362
2362
  {
2363
2363
  "id": "multi_qubit_gates__compound_gate__Verification.qs",
@@ -1,5 +1,4 @@
1
- import type { ICompletionList, IHover, ILocation, ISignatureHelp, INotebookMetadata, IWorkspaceConfiguration, IWorkspaceEdit, ITextEdit } from "../../lib/node/qsc_wasm.cjs";
2
- import { VSDiagnostic } from "../vsdiagnostic.js";
1
+ import type { ICompletionList, IHover, ILocation, ISignatureHelp, INotebookMetadata, IWorkspaceConfiguration, IWorkspaceEdit, ITextEdit, IPosition, VSDiagnostic } from "../../lib/node/qsc_wasm.cjs";
3
2
  import { IServiceProxy } from "../worker-proxy.js";
4
3
  type QscWasm = typeof import("../../lib/node/qsc_wasm.cjs");
5
4
  export type LanguageServiceEvent = {
@@ -20,13 +19,13 @@ export interface ILanguageService {
20
19
  }[]): Promise<void>;
21
20
  closeDocument(uri: string): Promise<void>;
22
21
  closeNotebookDocument(notebookUri: string): Promise<void>;
23
- getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
24
- getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
25
- getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
26
- getReferences(documentUri: string, offset: number, includeDeclaration: boolean): Promise<ILocation[]>;
27
- getSignatureHelp(documentUri: string, offset: number): Promise<ISignatureHelp | undefined>;
28
- getRename(documentUri: string, offset: number, newName: string): Promise<IWorkspaceEdit | undefined>;
29
- prepareRename(documentUri: string, offset: number): Promise<ITextEdit | undefined>;
22
+ getCompletions(documentUri: string, position: IPosition): Promise<ICompletionList>;
23
+ getHover(documentUri: string, position: IPosition): Promise<IHover | undefined>;
24
+ getDefinition(documentUri: string, position: IPosition): Promise<ILocation | undefined>;
25
+ getReferences(documentUri: string, position: IPosition, includeDeclaration: boolean): Promise<ILocation[]>;
26
+ getSignatureHelp(documentUri: string, position: IPosition): Promise<ISignatureHelp | undefined>;
27
+ getRename(documentUri: string, position: IPosition, newName: string): Promise<IWorkspaceEdit | undefined>;
28
+ prepareRename(documentUri: string, position: IPosition): Promise<ITextEdit | undefined>;
30
29
  dispose(): Promise<void>;
31
30
  addEventListener<T extends LanguageServiceEvent["type"]>(type: T, listener: (event: Extract<LanguageServiceEvent, {
32
31
  type: T;
@@ -40,13 +39,11 @@ export type ILanguageServiceWorker = ILanguageService & IServiceProxy;
40
39
  export declare class QSharpLanguageService implements ILanguageService {
41
40
  private languageService;
42
41
  private eventHandler;
43
- private code;
44
42
  private readFile;
45
43
  private backgroundWork;
46
44
  constructor(wasm: QscWasm, readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
47
45
  manifestDirectory: string;
48
46
  } | null>);
49
- loadFile(uri: string): Promise<string | null>;
50
47
  updateConfiguration(config: IWorkspaceConfiguration): Promise<void>;
51
48
  updateDocument(documentUri: string, version: number, code: string): Promise<void>;
52
49
  updateNotebookDocument(notebookUri: string, version: number, metadata: INotebookMetadata, cells: {
@@ -56,13 +53,13 @@ export declare class QSharpLanguageService implements ILanguageService {
56
53
  }[]): Promise<void>;
57
54
  closeDocument(documentUri: string): Promise<void>;
58
55
  closeNotebookDocument(documentUri: string): Promise<void>;
59
- getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
60
- getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
61
- getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
62
- getReferences(documentUri: string, offset: number, includeDeclaration: boolean): Promise<ILocation[]>;
63
- getSignatureHelp(documentUri: string, offset: number): Promise<ISignatureHelp | undefined>;
64
- getRename(documentUri: string, offset: number, newName: string): Promise<IWorkspaceEdit | undefined>;
65
- prepareRename(documentUri: string, offset: number): Promise<ITextEdit | undefined>;
56
+ getCompletions(documentUri: string, position: IPosition): Promise<ICompletionList>;
57
+ getHover(documentUri: string, position: IPosition): Promise<IHover | undefined>;
58
+ getDefinition(documentUri: string, position: IPosition): Promise<ILocation | undefined>;
59
+ getReferences(documentUri: string, position: IPosition, includeDeclaration: boolean): Promise<ILocation[]>;
60
+ getSignatureHelp(documentUri: string, position: IPosition): Promise<ISignatureHelp | undefined>;
61
+ getRename(documentUri: string, position: IPosition, newName: string): Promise<IWorkspaceEdit | undefined>;
62
+ prepareRename(documentUri: string, position: IPosition): Promise<ITextEdit | undefined>;
66
63
  dispose(): Promise<void>;
67
64
  addEventListener<T extends LanguageServiceEvent["type"]>(type: T, listener: (event: Extract<LanguageServiceEvent, {
68
65
  type: T;
@@ -1,202 +1,50 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
- import * as wasm from "../../lib/web/qsc_wasm.js";
4
3
  import { log } from "../log.js";
5
- import { mapDiagnostics, mapUtf16UnitsToUtf8Units, mapUtf8UnitsToUtf16Units, } from "../vsdiagnostic.js";
6
4
  export const qsharpLibraryUriScheme = "qsharp-library-source";
7
5
  export class QSharpLanguageService {
8
6
  constructor(wasm, readFile = () => Promise.resolve(null), listDir = () => Promise.resolve([]), getManifest = () => Promise.resolve(null)) {
9
7
  this.eventHandler = new EventTarget();
10
- // We need to keep a copy of the code for mapping diagnostics to utf16 offsets
11
- this.code = {};
12
8
  log.info("Constructing a QSharpLanguageService instance");
13
9
  this.languageService = new wasm.LanguageService();
14
10
  this.backgroundWork = this.languageService.start_background_work(this.onDiagnostics.bind(this), readFile, listDir, getManifest);
15
11
  this.readFile = readFile;
16
12
  }
17
- async loadFile(uri) {
18
- const result = this.code[uri];
19
- if (result === undefined || result === null) {
20
- return await this.readFile(uri);
21
- }
22
- if (result === null || result === undefined) {
23
- log.error("File", uri, "wasn't in document map when we expected it to be");
24
- return null;
25
- }
26
- return result;
27
- }
28
13
  async updateConfiguration(config) {
29
14
  this.languageService.update_configuration(config);
30
15
  }
31
16
  async updateDocument(documentUri, version, code) {
32
- this.code[documentUri] = code;
33
17
  this.languageService.update_document(documentUri, version, code);
34
18
  }
35
19
  async updateNotebookDocument(notebookUri, version, metadata, cells) {
36
- // Note: If a cell was deleted, its uri & contents will remain in the map.
37
- // This is harmless and it keeps the code simpler to just leave it this way
38
- // instead of trying to maintain a perfect map.
39
- for (const cell of cells) {
40
- this.code[cell.uri] = cell.code;
41
- }
42
20
  this.languageService.update_notebook_document(notebookUri, metadata, cells);
43
21
  }
44
22
  async closeDocument(documentUri) {
45
- delete this.code[documentUri];
46
23
  this.languageService.close_document(documentUri);
47
24
  }
48
25
  async closeNotebookDocument(documentUri) {
49
26
  this.languageService.close_notebook_document(documentUri);
50
27
  }
51
- async getCompletions(documentUri, offset) {
52
- const code = await this.loadFile(documentUri);
53
- if (code === null) {
54
- log.error(`getCompletions: expected ${documentUri} to be in the document map`);
55
- return { items: [] };
56
- }
57
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
58
- const result = this.languageService.get_completions(documentUri, convertedOffset);
59
- result.items.forEach((item) => item.additionalTextEdits?.forEach((edit) => {
60
- updateSpanFromUtf8ToUtf16(edit.range, code);
61
- }));
62
- return result;
63
- }
64
- async getHover(documentUri, offset) {
65
- const code = await this.loadFile(documentUri);
66
- if (code === null) {
67
- log.error(`getHover: expected ${documentUri} to be in the document map`);
68
- return undefined;
69
- }
70
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
71
- const result = this.languageService.get_hover(documentUri, convertedOffset);
72
- if (result) {
73
- updateSpanFromUtf8ToUtf16(result.span, code);
74
- }
75
- return result;
28
+ async getCompletions(documentUri, position) {
29
+ return this.languageService.get_completions(documentUri, position);
76
30
  }
77
- async getDefinition(documentUri, offset) {
78
- const sourceCode = await this.loadFile(documentUri);
79
- if (sourceCode === undefined || sourceCode === null) {
80
- log.error(`getDefinition: expected ${documentUri} to be in the document map`);
81
- return undefined;
82
- }
83
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], sourceCode)[offset];
84
- const result = this.languageService.get_definition(documentUri, convertedOffset);
85
- if (result) {
86
- let targetCode = (await this.loadFile(result.source)) || null;
87
- if (targetCode === null) {
88
- // Inspect the URL protocol (equivalent to the URI scheme + ":").
89
- // If the scheme is our library scheme, we need to call the wasm to
90
- // provide the library file's contents to do the utf8->utf16 mapping.
91
- const url = new URL(result.source);
92
- if (url.protocol === qsharpLibraryUriScheme + ":") {
93
- targetCode = wasm.get_library_source_content(url.pathname) || null;
94
- if (targetCode === undefined) {
95
- log.error(`getDefinition: expected ${url} to be in the library`);
96
- return undefined;
97
- }
98
- }
99
- }
100
- if (targetCode) {
101
- updateSpanFromUtf8ToUtf16(result.span, targetCode);
102
- }
103
- else {
104
- // https://github.com/microsoft/qsharp/issues/851
105
- log.error(`cannot do utf8->utf16 mapping for ${result.source} since contents are not available`);
106
- }
107
- }
108
- return result;
31
+ async getHover(documentUri, position) {
32
+ return this.languageService.get_hover(documentUri, position);
109
33
  }
110
- async getReferences(documentUri, offset, includeDeclaration) {
111
- const sourceCode = await this.loadFile(documentUri);
112
- if (sourceCode === undefined || sourceCode === null) {
113
- log.error(`getReferences: expected ${documentUri} to be in the document map`);
114
- return [];
115
- }
116
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], sourceCode)[offset];
117
- const results = this.languageService.get_references(documentUri, convertedOffset, includeDeclaration);
118
- if (results && results.length > 0) {
119
- const references = [];
120
- for (const result of results) {
121
- let resultCode = await this.loadFile(result.source);
122
- // Inspect the URL protocol (equivalent to the URI scheme + ":").
123
- // If the scheme is our library scheme, we need to call the wasm to
124
- // provide the library file's contents to do the utf8->utf16 mapping.
125
- const url = new URL(result.source);
126
- if (url.protocol === qsharpLibraryUriScheme + ":") {
127
- resultCode = wasm.get_library_source_content(url.pathname) || null;
128
- if (resultCode === undefined) {
129
- log.error(`getReferences: expected ${url} to be in the library`);
130
- }
131
- }
132
- if (resultCode) {
133
- updateSpanFromUtf8ToUtf16(result.span, resultCode);
134
- references.push(result);
135
- }
136
- else {
137
- // https://github.com/microsoft/qsharp/issues/851
138
- log.error(`cannot do utf8->utf16 mapping for ${result.source} since contents are not available`);
139
- }
140
- }
141
- return references;
142
- }
143
- else {
144
- return [];
145
- }
34
+ async getDefinition(documentUri, position) {
35
+ return this.languageService.get_definition(documentUri, position);
146
36
  }
147
- async getSignatureHelp(documentUri, offset) {
148
- const code = await this.loadFile(documentUri);
149
- if (code === null) {
150
- log.error(`expected ${documentUri} to be in the document map`);
151
- return undefined;
152
- }
153
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
154
- const result = this.languageService.get_signature_help(documentUri, convertedOffset);
155
- if (result) {
156
- result.signatures = result.signatures.map((sig) => {
157
- sig.parameters = sig.parameters.map((param) => {
158
- updateSpanFromUtf8ToUtf16(param.label, sig.label);
159
- return param;
160
- });
161
- return sig;
162
- });
163
- }
164
- return result;
37
+ async getReferences(documentUri, position, includeDeclaration) {
38
+ return this.languageService.get_references(documentUri, position, includeDeclaration);
165
39
  }
166
- async getRename(documentUri, offset, newName) {
167
- const code = await this.loadFile(documentUri);
168
- if (code === null) {
169
- log.error(`expected ${documentUri} to be in the document map`);
170
- return undefined;
171
- }
172
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
173
- const result = this.languageService.get_rename(documentUri, convertedOffset, newName);
174
- const mappedChanges = [];
175
- for (const [uri, edits] of result.changes) {
176
- const code = await this.loadFile(uri);
177
- if (code) {
178
- const mappedEdits = edits.map((edit) => {
179
- updateSpanFromUtf8ToUtf16(edit.range, code);
180
- return edit;
181
- });
182
- mappedChanges.push([uri, mappedEdits]);
183
- }
184
- }
185
- result.changes = mappedChanges;
186
- return result;
187
- }
188
- async prepareRename(documentUri, offset) {
189
- const code = await this.loadFile(documentUri);
190
- if (code === null) {
191
- log.error(`expected ${documentUri} to be in the document map`);
192
- return undefined;
193
- }
194
- const convertedOffset = mapUtf16UnitsToUtf8Units([offset], code)[offset];
195
- const result = this.languageService.prepare_rename(documentUri, convertedOffset);
196
- if (result) {
197
- updateSpanFromUtf8ToUtf16(result.range, code);
198
- }
199
- return result;
40
+ async getSignatureHelp(documentUri, position) {
41
+ return this.languageService.get_signature_help(documentUri, position);
42
+ }
43
+ async getRename(documentUri, position, newName) {
44
+ return this.languageService.get_rename(documentUri, position, newName);
45
+ }
46
+ async prepareRename(documentUri, position) {
47
+ return this.languageService.prepare_rename(documentUri, position);
200
48
  }
201
49
  async dispose() {
202
50
  this.languageService.stop_background_work();
@@ -211,26 +59,11 @@ export class QSharpLanguageService {
211
59
  }
212
60
  async onDiagnostics(uri, version, diagnostics) {
213
61
  try {
214
- const code = await this.loadFile(uri);
215
- const empty = diagnostics.length === 0;
216
- if (code === null && !empty) {
217
- // We need the contents of the document to convert error offsets to utf16.
218
- // But the contents aren't available after a document is closed.
219
- // It is possible to get diagnostics events for a document after it's been closed,
220
- // since document events are handled asynchronously by the language service.
221
- // We just drop those diagnostics, assuming that eventually we will receive further
222
- // events that will bring the diagnostics up to date.
223
- // However, if we receive an *empty* array of diagnostics for a document, we don't want
224
- // to drop that update. It's necessary for the diagnostics to get cleared for a document
225
- // that has been closed.
226
- log.warn(`onDiagnostics: received diagnostics for ${uri} which is not in the document map`);
227
- return;
228
- }
229
62
  const event = new Event("diagnostics");
230
63
  event.detail = {
231
64
  uri,
232
65
  version: version ?? 0,
233
- diagnostics: empty ? [] : mapDiagnostics(diagnostics, code),
66
+ diagnostics,
234
67
  };
235
68
  this.eventHandler.dispatchEvent(event);
236
69
  }
@@ -239,8 +72,3 @@ export class QSharpLanguageService {
239
72
  }
240
73
  }
241
74
  }
242
- function updateSpanFromUtf8ToUtf16(span, code) {
243
- const mappedSpan = mapUtf8UnitsToUtf16Units([span.start, span.end], code);
244
- span.start = mappedSpan[span.start];
245
- span.end = mappedSpan[span.end];
246
- }
package/dist/log.js CHANGED
@@ -55,9 +55,8 @@ export const log = {
55
55
  * @param args - The format string and args to log, e.g. ["Index of %s is %i", str, index]
56
56
  */
57
57
  logWithLevel(level, target, ...args) {
58
- // Convert to a format string containing the target (if present)
59
- const [, ...trailingArgs] = args; // All but first element of args
60
- const outArgs = [`[%s] ${args[0]}`, target || "", ...trailingArgs];
58
+ const [firstArg, ...trailingArgs] = args;
59
+ const outArgs = [`[${target || ""}] ${firstArg}`, ...trailingArgs];
61
60
  switch (level) {
62
61
  case 1:
63
62
  log.error(...outArgs);