Wie sind Q#-Programme strukturiert?

Abgeschlossen

Die Q#-Quantenprogrammiersprache verfügt über eine klar definierte Struktur. In dieser Einheit überprüfen Sie die Hauptkomponenten eines Q#-Programms.

Namespace

Jede Q#-Datei beginnt mit einem Namespace. Ein Beispiel:

namespace HelloQuantum {
    // Your code goes here.
}

Das namespace-Schlüsselwort wird verwendet, um einen Namespace zu definieren. Namespaces werden verwendet, um Q#-Code in logische Einheiten zu organisieren. Sie werden wichtig, wenn Sie Q#-Bibliotheken in ihren Programmen verwenden und eigene Bibliotheken schreiben.

Libraries

Q#-Bibliotheken enthalten Funktionen und Vorgänge, die Sie in Quantenprogrammen verwenden können. Wenn Sie eine Funktion oder einen Vorgang aus einer Bibliothek abrufen, verwenden Sie die open-Direktive und geben Sie den Namespace der Bibliothek an. Beispiel:

namespace HelloQuantum {

    open Microsoft.Quantum.Intrinsic;

    @EntryPoint()
    operation HelloQ() : Unit {
        Message("Hello quantum world!");
    }
}

In diesem Beispiel weist die open-Direktive den Q#-Compiler an, nach dem Message-Vorgang im Microsoft.Quantum.Intrinsic-Namespace zu suchen.

Einstiegspunkte

EntryPoint weist den Q#-Compiler an, wo mit der Ausführung des Programms begonnen werden soll. Jedes Q#-Programm muss mindestens einen Einstiegspunkt aufweisen, gefolgt von einem Vorgang.

Zuordnen von Qubits

In Q# verwenden Sie zum Abrufen eines Qubit das Schlüsselwort use. Jedes Qubit, das Sie mit dem Schlüsselwort use zuordnen, beginnt im Zustand null.

Sie können ein oder mehrere Qubits gleichzeitig zuordnen. Hier ist ein Beispiel, das ein und fünf Qubits zuweist:

use q1 = Qubit(); // Allocate one qubit
use q5 = Qubit[5]; // Allocate five qubits

Quantenvorgänge

Vorgänge sind die grundlegenden Bausteine eines Q#-Programms. Ein Q#-Vorgang ist eine Quantenunterroutine. Das heißt, es handelt sich um eine aufrufbare Routine, die Quantenvorgänge enthält, mit denen der Zustand des Qubit-Registers geändert wird.

Um einen Q#-Vorgang zu definieren, geben Sie einen Namen für den Vorgang und dessen Ein- und Ausgabe an. Im Folgenden finden Sie ein einfaches Beispiel:

@EntryPoint()
operation SayHelloQ() : Unit {
    Message("Hello quantum world!");
}

Der Name des Vorgangs lautet hierbei SayHelloQ. Er akzeptiert null Argumente als Eingabe und gibt den Typ Unit zurück. Dies bedeutet, dass der Vorgang keine Informationen zurückgibt.

Q#-Bibliotheken enthalten auch Vorgänge, die Sie in ihren Programmen verwenden können. Ein Vorgang, den Sie später verwenden, ist der H-Vorgang. Bei einem Qubit auf Z-Basis versetzt der H-Vorgang das Qubit in eine ausgeglichene Superposition. Wenn sich das Qubit in Superposition befindet, ist die Wahrscheinlichkeit jeweils 50 Prozent, dass eine Messung null oder eins ergibt.

Typen

Q# bietet viele integrierte Typen, mit denen Sie bereits vertraut sind, einschließlich Int, Double, Bool und String sowie Typen, die für das Quantencomputing spezifisch sind. Q# bietet auch Typen, die Bereiche, Arrays und Tupel definieren. Sie können sogar eigene benutzerdefinierte Typen definieren.

In diesem Modul arbeiten Sie mit dem Typ Result. Ein Result stellt das Ergebnis einer Qubit-Messung dar und kann einen von zwei möglichen Werten aufweisen: One und Zero.

Messen von Qubits

In Q# werden Pauli-Messungen durchgeführt, indem der Measure-Vorgang angewendet wird, der eine gemeinsame Messung eines oder mehrerer Qubits in den angegebenen Pauli-Basen durchführt. Der Measure-Vorgang gibt einen Result-Typ zurück, der entweder One oder Zero ist.

Hinweis

Wenn das Basisarray und das Qubitarray unterschiedliche Längen aufweisen, ist der Measure-Vorgang nicht erfolgreich.

Um eine Messung in der Rechenbasis {|0\ ,|1%} zu implementieren, können Sie auch den Vorgang verwenden, der M eine Messung eines einzelnen Qubits in der Pauli Z-Basis durchführt. Daher entspricht der M-Vorgang der Anwendung von Measure([PauliZ], [qubit]).

Ein einfaches Beispiel ist das folgende Programm, das einen Qubit im Zustand |0} zuordnet, dann einen Hadamard-Vorgang H darauf anwendet und das Ergebnis in der PauliZ Basis misst.

@EntryPoint()
operation MeasureOneQubit() : Result {
    // Allocate a qubit, by default it is in zero state      
    use q = Qubit();  
    // We apply a Hadamard operation H to the state
    // It now has a 50% chance of being measured 0 or 1  
    H(q);      
    // Now we measure the qubit in Z-basis.
    let result = M(q);

    // Reset the qubit so it can be safely released.
    Reset(qubit);
    return result;
}

Hinweis

Der Reset Vorgang wird verwendet, um den Qubit auf den Zustand '|0' zurückzusetzen. In F# müssen Qubits im Zustand "|0" liegen, wenn sie losgelassen werden.