Estrutura de um Q# programa
Este artigo explora os componentes gerais que compõem um Q# programa. Observe que Q# os programas escritos no Jupyter Notebooks não usam alguns desses componentes – essas diferenças são descritas em cada seção.
Considere o seguinte programa Q#:
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;
}
}
Apenas lendo os comentários (//), você pode dizer que este programa aloca um qubit, aplica uma operação para colocá-lo em superposição, mede o estado do qubit, redefine-o e retorna o resultado.
Para executar este programa no Visual Studio Code, consulte Introdução a Q# programas e VS Code.
Namespaces de usuário
Q# os programas normalmente começam com um namespace nomeado pelo usuário, como
namespace Superposition {
// Your code goes here.
}
Os namespaces ajudam você a organizar a funcionalidade relacionada. Os namespaces são nomeados pelo usuário e só pode haver um namespace
por arquivo qsharp (*.qs).
A Q# biblioteca padrão tem namespaces predefinidos que contêm funções e operações que você pode usar em programas quânticos. Para obter mais informações, consulte Namespaces internos.
Os Jupyter Notebooks não usam namespaces de usuário.
EntryPoint()
O @EntryPoint()
atributo informa ao Q# compilador onde começar a executar o programa. Em programas com várias definições de função e operação, o @EntryPoint()
pode ser colocado antes que qualquer uma das funções ou operações e o fluxo do programa comece a partir daí e continue sequencialmente.
...
@EntryPoint()
operation MeasureOneQubit() : Result {
...
Os Jupyter Notebooks não usam pontos de entrada.
O comando %%qsharp
Por padrão, Q# os programas no Jupyter Notebooks usam o kernel do Python ipykernel . Para adicionar Q# código a uma célula do notebook, você precisa usar o %%qsharp
comando , que está habilitado com o pacote do qsharp
Python. Por exemplo, o código de exemplo anterior em um Jupyter Notebook tem esta aparência:
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();
Observe a ausência de um namespace de usuário ou um @EntryPoint()
, que não são necessários para Jupyter Notebooks. Em vez de um ponto de entrada, a operação é chamada diretamente na última linha. Observe também que uma Message
instrução foi adicionada ao código Jupyter Notebook para exibir o resultado. Quando você executa o programa anterior Q# no VS Code, o simulador interno exibe o resultado por padrão.
Ao usar o %%qsharp
comando :
- Você deve executar
import qsharp
primeiro para habilitar o comando%%qsharp
. - O
%%qsharp
comando tem como escopo toda a célula na qual ele aparece. - O código Q# que segue o comando deve aderir à sintaxe de codificação Q# padrão. Por exemplo, você denota comentários usando
//
em vez de dentro%%qsharp
das#
células, e as linhas de código devem terminar com um ponto e vírgula;
. - O comando
%%qsharp
não pode ser precedido ou seguido por uma instrução Python na célula.
Para obter um exemplo de como trabalhar com um programa Jupyter Notebook, consulte Introdução a Q# programas e VS Code.
Tipos
Q# fornece muitos tipos internos que são comuns à maioria das linguagens, incluindo Int
, Double
, Bool
e String
, juntamente com tipos específicos da computação quântica. Por exemplo, o Result
tipo representa o resultado de qualquer medida de qubit e pode ter um dos dois valores definidos possíveis: One
e Zero
. No programa de exemplo, a operação MeasureOneQubit()
espera um tipo de retorno de Result
e a M
operação mede o qubit e retorna o 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);
...
}
O Q# também fornece tipos que definem intervalos, matrizes e tuplas. Você pode até mesmo definir seus tipos personalizados.
Alocação de qubits
No Q#, qubits são alocados por meio da palavra-chave use
.
Nosso exemplo define um único qubit:
// Allocate a qubit.
use q = Qubit();
...
mas você também pode alocar vários qubits e acessar cada um por meio de seu índice:
...
use qubits = Qubit[2];
X(qubits[1]);
H(qubits[0]);
...
Por padrão, cada qubit que você aloca com a palavra-chave use
começa no estado zero. Cada qubit deve ser redefinido para o estado zero antes de ser lançado no final do programa. Falha ao redefinir um qubit dispara um erro de runtime.
// Reset a qubit.
Reset(q);
...
Operações quânticas
Uma vez alocado, um qubit pode ser passado para operações e funções, também conhecido como chamadores. Operações são os blocos de construção básicos de um programa em Q#. Uma operação Q# é uma sub-rotina quântica. Ou seja, é uma rotina que pode ser chamada e que contém operações quânticas que modificam o estado do registro do qubit.
Para definir uma operação de Q#, especifique um nome para a operação junto com as respectivas entradas e saída. Em nosso exemplo, a única operação é essencialmente o programa inteiro. Ele não usa parâmetros e espera um tipo de retorno de Result
:
operation MeasureOneQubit() : Result {
...
}
Aqui está um exemplo básico que não usa parâmetros e não espera nenhum valor retornado. O Unit
valor é equivalente a NULL
em outros idiomas.
operation SayHelloQ() : Unit {
Message("Hello quantum world!");
}
A Q# biblioteca padrão também fornece operações que você pode usar em seus programas, por exemplo, o Hadamard ou a H
operação usada no programa de exemplo. Considerando um qubit em base Z, a operação H
coloca o qubit em uma sobreposição uniforme. Uma vez em sobreposição, o qubit tem uma chance de 50% de ser medido como zero ou um.
Medindo qubits
Há muitos tipos de medidas quânticas, mas Q# se concentra em medidas projetivas em qubits únicos, também conhecidos como medidas Pauli. Na medida em uma determinada base (por exemplo, a base computacional $\ket{0},\ket{1}$), o estado do qubit é projetado para o estado base que foi medido, destruindo eventual sobreposição existente entre os dois.
Nosso programa de exemplo usa a M
operação , que executa uma medida de um único qubit na base Pauli Z e retorna um Result
tipo.
Namespaces internos
A biblioteca padrão Q# usa namespaces internos que contêm funções e operações que você pode usar em programas quânticos. Por exemplo, o namespace Microsoft.Quantum.Intrinsic
contém operações e funções comumente usadas, como M
, para medir os resultados e Message
, para exibir mensagens de usuário em qualquer lugar do programa.
Você pode chamar uma função ou operação especificando o namespace completo ou usar uma instrução open
para disponibilizar todas as funções e operações para esse namespace e facilitar a leitura do código. Esses dois exemplos chamam a mesma operação:
Microsoft.Quantum.Intrinsic.Message("Hello quantum world!");
open Microsoft.Quantum.Intrinsic;
Message("Hello quantum world!");
Observe que, no programa de exemplo, não open
há instruções ou chamadas com namespaces completos. Isso ocorre porque o Q# ambiente de desenvolvimento carrega automaticamente dois namespaces por padrão - Microsoft.Quantum.Core
e Microsoft.Quantum.Intrinsic
- que contêm funções e operações comumente usadas.
Você pode aproveitar o Microsoft.Quantum.Measurement
namespace e usar a MResetZ
operação para otimizar o código no programa de exemplo. MResetZ
combina as operações de medida e redefinição em uma etapa, como no exemplo a seguir:
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);
}
}
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de