Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Um programa sempre começa sem qubits, o que significa que você não pode passar valores do tipo Qubit
como argumentos de ponto de entrada. Esta restrição é intencional, uma vez que o objetivo do Q# é expressar e raciocinar sobre um programa em sua totalidade.
Em vez disso, um programa aloca e libera qubits, ou memória quântica, como ele vai.
A este respeito, Q# modela o computador quântico como uma pilha de qubit.
Em vez de suportar separadas alocar e liberar instruções para memória quântica, Q# suporta alocação de memória quântica na forma de instruções de bloco, onde a memória é acessível apenas dentro do escopo dessa instrução de bloco. O bloco de instrução pode ser implicitamente definido ao alocar qubits para a duração do escopo atual, conforme descrito com mais detalhes nas seções sobre as instruções use
e borrow
. A tentativa de acessar os qubits alocados após o encerramento da instrução resulta em uma exceção de tempo de execução.
Q# tem duas instruções, use
e borrow
, que instanciam valores de qubit, matrizes de qubits ou qualquer combinação deles. Você só pode usar essas declarações dentro de operações. Eles reúnem os valores de qubit instanciados, vinculam-nos às variáveis especificadas na instrução e, em seguida, executam um bloco de instruções.
No final do bloco, as variáveis vinculadas saem do escopo e não são mais definidas.
Q# distingue entre a atribuição de limpo e qubits sujos. Qubits limpos são desembaraçados e não são usados por outra parte da computação. Qubits sujos são qubits cujo estado é desconhecido e podem até ser emaranhados com outras partes da memória do processador quântico.
Declaração de utilização
Qubits limpos são alocados pela instrução use
.
- A instrução consiste na palavra-chave
use
seguida por um bloco de instrução vinculante e opcional. - Se um bloco de instrução estiver presente, os qubits só estarão disponíveis dentro desse bloco. Caso contrário, os qubits estarão disponíveis até o final do escopo atual.
- A ligação segue o mesmo padrão que
let
instruções: um único símbolo ou uma tupla de símbolos, seguido por um sinal de igual=
, e uma única tupla ou uma tupla correspondente de inicializadores.
Os inicializadores estão disponíveis para um único qubit, indicado como Qubit()
, ou uma matriz de qubits, Qubit[n]
, onde n
é uma expressão Int
.
Por exemplo
use qubit = Qubit();
// ...
use (aux, register) = (Qubit(), Qubit[5]);
// ...
use qubit = Qubit() {
// ...
}
use (aux, register) = (Qubit(), Qubit[5]) {
// ...
}
É garantido que os qubits estejam em um estado |0⟩ após a alocação. Eles são liberados no final do escopo e devem estar em um estado |0⟩ após a liberação. Este requisito não é imposto pelo compilador, uma vez que isso exigiria uma avaliação simbólica que rapidamente se torna proibitivamente cara. Ao executar em simuladores, o requisito pode ser imposto em tempo de execução. Em processadores quânticos, o requisito não pode ser imposto em tempo de execução; Um qubit não medido pode ser redefinido para |0⟩ por meio de transformação unitária. Não fazer isso resulta em comportamento incorreto.
A instrução use
aloca os qubits do heap de qubit livre do processador quântico e os retorna ao heap o mais tardar no final do escopo no qual os qubits estão vinculados.
Declaração de empréstimo
A instrução borrow
concede acesso a qubits que já estão alocados, mas não estão em uso no momento. Esses qubits podem estar em um estado arbitrário e precisam estar no mesmo estado novamente quando a declaração de empréstimo termina.
Alguns algoritmos quânticos podem usar qubits sem depender de seu estado exato e sem exigir que eles estejam desembaraçados com o resto do sistema. Ou seja, eles exigem qubits extras temporariamente, mas podem garantir que esses qubits sejam retornados exatamente ao seu estado original, independentemente de qual estado foi.
Se houver qubits que estão em uso, mas não são tocados durante partes de uma sub-rotina, esses qubits podem ser emprestados para uso por tal algoritmo em vez de alocar memória quântica adicional. Tomar emprestado em vez de alocar pode reduzir significativamente os requisitos gerais de memória quântica de um algoritmo e é um exemplo quântico de uma compensação espaço-tempo típica.
Uma instrução borrow
segue o mesmo padrão descrito anteriormente para a instrução use
, com os mesmos inicializadores disponíveis.
Por exemplo
borrow qubit = Qubit();
// ...
borrow (aux, register) = (Qubit(), Qubit[5]);
// ...
borrow qubit = Qubit() {
// ...
}
borrow (aux, register) = (Qubit(), Qubit[5]) {
// ...
}
Os qubits emprestados estão em um estado desconhecido e saem do escopo no final do bloco de demonstração. O mutuário compromete-se a deixar os qubits no mesmo estado em que se encontravam quando foram emprestado; ou seja, espera-se que seu estado no início e no final do bloco de instruções seja o mesmo.
A instrução borrow
recupera qubits em uso que são garantidos não serem usados pelo programa desde o momento em que o qubit é vinculado até o último uso desse qubit.
Se não houver qubits suficientes disponíveis para empréstimo, então os qubits são alocados e retornados para a pilha como uma instrução use
.
Observação
Entre os casos de uso conhecidos de qubits sujos estão implementações de portas CNOT multi-controladas que exigem muito poucos qubits, e implementações de incrementadores. Este artigo sobre factoring com qubits fornece um exemplo de um algoritmo que utiliza qubits emprestados.