Q#

Личный сайт Go-разработчика из Казани

Q# is a high-level domain-specific language which enables developers to write quantum algorithms. Q# programs can be executed on a quantum simulator running on a classical computer and (in future) on quantum computers.

1// Single-line comments start with // 2 3 4///////////////////////////////////// 5// 1. Quantum data types and operators 6 7// The most important part of quantum programs is qubits. 8// In Q# type Qubit represents the qubits which can be used. 9// This will allocate an array of two new qubits as the variable qs. 10operation QuantumDataTypes() : Unit { 11 use qs = Qubit[2]; 12 13 // The qubits have internal state that you cannot access to read or modify directly. 14 // You can inspect the current state of your quantum program 15 // if you're running it on a classical simulator. 16 // Note that this will not work on actual quantum hardware! 17 Std.Diagnostics.DumpMachine(); 18 19 // If you want to change the state of a qubit 20 // you have to do this by applying quantum gates to the qubit. 21 H(qs[0]); // This changes the state of the first qubit 22 // from |0⟩ (the initial state of allocated qubits) 23 // to (|0⟩ + |1⟩) / sqrt(2). 24 // qs[1] = |1⟩; - this does NOT work, you have to manipulate a qubit by using gates. 25 26 // You can apply multi-qubit gates to several qubits. 27 CNOT(qs[0], qs[1]); 28 29 // You can also apply a controlled version of a gate: 30 // a gate that is applied if all control qubits are in |1⟩ state. 31 // The first argument is an array of control qubits, 32 // the second argument is the target qubit. 33 Controlled Y([qs[0]], qs[1]); 34 35 // If you want to apply an anti-controlled gate 36 // (a gate that is applied if all control qubits are in |0⟩ state), 37 // you can use a library function. 38 ApplyControlledOnInt(0, X, [qs[0]], qs[1]); 39 40 // To read the information from the quantum system, you use measurements. 41 // Measurements return a value of Result data type: Zero or One. 42 // You can print measurement results as a classical value. 43 Message($"Measured {M(qs[0])}, {M(qs[1])}"); 44} 45 46 47///////////////////////////////////// 48// 2. Classical data types and operators 49 50function ClassicalDataTypes() : Unit { 51 // Numbers in Q# can be stored in Int, BigInt or Double. 52 let i = 1; // This defines an Int variable i equal to 1 53 let bi = 1L; // This defines a BigInt variable bi equal to 1 54 let d = 1.0; // This defines a Double variable d equal to 1 55 56 // Arithmetic is done as expected, as long as the types are the same 57 let n = 2 * 10; // = 20 58 // Q# does not have implicit type cast, 59 // so to perform arithmetic on values of different types, 60 // you need to cast type explicitly 61 let nd = Std.Convert.IntAsDouble(2) * 1.0; // = 20.0 62 63 // Boolean type is called Bool 64 let trueBool = true; 65 let falseBool = false; 66 67 // Logic operators work as expected 68 let andBool = true and false; 69 let orBool = true or false; 70 let notBool = not false; 71 72 // Strings 73 let str = "Hello World!"; 74 75 // Equality is == 76 let x = 10 == 15; // is false 77 78 // Range is a sequence of integers and can be defined like: start..step..stop 79 let xi = 1..2..7; // Gives the sequence 1,3,5,7 80 81 // Assigning new value to a variable: 82 // by default all Q# variables are immutable; 83 // if the variable was defined using let, you cannot reassign its value. 84 85 // When you want to make a variable mutable, you have to declare it as such, 86 // and use the set word to update value 87 mutable xii = true; 88 set xii = false; 89 90 // You can create an array for any data type like this 91 let xiii = [0.0, size = 10]; 92 93 // Getting an element from an array 94 let xiv = xiii[8]; 95 96 // Assigning a new value to an array element 97 mutable xv = [0.0, size = 10]; 98 set xv w/= 5 <- 1.0; 99} 100 101 102///////////////////////////////////// 103// 3. Control flow 104 105operation ControlFlow() : Unit { 106 let a = 1; 107 // If expressions support a true branch, elif, and else. 108 if (a == 1) { 109 // ... 110 } elif (a == 2) { 111 // ... 112 } else { 113 // ... 114 } 115 use qubits = Qubit[2]; 116 117 // For loops can be used to iterate over an array 118 for qubit in qubits { 119 X(qubit); 120 } 121 122 // Regular for loops can be used to iterate over a range of numbers 123 for index in 0..Length(qubits) - 1 { 124 X(qubits[index]); 125 } 126 127 // While loops are restricted for use in classical context only 128 mutable index = 0; 129 while (index < 10) { 130 set index += 1; 131 } 132 133 let success_criteria = true; 134 // Quantum equivalent of a while loop is a repeat-until-success loop. 135 // Because of the probabilistic nature of quantum computing sometimes 136 // you want to repeat a certain sequence of operations 137 // until a specific condition is achieved; you can use this loop to express this. 138 repeat { 139 // Your operation here 140 } until (success_criteria) // This could be a measurement to check if the state is reached 141 fixup { 142 // Resetting to the initial conditions, if required 143 } 144} 145 146///////////////////////////////////// 147// 4. Putting it all together 148 149// Q# code is written in operations and functions 150operation ApplyXGate(source : Qubit) : Unit { 151 X(source); 152} 153 154// If the operation implements a unitary transformation, you can define 155// adjoint and controlled variants of it. 156// The easiest way to do that is to add "is Adj + Ctl" after Unit. 157// This will tell the compiler to generate the variants automatically. 158operation ApplyXGateCA(source : Qubit) : Unit is Adj + Ctl { 159 X(source); 160} 161 162// Now you can call Adjoint ApplyXGateCA and Controlled ApplyXGateCA. 163 164 165// To run Q# code, you can put @EntryPoint() before the operation you want to run first 166operation XGateDemo() : Unit { 167 use q = Qubit(); 168 ApplyXGate(q); 169} 170 171// Here is a simple example: a quantum random number generator. 172// We will generate a classical array of random bits using quantum code. 173// Callables (functions or operations) named `Main` are used as entry points. 174operation Main() : Unit { 175 mutable bits = [0, size = 5]; // Array we'll use to store bits 176 use q = Qubit(); 177 { 178 // Allocate a qubit 179 for i in 0..4 { 180 // Generate each bit independently 181 H(q); // Hadamard gate sets equal superposition 182 let result = M(q); // Measure qubit gets 0|1 with 50/50 prob 183 let bit = result == Zero ? 0 | 1; // Convert measurement result to integer 184 set bits w/= i <- bit; // Write generated bit to an array 185 } 186 } 187 Message($"{bits}"); // Print the result 188}

Further Reading

The Quantum Katas (repo hosted tutorials offer great self-paced tutorials and programming exercises to learn quantum computing and Q#.

Q# Documentation is official Q# documentation, including language reference and user guides.