Strukturen för ett Q# program

Den här artikeln utforskar de allmänna komponenter som utgör ett Q# program. Observera att program som Q# skrivits i Jupyter Notebooks inte använder några av dessa komponenter – dessa skillnader beskrivs i varje avsnitt.

Överväg följande Q# program:

namespace Superposition {

    @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);
        // We reset the qubit before releasing it.
        Reset(q);
        // Finally, we return the result of the measurement.
        return result;
    }
}

Genom att bara läsa kommentarerna (//) kan du se att det här programmet allokerar en qubit, tillämpar en åtgärd för att placera den i superposition, mäter qubitens tillstånd, återställer den och returnerar resultatet.

Information om hur du kör det här programmet i Visual Studio Code finns i Kom igång med Q# program och VS Code.

Användarnamnområden

Q# program börjar vanligtvis med ett namnområde med namnet användare, till exempel

namespace Superposition {
    // Your code goes here.
}

Namnområden hjälper dig att organisera relaterade funktioner. Namnområden är användarnamn och det kan bara finnas en namespace per qsharp-fil (*.qs).

Standardbiblioteket Q# har fördefinierade namnrymder som innehåller funktioner och åtgärder som du kan använda i kvantprogram. Mer information finns i Inbyggda namnområden.

Jupyter Notebooks använder inte användarnamnområden.

EntryPoint()

Attributet @EntryPoint() talar om Q# för kompilatorn var programmet ska börja köras. I program med flera funktions- och åtgärdsdefinitioner @EntryPoint() kan placeras innan någon av funktionerna eller åtgärderna och programflödet börjar därifrån och fortsätter sekventiellt.

    ...
    @EntryPoint()
    operation MeasureOneQubit() : Result {
        ...

Jupyter Notebooks använder inte startpunkter.

Kommandot %%qsharp

Som standard Q# använder program i Jupyter Notebooks Python-kerneln ipykernel . För att kunna lägga Q# till kod i en notebook-cell måste du använda %%qsharp kommandot , som är aktiverat med qsharp Python-paketet. Den tidigare exempelkoden i en Jupyter Notebook ser till exempel ut så här:

import qsharp
%%qsharp

    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);
        // We reset the qubit before releasing it.
        Reset(q);
        // Display the result
        Message($"Result is {result}");
        // Finally, we return the result of the measurement.
        return result;
    
    }
    MeasureOneQubit();

Observera avsaknaden av ett användarnamn eller ett @EntryPoint(), som inte behövs för Jupyter Notebooks. I stället för en startpunkt anropas åtgärden direkt på den sista raden. Observera också att en Message instruktion har lagts till i Jupyter Notebook kod för att visa resultatet. När du kör det tidigare Q# programmet i VS Code visar den inbyggda simulatorn resultatet som standard.

När du använder %%qsharp kommandot :

  • Du måste köra import qsharp först för att aktivera %%qsharp kommandot.
  • Kommandot %%qsharp är begränsat till hela cellen där den visas. Observera att den ändrar celltypen för notebook-filer från Python till Q#.
  • Koden Q# som följer kommandot måste följa standardkodningssyntaxen Q# . Du kan till exempel ange kommentarer med hjälp // av # i stället för inuti %%qsharp celler, och kodrader måste sluta med semikolon ;.
  • Kommandot %%qsharp kan inte föregås av eller följas av en Python-instruktion i cellen.

Ett exempel på hur du arbetar med ett Jupyter Notebook program finns i Kom igång med Q# program och VS Code.

Typer

Q# innehåller många inbyggda typer som är gemensamma för de flesta språk, inklusive Int, Double, Booloch String, tillsammans med typer som är specifika för kvantberäkning. Typen representerar till exempel Result resultatet av valfritt kvantbitsmått och kan ha ett av två möjliga definierade värden: One och Zero. I exempelprogrammet förväntar sig åtgärden MeasureOneQubit() en returtyp av Result och M åtgärden mäter kvantbiten och returnerar Result.

...
// operation definition expecting a return type of Result
operation MeasureOneQubit() : Result {
    ...
    // Now we measure the qubit in Z-basis, returning a Result type
    let result = M(q);
    ...
}

Q# innehåller också typer som definierar intervall, matriser och tupplar. Du kan även definiera dina egna anpassade typer.

Allokera qubitar

I Q#allokeras kvantbitar via nyckelordet use .

Vårt exempel definierar en enda qubit:

// Allocate a qubit.
use q = Qubit();
...

men du kan också allokera flera kvantbitar och komma åt var och en via dess index:

...
use qubits = Qubit[2];
X(qubits[1]);
H(qubits[0]);
...

Som standard börjar varje qubit som du allokerar med nyckelordet use i tillståndet noll. Varje qubit måste återställas till nolltillståndet innan det släpps i slutet av programmet. Om du inte återställer en qubit utlöses ett körningsfel.

// Reset a qubit.
Reset(q);
...

Kvantåtgärder

När en kvantbit har allokerats kan den skickas till åtgärder och funktioner, som även kallas anropsbara objekt. Åtgärder är de grundläggande byggstenarna i ett Q# program. En Q# åtgärd är en kvantunderrutin. Den är alltså en anropsbar rutin som innehåller kvantåtgärder som ändrar qubitregistrets tillstånd.

Om du vill definiera en Q# åtgärd anger du ett namn för åtgärden tillsammans med dess indata och utdata. I vårt exempel är den enskilda åtgärden i princip hela programmet. Det tar inga parametrar och förväntar sig en returtyp av Result:

operation MeasureOneQubit() : Result {
    ...
}

Här är ett grundläggande exempel som inte tar några parametrar och förväntar sig inget returvärde. Värdet Unit motsvarar NULL på andra språk.

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

Standardbiblioteket Q# innehåller även åtgärder som du kan använda i dina program, till exempel Hadamard eller den H åtgärd som används i exempelprogrammet. Med en kvantbit i Z-basis H placerar åtgärden kvantbiten i en jämn superposition. Väl i superposition har kvantbiten 50 % chans att mätas som noll eller en.

Mäta kvantbitar

Det finns många typer av kvantmått, men Q# fokuserar på projektiva mätningar på enskilda kvantbitar, även kallade Pauli-mätningar. Vid mätning i en viss bas (till exempel beräkningsbasen $\ket{0},\ket{1}$) beräknas kvantbitstillståndet till det bastillstånd som mättes, vilket förstör eventuell superposition mellan de två.

Vårt exempelprogram använder M åtgärden , som utför en mätning av en enda qubit i Pauli Z-basen och returnerar en Result typ.

Inbyggda namnområden

Q# Standardbiblioteket använder inbyggda namnrymder som innehåller funktioner och åtgärder som du kan använda i kvantprogram. Namnområdet Microsoft.Quantum.Intrinsic innehåller till exempel vanliga åtgärder och funktioner som M, för att mäta resultat och Message, för att visa användarmeddelanden var som helst i programmet.

Du kan anropa en funktion eller åtgärd genom att ange det fullständiga namnområdet eller använda en open -instruktion för att göra alla funktioner och åtgärder för det namnområdet tillgängliga och för att göra koden enklare att läsa. De här två exemplen anropar samma åtgärd:

 Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
open Microsoft.Quantum.Intrinsic;
Message("Hello quantum world!");

Observera i exempelprogrammet att det inte finns några open instruktioner eller anrop med fullständiga namnrymder. Det beror på att Q# utvecklingsmiljön automatiskt läser in två namnrymder som standard – Microsoft.Quantum.Core och Microsoft.Quantum.Intrinsic – som innehåller vanliga funktioner och åtgärder.

Du kan dra nytta av Microsoft.Quantum.Measurement namnområdet och använda MResetZ åtgärden för att optimera koden i exempelprogrammet. MResetZ kombinerar mått- och återställningsåtgärderna till ett steg, som i följande exempel:

namespace Superposition {

    // open the namespace for the MResetZ operation
    open Microsoft.Quantum.Measurement;

    @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);   
        // Measure and reset the qubit, and return the result value   
        return MResetZ(q);
    }
    
}