SlideShare uma empresa Scribd logo
1 de 24
CELSO DE SOUZA JÚNIOR
UMA INTRODUÇÃO À COMPUTAÇÃO QUÂNTICA COM Q#
RIO DE JANEIRO
Maio/2019
Resumo
Computação quântica não é um assunto novo. Já existem estudos sobre essa
disciplina a mais de cem anos. Até o próprio Albert Einstein usou a computação
quântica em suas pesquisas e estudos. Hoje em dia existem algumas soluções
sendo exploradas nas áreas de finanças, logística, saúde, entre outras. Como o
hardware tem barateado bastante ultimamente, criou-se uma nova especulação
acerca deste assunto. Pesquisadores dos dias atuais acreditam que talvez seja
finalmente a hora da computação quântica ajudar a desenvolver a sociedade em que
vivemos. Mas para isso, nós precisaremos de novos e avançados dispositivos de
hardware bem como de softwares mais robustos e inteligentes. Para ajudar nessa
revolução, têm surgido uma quantidade considerável de linguagens de programação
quânticas nos últimos tempos, a maioria delas está embutida em alguma outra
linguagem conhecida e é orientada a circuitos. Ou seja, elas recebem um circuito
como entrada em produzem um circuito como saída. Sendo que alguns algoritmos
quânticos podem empregar padrões que não podem ser expressados em circuitos.
Programadores precisam que preocupações de baixo nível sejam abstraídas para
que eles possam focar apenas na criação de algoritmos em uma linguagem de alto
nível, aumentando a sua produtividade sem que eles estejam limitados a circuitos.
Para resolver essa limitação imposta aos algoritmos pensados nas outras linguagens
de computação quântica existentes e outros problemas de produtividade, basta
adotar uma linguagem de programação nova, não orientada a circuitos que foi criada
especialmente para a computação quântica. E neste trabalho, será apresentada
essa nova linguagem e como é possível começar a trabalhar com ela visando um
aumento de produtividade e o avanço nas pesquisas.
Palavras-Chave: COMPUTAÇÃO QUÂNTICA; QSHARP; Q#;
2
1. Introdução
A computação clássica e a computação quântica são dois paradigmas de
computação diferentes. O modelo de computação utilizado hoje em dia na grande
maioria dos dispositivos é denominado computação clássica. As informações são
representadas por bits por meio de um sistema binário que opera basicamente entre
dois estados 0 ou 1. O bit é a menor unidade endereçável em um dispositivo de
computação clássica e pode representar, transmitir e/ou armazenar informações.
Tudo o que é exibido na tela do computador, tudo o que é processado, toda entrada
ou saída, seja texto, seja uma imagem, seja um arquivo, tudo é representado por
uma abstração de um conjunto de bits. Desde os primórdios da computação por
volta dos anos de 1945, onde começaram a surgir os primeiros computadores e as
primeiras linguagens de programação, as coisas evoluíram numa velocidade
inimaginável. Computadores que pesavam até uma tonelada e não cabiam numa
única sala, hoje em dia cabem na palma da mão e são dez vezes mais potentes.
Mas apesar dessa evolução absurda, uma coisa permanece a mesma desde
sempre: o modelo computacional.
A computação quântica não veio para substituir a computação clássica ao
contrário do que muitos pensam. Enquanto o modelo clássico de computação se
utiliza da lógica booleana para processamento de dados, as informações no modelo
de computação quântico são armazenados em estados quânticos da matéria e são
processados por meio de operações baseadas em interferência quântica. Assim
como os valores binários individuais são armazenados em um bit, os estados
quânticos são armazenados em qubits. O processamento de uma computação
quântica que opera em um ou mais quibit é chamada de gate. E uma sequência de
gates operando um conjunto de qubits é tradicionalmente chamada de circuito. A
maioria das linguagens de computação quântica existentes são efetivamente
descrições de circuitos. Ou seja, elas recebem um circuito como entrada e produzem
um circuito também como saída. Sendo que isso acaba limitando a criação de
alguns algoritmos que são muitas vezes impossíveis de serem representados por
meio de circuitos devido ao nível de abstração necessário. Desenvolvedoresde
3
software precisam que alguns detalhes operacionais de baixo nível sejam abstraídos
em uma linguagem de programação de alto nível, mas sem que eles sejam
impedidos de abordar detalhes que exigem tratamento explícito como correções de
erros, ruídos e temporizações. E essa é a idéia por trás da criação de uma nova
linguagem de programação quântica como expressado na citação a seguir:
No entanto, um desenvolvedor de software exige que esses detalhes
sejam abstraídos para que o foco seja mantido na expressão de um
algoritmo quântico de alto nível. (SVORE, GELLER, et al., 2018, p. 1,
tradução nossa)
Para atender a necessidade de expressividade e abstração, foi que os
pesquisadores da Microsoft®
Research em Readmond WA Estados Unidos
desenvolveram “uma linguagem especial que fornece uma separação clara entre o
código a ser executado no contexto quântico a partir do código do driver que pode
ser programado em uma linguagem tradicional de alto nível.” (SVORE, GELLER, et
al., 2018, p. 1, tradução nossa).
O computador quântico não veio para substituir os computadores clássicos,
mas sim para funcionar lado a lado com eles ou até com outros dispositivos.
Além disso, uma vez que apenas algumas partes computacionais de
um “programa” são de natureza quântica, é conveniente considerar
um computador quântico não como um dispositivo de computação
completo por si só (repleto de mecanismos para armazenamento,
comunicação de rede, interação de usuário e assim por diante), mas
sim como um co-processador externo, adjunto, para uma máquina
clássica. (SVORE, GELLER, et al., 2018, p. 1, tradução nossa)
E o Q# foi projetado para ajudar a abstrair a criação de códigos de baixo nível
para que programadores possam manter o foco apenas na criação de algoritmos de
alto nível com todo o poder oferecido pela linguagem. A seguir há uma explicação
mais detalhada sobre como o Q# pode ajudar nesse processo de abstração através
da automatização da geração do adjunto de uma transformação.
Sem a computação simbólica, a única maneira de produzir o adjunto
de uma transformação é explicitamente escrevê-la como parte do
código-base. No entanto, o Q# é capaz de empregar computação
simbólica poderosa e type-safe no corpo de uma determinada
operação para gerar automaticamente o adjunto, se for logicamente
4
possível fazê-lo. (SVORE, GELLER, et al., 2018, p. 1, tradução
nossa)
Q# (Leia-se “Q /quiu/ Sharp”) é uma linguagem de programação quântica de
alto nível — mais detalhes sobre linguagens de alto e de baixo nível são
apresentados por (REBELO, 2002) — que, até a data de elaboração deste trabalho
de pesquisa, era a única linguagem autônoma classificada como “linguagem de
definição de algoritmo e como tal, representa naturalmente a composição de
algoritmos clássicos e quânticos” (SVORE, GELLER, et al., 2018, p. 2, tradução
nossa) e não é uma linguagem embutida como as outras DSLs, do acrônimo em
inglês domain-specific language (Linguagem específica de domínio). Ela foi
desenvolvida com objetivo de atender a necessidade de expressar algoritmos
quânticos de forma clara e completa não orientada na criação, manipulação e/ou
transformação de circuitos.
Não há noção de um circuito em Q#, e há declarações Q#, por
exemplo, repeat-until-success, que não podem ser representados
como um circuito sem introduzir novas e especializadas portas e são
mais facilmente tratados como construções híbridas quânticas-
clássicas. Por exemplo, o Q# facilita a expressão de algoritmos de
estimação de fase e de química quântica, os quais requerem
interações quântico-clássicas ricas. (SVORE, GELLER, et al., 2018,
p. 2, tradução nossa)
Não serão abordados detalhes sobre algoritmos, no entanto PAETZNICK e
SVORE (2014) trazem mais informações sobre o algoritmo repeat-until-success
supracitado para aqueles mais interessados.
Será abordado como Q# pode ser usada para implementar algoritmos
quânticos existentes através de um olhar mais atento em algumas das
características da linguagem.
2. Objetivos
Este trabalho apresenta uma visão geral da computação quântica sob a
perspectiva do Q#, uma linguagem de programação recentemente desenvolvida
pelos pesquisadores da Microsoft®
Research que é autônoma, de alto nível e
5
específica de domínio, a fim de habilitar a abstração e o desenvolvimento
escalonável em favor da construção e análise de algoritmos claros e completos.
Será apresentado um breve tutorial de introdução à linguagem através de uma
demonstração de como usar os seus principais recursos.
1. Objetivo Geral
Servir como um material de referência introdutório à computação quântica
através da linguagem de programação Q#, bem como ilustrar a sua utilização básica
por meio de exemplos práticos.
2. Objetivos Específicos
● Apresentar uma breve introdução à computação quântica e sua
importância na transformação digital;
● Um pouco da história e evolução das linguagens de programação
quântica desenvolvidas nos últimos anos;
● Apresentar o modelo de computação quântica e a sua arquitetura
híbrida de execução;
● Como configurar um ambiente de desenvolvimento e começar a
praticar;
● Apresentar palavras reservadas, tipos de dados primitivos, funções,
operações, fluxo de controle, etc;
● Como debugar e testar programas em Q# bem como enviar
mensagens de erro para a aplicação hospedeira;
3. Justificativa
Já existe serviço de acesso à computação quântica (SANTOS, 2016), mas
devido às dificuldades na implementação, os computadores quânticos ainda não
estão disponíveis para o público geral apesar de várias empresas estarem
trabalhando em projetos de pesquisa neste sentido (CALUDE e CALUDE, 2017). No
entanto, os estudos de programação de computadores quânticos continuam
6
avançando por meio de modelos que representam o seu funcionamento, servindo
como base para a concepção de linguagens de programação e permitindo a sua
execução em computadores clássicos com algumas limitações. A computação
quântica explora fenômenos quânticos que seriam impossíveis de serem
reproduzidos na computação tradicional devido a sua natureza. Soluções que
levariam centenas de anos para processar nos computadores de hoje poderiam ser
processadas em segundos. Para ajudar na escrita de algoritmos que permitem esse
tipo poderoso de processamento é que várias linguagens de programação quântica
de alto nível têm sido criadas, mas a grande maioria das abstrações oferecidas
acabam por criar também algumas limitações.
Essa abordagem pode permitir cálculos sem sentido em um contexto
quântico, proibir a expressão sucinta da interação entre a lógica
clássica e a lógica quântica, e não fornecer construções importantes
que são necessárias para a programação quântica. (SVORE,
GELLER, et al., 2018, p.1, tradução nossa)
Várias linguagens de programação quântica foram desenvolvidas nos últimos
anos. Elas são conhecidas como “linguagens de definição de circuitos” (SVORE,
GELLER, et al., 2018, p. 2, tradução nossa)
1
e o nível de abstração oferecido por
elas possui foco na criação e manipulação de circuitos quânticos e/ou na
transformação dos mesmos.
Isso impede que essas DSLs modelem, por exemplo, algoritmos
repeat-until-success e outros algoritmos com ramificação não trivial.
Esta limitação pode ser parcialmente mitigada incluindo alguns tipos
de realimentação clássica como elementos do circuito, como é feito
em alto nível pelo LIQUi|> ou ProjectQ e em baixo nível pelo
OpenQASM 2.0. Incluir feedback clássico diretamente nas
representações de circuitos é impraticável para a interação de
algoritmos clássicos robustos com processamento quântico, limitando
a utilidade para caracterização adaptativa ou para computações
híbridas quânticas-clássicas. (SVORE, GELLER, et al., 2018, p. 2,
tradução nossa)
1
Do original: circuit definition languages.
7
Para atender a necessidade de expressar de forma clara e completa os
algoritmos quânticos, foi que os pesquisadores da Microsoft®
Research criaram essa
linguagem especial e completamente nova.
Q# fornece um sistema de tipos, um ambiente rigidamente restrito
para intercalar com segurança computações clássicas e quânticas,
sintaxe especializada, manipulação de código simbólico para gerar
automaticamente transformações corretas de operações quânticas e
poderosas construções funcionais que auxiliam na composição.
(SVORE, GELLER, et al., 2018, p. 1, tradução nossa)
Este trabalho visa trazer benefícios na criação e na manipulação de
algoritmos quânticos de forma facilitada através da apresentação desta nova
linguagem de programação. Alunos de Engenharia de Software e cursos similares os
quais desejam se aprofundar na pesquisa com algoritmos e estruturas de dados,
análise de algoritmos e afins, poderão abstrair a criação e manipulação de códigos
de baixo nível e acelerar o desenvolvimento de algoritmos nos estudos da
computação quântica.
4. Desenvolvimento
1. Um breve histórico
Desde que os primeiros computadores surgiram entre 1940 e 1950, muitas
coisas mudaram mas a computação tem seguido o mesmo modelo computacional
mesmo após diversos avanços. Computadores pessoais e comerciais processam
informações computacionais através de microprocessadores baseados em
transistores variando entre 0 e 1 até os dias de hoje. A representação das
informações nos computadores clássicos é uma abstração de um conjunto de bits.
Um bit é a menor unidade endereçável de um computador. Hoje em dia, um
programador não precisa se preocupar em como tratar um conjunto de bits para
transmitir, armazenar e/ou representar informações. Pois isso está abstraído dele em
uma linguagem de programação de alto nível para que ele se preocupe apenas com
a lógica da aplicação, enquanto que o sistema operacional fica encarregado de
8
representar as informações e cuidar de muitas outras preocupações de forma
automatizada.
No decorrer dos anos muitas abstrações foram sendo implementadas a fim de
diminuir as responsabilidades técnicas que dizem respeito à mecânica clássica da
computação tradicional. E ainda hoje muitas outras abstrações estão sendo
implementadas até mesmo como melhoria a medida que novos dispositivos de
hardware são reinventados e são capazes de processar as informações de forma
otimizada como o exemplo dos processadores e dos tipos de memória.
A computação quântica já é um tópico de pesquisa há mais de 100 anos,
desde que Max Planck lançou sua Hipótese Quântica em 1900 (PHYSICS: THE
QUANTUM HYPOTHESIS, 2018) e muitos outros estudiosos demonstraram
interesse pelo assunto. Até o Albert Einstein usou a teoria quântica para explicar
várias hipóteses. Hoje em dia, como resultado de tantos anos de pesquisa, nós
temos a promessa de que computação quântica pode trazer melhorias drásticas na
resolução de problemas específicos.
4.2 A promessa da computação quântica
Para entender o real potencial da computação quântica na promessa da
transformação digital, vamos nos utilizar de um comparativo com a computação
tradicional que — embora sejam modelos distintos de computação — pode nos
ajudar a ter uma boa percepção pelas diferenças.
Suponhamos que exista um algoritmo com 2^60 possibilidades de entrada e
suponhamos também que seria necessário 1 nanosegundo para executar cada uma
delas em um supercomputador — algo absurdamente otimista! O tempo total
necessário para percorrer todas as entradas possíveis seria de 36,5 anos. É claro
que seria muito melhor simplesmente executar a entrada com a qual você se importa
e obter a resposta em um instante, em vez de esperar metade da vida para
processar cada uma delas é selecionar apenas uma a partir de uma lista. Essa
diferença fica mais clara se não considerarmos o nanosegundo otimista.
9
4.3 Superposição
Um dos princípios mais fundamentais da mecânica quântica e, portanto da
computação quântica, é o princípio da superposição.
Como o estado quântico é especificado por momento, energia, momento
angular ou spin e há uma incerteza na determinação de seu valor, isso implica que
uma partícula pode ocupar muitos estados quânticos (com probabilidade diferente).
Isso é chamado de superposição.
Por exemplo, os elétrons possuem um recurso quântico chamado spin, um
tipo de momento angular intrínseco. Na presença de um campo magnético, o elétron
pode existir em dois possíveis estados de spin, geralmente chamados spin up e spin
down. Cada elétron, até ser medido, terá uma chance finita de estar em qualquer
estado. Apenas quando medido é observado estar em um estado de spin específico.
Na experiência comum, uma moeda voltada para cima tem um valor definido: é cara
ou coroa. Mesmo se você não tenha olhado para a moeda você já sabe que ela deve
ser cara ou coroa. Na experiência quântica, a situação é mais inquietante: as
propriedades materiais das coisas não existem até serem medidas. Até que você
“olhe” (meça a propriedade particular) na moeda, por assim dizer, ela não é nem
cara nem coroa.
A Figura 1 ilustra a fórmula de um estado de superposição de um qubit que
quando medido pode resultar em 0 cinquenta por cento das vezes, e resultar em 1
também cinquenta por cento das vezes.
Figura 1. Superposição. (NIELSEN, M. A.; CHUANG I. L, 2010)
Apenas quando o estado da partícula é medido é que se estabelece um
estado definido. Mas assim que paramos de monitorar seu comportamento, a
partícula se dissolve novamente retornando ao seu estado de superposição.
O princípio da superposição afirma que dois ou mais estados quânticos
válidos podem ser adicionados, ou sobrepostos, para criar um novo estado quântico
10
válido não importa quão contraintuitivo isso possa parecer para nós. Por outro lado,
todo estado quântico pode ser representado como dois ou mais estados quânticos
distintos também. Além disso, objetos quânticos — que são frequentemente elétrons
ou átomos — podem estar em mais de um estado quântico ao mesmo tempo. Sim,
ao mesmo tempo! Podem ter dois estados diferentes, tanto na aparência, quanto na
velocidade e na localização.
Se você pensar em partículas quânticas como ondas, essas ondas estarão
em todos os estados possíveis ao mesmo tempo, em vez de estarem em um estado
ou outro. É como se as ondas estivessem se sobrepondo e, ao mesmo tempo, não.
Por mais estranho que seja, uma partícula pode estar em dois lugares ao mesmo
tempo, assim que você a observa (mede) ela entrará em colapso, seu estado final.
Isso significa que, assim que você fizer uma medição, todas as partículas quânticas
serão paralisadas em um único estado.
4.4 Entrelaçamento (Entanglement)
Entrelaçamento (ou emaranhamento) quântico é um fenômeno físico que
ocorre quando pares ou grupos de partículas são gerados, interagem ou
compartilham a proximidade espacial de maneiras que o estado quântico de cada
partícula não pode ser descrito independentemente do estado das outras, mesmo
quando as partículas são separadas por uma grande distância.
Entrelaçamento quântico: é uma forma específica de superposição
entre sistemas físicos distintos e diz respeito à correlação mais
profunda que clássica do estado do sistema (como posição,
momento, polarização e spin) de objetos muitas vezes separados
amplamente no espaço e/ou tempo. Assim, a medição de um objeto
definirá outro, mesmo que nenhuma informação tenha sido trocada.
(MICHAEL J. C. H. et al, 2017, p.3, tradução nossa)
Medidas de propriedades físicas, como posição, momento, spin e polarização,
realizadas em partículas emaranhadas, são correlacionadas. Por exemplo, se um
par de partículas for gerado de tal forma que seu spin total seja conhecido como
zero, e se uma partícula tiver rotação no sentido horário em um determinado eixo, o
11
spin da outra partícula, medido no mesmo eixo, será encontrado no sentido anti-
horário, como é de se esperar devido ao seu emaranhamento.
Tais fenômenos foram o tema de um artigo de 1935 de Albert Einstein, Boris
Podolsky e Nathan Rosen (EINSTEIN, A. et al, 1935), e vários trabalhos de Erwin
Schrödinger logo depois, descrevendo o que veio a ser conhecido como o Paradoxo
EPR. Einstein e outros consideraram tal comportamento impossível, uma vez que
violava a visão de causalidade do realismo local. Einstein referindo-se a ele como
"ação assustadora à distância" (BELLS, J. S., p. 143, 1987, tradução nossa). E
argumentava que a formulação aceita da mecânica quântica deveria ser incompleta.
Mais tarde, no entanto, as previsões contraintuitivas da mecânica quântica
foram verificadas experimentalmente em testes onde a polarização ou spin de
partículas emaranhadas foram medidas em locais separados. Em testes anteriores,
não poderia ser absolutamente descartável que o resultado do teste em um ponto
pudesse ter sido sutilmente transmitido ao ponto remoto, afetando o resultado no
segundo local. No entanto, os chamados "testes livres de fendas" foram realizados
nos quais os locais foram separados de forma que as comunicações na velocidade
da luz levariam mais tempo — em um caso, 10.000 vezes mais tempo — do que o
intervalo entre as medidas (Yin, J. et al, 2013).
4.5 Linguagens de programação
Existem várias linguagens de programação quânticas hoje em dia. A maioria
delas são incorporadas/embutidas em linguagens existentes permitindo a rápida
adoção por programadores de diferentes gostos/estilos. Isso é como ver um filme em
outra língua legendado para a sua língua nativa.
O Quipper é uma linguagem de programação quântica funcional e
fortemente tipada, incorporada em Haskell; O ScaffCC/Scaffold está
embutido em C/C++, aproveitando a infraestrutura da LLVM; QWire é
incorporado no sistema de prova Coq; LIQUi|> é incorporado em F#;
e ProjectQ e Quil estão embutidos no Python. (SVORE, GELLER, et
al., 2018, p.1-2, tradução nossa)
12
Várias linguagens de programação quântica têm sido propostas nos últimos
anos, algumas no estilo imperativo outras no estilo funcional, umas de baixo nível
outras de alto nível.
As abstrações e os principais recursos, no entanto, concentram-se na
criação e manipulação de circuitos quânticos. Enquanto várias
linguagens como Quipper, LIQUi|> e ProjectQ, suportam funções de
alto nível, elas são implementadas como transformações de circuitos:
funções que recebem circuito(s) de entrada e produzem circuito(s) de
saída. (SVORE, GELLER, et al., 2018, p. 2, tradução nossa)
Porém, apesar de existir uma vasta quantidade de opções de linguagens de
programação quânticas, a maioria delas é normalmente orientada na criação e/ou
manipulação de circuito(s) quântico(s). Isso acontece até mesmo com as linguagens
que suportam funções de alto nível.
4.6 Modelo quântico de computação
A arquitetura de hardware de um computador quântico é completamente
diferente dos computadores clássicos que já temos por muitos anos. Informações
quânticas são armazenadas em estados quânticos da matéria e não em lógica
booleana, a qual está limitada a apenas duas possibilidades. A computação quântica
é efetuada por operações baseadas em interferência quântica e os estados
quânticos são armazenados no que é conhecido como qubit.
Um modelo natural para computação quântica é tratar o computador
quântico como um co-processador, semelhante a GPUs, FPGAs e
outros processadores adjuntos. A lógica de controle primária executa
o código clássico em um computador host clássico. Quando
apropriado e necessário, o programa host pode invocar um sub-
programa executado no processador quântico adjunto. Quando o
sub-programa termina, o programa host obtém acesso aos resultados
do sub-programa. (SVORE, GELLER, et al., 2018, p. 3, tradução
nossa)
Na Figura 2 é possível ter uma idéia visual da arquitetura de computação
quântica e fazer uma comparação com a arquitetura de computação clássica. Note
13
que na computação quântica, é possível processar diversos resultados
simultaneamente.
Figura 2. Programa quântico comparado com o clássico. (MATTHEW, 2005)
O poder de paralelismo do modelo de computação quântico é absurdamente
maior em comparação com o modelo tradicional. Porém o grande desafio agora é
poder extrair o resultado correto antes que ocorra uma medição, o que anula as
propriedades atômicas de processamento. Ainda não é possível ter acesso ao que
está sendo processado dentro do contexto de uma computação no modelo quântico
a fim de extrair resultados. Um programa Q# não tem capacidade de introspecção no
estado de um qubit e, portanto, é totalmente agnóstico sobre o que um estado
quântico é ou sobre como é realizado. Tudo o que se tem hoje são estatísticas
probabilísticas de resultados que podem não ser muito práticas conforme o número
de possibilidades de resultados aumenta e se mostra exponencial.
4.8 Debugando e testando um programa em Q#
Debugar programas quânticos pode ser uma tarefa desafiadora
principalmente no contexto do modelo de computação quântica o qual funciona
apenas como um adjunto nos dias atuais, mas na concepção do Q# foram previstos
14
alguns recursos que podem auxiliar nessa difícil tarefa. Diferentemente de outras
linguagens de programação do gênero, o Q# fornece abstração em alto nível para os
desenvolvedores porém sem os limitar ao acesso a correções de erro e outros
detalhes de baixo nível que são importantes em algumas situações mais específicas.
Uma função que retorne uma tupla vazia pode ser ignorada por um programa host
sem nenhuma preocupação adicional por exemplo.
Ou seja, uma máquina de destino pode optar por não executar
nenhuma função que retorne ()} com a garantia de que essa omissão
não modificará o comportamento de qualquer código Q# seguinte.
Essa consequência torna as funções uma ferramenta útil para
incorporar a lógica de depuração e teste. (SVORE, GELLER, et al.,
2018, p. 10, tradução nossa)
O exemplo de código abaixo em Q# exibe uma função usada para representar
efeitos colaterais de diagnóstico. Trata-se de uma função que recebe um valor do
tipo Double o qual não deve ser menor ou igual a zero. Caso contrário, será enviada
uma mensagem de falha formatada como uma string para o programa host.
Figura 3. Assert Positive. (SVORE, GELLER, et al., 2018)
Podemos notar a semelhança com o C# na estrutura do código apresentado,
mas vale ressaltar que o Q# é uma linguagem completamente nova e não está
embutida em nenhuma linguagem como as outras linguagens de programação
quântica estão.
4.9 Configurando o ambiente de desenvolvimento
Você também pode começar a trabalhar com computação quântica a partir do
seu computador pessoal. O Quantum Development Kit pode ser usado com o Visual
Studio 2017 ou com linha de comando e um editor de códigos como o Visual Studio
Code. Também é possível usar o QDK a partir da linha de comando diretamente se
você preferir.
15
Para mais informações basta acessar este link com instruções em inglês:
https://docs.microsoft.com/en-us/quantum/install-guide/?view=qsharp-preview
Após instalar a IDE (Do acrônimo em inglês: Integrated Development
Environment) Visual Studio 2017 ou superior caso você ainda não o tenha feito,
basta baixar e instalar o Microsoft®
Quantum Development Kit:
https://marketplace.visualstudio.com/items?itemName=quantum.DevKit
Com o Visual Studio 2017 instalado e também o QDK, agora é hora de validar
a instalação do QDK. Para isso, nós vamos criar a nossa primeira aplicação quântica
Hello World apenas para verificar se o nosso ambiente Q# foi corretamente instalado
e configurado.
● Abra o Visual Studio 2017;
● Acesse o menu File e clique em New > Project...;
● No navegador de modelos de projetos, abaixo de Installed > Visual C#,
selecione o modelo Q# Application;
● Certifique-se de ter selecionado o .NET Framework 4.6.1 na lista na parte
inferior da caixa de diálogo New Project;
16
Figura 4. Criando um novo projeto no Visual Studio 2017. (Fonte: O autor)
Após a criação do projeto, o Visual Studio 2017 irá atualizar as dependências
automaticamente. Antes de continuar, abra o arquivo Driver.cs e adicione a linha de
código conforme destacado na imagem abaixo:
Figura 5. Adicionando um comando de pausa para o console. (Fonte: O autor)
17
Agora basta pressionar F5 e o seu programa será compilado e executado.
Parabéns, você acaba de criar o seu primeiro programa em Q#!
O Q# lembra muito linguagens já consagradas como C# e Java no estilo de
escrita de códigos, no uso de chaves para agrupamento de instruções, ponto-e-
vírgula para finalizar instruções bem como barra dupla para comentários. Além
disso, o Q# também nos permite trabalhar com namespaces de forma similar ao
acontece no C# em muitos casos.
No Q# é comum a utilização de operações. Operação é uma unidade básica
que em essência, diz respeito a uma “função” que tem o poder de afetar o estado do
dispositivo quântico e pode misturar computação clássica e quântica.
O estilo de programação em Q# se assemelha ao estilo de programação
funcional muitas vezes. Por padrão, as variáveis são imutáveis e o compilador faz
interferência de tipos para as variáveis locais. Mas também há suporte para
mutabilidade e o estilo imperativo de desenvolvimento desde que isso seja feito no
mesmo escopo onde uma variável foi definida, pois não existem tipos de referência
em Q#. Além do mais, operações e funções podem ser retornadas para outras
funções ou podem ser usadas como argumento para outras operações.
Funções em Q# são como operações, a não ser pelo fato de que as funções
só podem realizar computação clássica. Elas não são capazes de chamar nenhuma
operação que venha a afetar o estado quântico de um qubit, nem ter variantes. Ou
seja, podemos garantir que uma função sempre retorna o mesmo resultado a partir
da mesma entrada de dados. Sendo assim, um programa host clássico normalmente
começa com uma chamada a uma operação em Q#. (SVORE, GELLER, et al., 2018,
tradução nossa)
4.9.1 Tipos Primitivos Clássicos
Q# possui os tipos de dados clássicos por padrão como Int, Double, Boolean
e String. Os tipos Int, Double e Boolean suportam os operadores comuns de
aritmética em numéricos e operações lógicas para Booleanos.
Q# possui suporte para operações bitwise em inteiros o que significa que as
informações podem ser computadas bit a bit, que menor unidade de dados de um
18
computador. Muitas outras linguagens de programação armazenam dados e
executam instruções em grupos de bits múltiplos de tamanhos 4, 8, 16 ou 32 bits.
O tipo string em Q# é usado apenas para informações de diagnóstico e,
portanto, apenas funcionalidade mínima de manipulação de strings é oferecida
reforçando o fato de que o Q# é projetado para execução em um processador
quântico adjuntivo.
No exemplo abaixo, as informações de depuração são passadas de volta para
um programa host utilizando interpolação de strings como no C#, porém este trecho
de código apresentado está em Q#. (SVORE, GELLER, et al., 2018, tradução nossa)
Ex.:
Figura 6. Interpolação de strings com Q#. (Fonte: O autor)
Q# também tem um tipo Range que é basicamente uma sequência aritmética
de inteiros e funciona de forma similar ao que podemos ver em linguagens como F#
e também no C# a partir da versão 8.
Por exemplo, o Range 1..4 é o mesmo que 1, 2, 3, 4. E como o Range é um
primitivo, eles podem ser passados como parâmetros, como valores de funções ou
até como retorno de operação. (SVORE, GELLER, et al., 2018, tradução nossa)
4.9.2 Tipos Primitivos Quânticos
Devemos observar que o Q# é uma linguagem fortemente tipada, de modo
que o uso cuidadoso desses tipos pode ajudar o compilador a fornecer fortes
garantias sobre os programas Q# em tempo de compilação.
Q# fornece tipos primitivos clássicos e quânticos que podem ser usados
diretamente e uma variedade de maneiras de produzir novos tipos de outros tipos.
Os tipos Pauli, Result e Qubit por exemplo são tipos usados exclusivamente
em computação quântica. Ou seja, a utilização desses tipos não faz nenhum sentido
em linguagens puramente clássicas como aquelas que já foram mencionadas
anteriormente.
19
Valores do tipo Pauli especificam um operador Pauli de um qubit único.
Existem variações de Pauli como PauliI, PauliX, PauliY e PauliZ cujos valores são
utilizados para se especificar a base de uma medição.
O tipo Result especifica o resultado de uma medição quântica. Q# espelha a
maioria dos hardwares quânticos fornecendo medições em produtos de operadores
Pauli de um único qubit.
Um Result de Zero indica que o autovalor de +1 foi medido e um
Result de Um indica que o autovalor -1 foi medido. Ou seja, Q#
representa autovalores pela potência para a qual −1 é gerado,
usando +1 = (−1)0
e −1 = (−1)1
. Essa convenção é mais comum na
comunidade de algoritmos quânticos, pois mapeia mais de perto os
bits clássicos. (SVORE, GELLER, et al., 2018, p. 6, tradução nossa)
Existe também o tipo Unit que é o tipo que permite apenas um valor (). Este
tipo é usado para indicar que uma função ou operação em Q# não retorna nenhuma
informação. As constantes Pauli, PauliX, PauliY, PauliZ, One e Zero são todos
símbolos reservados em Q#.
4.9.3 Qubits
Q# considera os qubits como itens obscuros que podem ser passados para
funções e operações com a restrição de que eles só podem ser usados em
operações primitivas embutidas. De qualquer forma, um estado quântico não pode
ser representado por nenhum tipo ou construção. Ao invés disso, assim como os bits
em computadores clássicos, os qubits representam a menor unidade física
endereçável de um computador quântico. E como um qubit é um item de vida longa,
então o Q# não precisa de tipos lineares.
Vale lembrar que estado não é referenciado de forma explícita no Q#, mas é
feita uma descrição da transformação do estado. Assim como são acumuladas as
transformações de cada vértice nos programas de computação gráfica, um programa
em Q# acumula transformações em estados quânticos que são representados de
forma totalmente obscura para um dispositivo de destino. (SVORE, GELLER, et al.,
2018, tradução nossa)
20
É possível que um programa quântico permita-nos fazer medições e até
modificar o estado de um qubit, mas não é possível saber o que é um estado
quântico ou sobre como ele é realizado. Ao invés disso, é possível que um programa
em Q# possa chamar operações que são capazes de aprender informações de um
quibit e também operações que podem atuar no estado de um quibit embora que
estas operações não tenham nenhuma definição dentro da linguagem em si mesma
até que o programa host execute tal programa em Q#.
Um programa em Q# pode combinar tais operações conforme definição a
partir de uma máquina host de destino, para criar novas operações de alto nível a
fim de expressar a computação quântica de uma solução completa. Essa
flexibilidade oferecida pelo Q# torna mais fácil a expressão de lógica subjacente
favorecendo a criação de algoritmos híbridos clássico-quânticos.
Essas funções não podem modificar o estado dos qubits transmitidos,
pois aos argumentos de entrada aplica-se então a restrição de que as
funções só podem chamar outras funções e não podem chamar
operações. (SVORE, GELLER, et al., 2018, p. 6, tradução nossa)
Na computação clássica, não existe diferença essencial entre um método e
uma função. Mas na computação quântica com Q#, é importante saber a diferença
que há entre funções e operações. E isso é o que será explorado com mais detalhes
no próximo tópico.
4.9.4 Operações e funções
O Q# oferece suporte para dois tipos de chamadas, são elas as operações e
as funções. As operações são capazes de afetar o estado quântico, já as funções
garantem que isso não aconteça, além de sempre retornar o mesmo resultado a
partir da mesma entrada de dados. Uma função pode ser encarregada de executar
uma computação clássica como parte de um requisito de execução de um algoritmo
quântico por exemplo.
Tanto operações como funções trabalham com tuplas — uma tupla
representa objeto composto. Elas recebem uma tupla como argumento de entrada e
21
produzem uma tupla como resultado da computação. Mesmo quando não nenhum
resultado computado como saída, elas retornam uma tupla vazia.
Por causa da equivalência de uma única instância de uma tupla singleton,
operações e funções que retornam uma tupla singleton podem ser tratadas como se
estivessem retornando um valor único, desembrulhado.
Operações e funções são tipos de primeira classe em Q# e por isso elas
podem ser passadas como argumentos para outras operações e/ou funções, e ainda
serem retornadas como resultados de uma operação ou função criando uma
composição, demonstrando com isso entre outras coisas que o Q# tem seu sabor de
programação funcional. Operações e funções podem ser incluídas em tuplas e é
possível se ter matrizes de operações e funções. (SVORE, GELLER, et al., 2018,
tradução nossa)
4.9.5 Aprendendo mais sobre o Q#
Existe um projeto de código aberto chamado Microsoft®
Quantum Katas
(https://github.com/Microsoft/QuantumKatas) no qual há uma série de exercícios de
programação que oferecem feedback imediato a medida em que se avança nas
tarefas propostas para que se possa aprender o Q# em um ritmo mais adequado.
Cada uma dessas tarefas, espera que você preencha um pequeno trecho de código
que aumenta de dificuldade gradativamente. Existem comentários explicativos nos
arquivos de código e um framework de testes valida o código digitado nas soluções.
Para mais informações sobre como utilizar esse excelente recurso de
aprendizagem dessa nova linguagem de programação, é recomendado assistir ao
vídeo da segunda sessão deste evento Microsoft®
Ignite 2018 apresentado na língua
inglesa pela Bettina Heim:
https://cloudblogs.microsoft.com/quantum/2018/10/11/presenting-the-potential
-of-quantum-computing-at-microsoft-ignite-2018/
5. Considerações Finais
Foi apresentada uma revisão bibliográfica do Q#, uma nova linguagem de
programação quântica da Microsoft®
a fim de fornecer maior flexibilidade de
22
abstração de circuitos quânticos visando a melhoria de performance na criação de
algoritmos para computação quântica. Com essa nova linguagem desenvolvedores
de software agora dispõem de mais flexibilidade na representação de circuitos
quânticos podendo corrigir erros, tratar temporizações e ruídos de forma explícita. E
além disso, ainda poderão escrever algoritmos mais precisos e eficientes sem se
preocupar com detalhes de baixo nível utilizando uma linguagem de alto nível. Com
essa linguagem fica mais fácil trabalhar com recursão e iteração por exemplo. Algo
que abre um novo leque de possibilidade na escrita e na elaboração de algoritmos
mantendo sempre uma separação clara entre o código computacional quântico e
clássico. Vale ressaltar também que existem uma série de ferramentas dentro da
IDE do Visual Studio como o framework de testes de unidade por exemplo que
auxiliam e potencializam os recursos oferecidos pela linguagem em si, o que
aumenta muito a produtividade.
Também foram apresentadas formas de simular a execução de algoritmos
quânticos em um computador de desenvolvimento local, de baixo custo, visando
aumentar a produtividade das pesquisas em computação quântica.
E analisando os resultados obtidos, é possível concluir que essa nova
linguagem de programação coloca os estudos e pesquisas na criação de algoritmos
quânticos em uma certa vantagem em relação às outras linguagens já existentes em
alguns aspectos. Outro fato importante para o avanço e desenvolvimento desta
linguagem é que a Microsoft®
está abrindo o código fonte do QDK no Github para
que toda a comunidade de desenvolvedores ao redor do mundo possa contribuir
com suas ideias, com suas descobertas e com suas dúvidas. Essa nova linguagem
tem todos os recursos necessários para continuar crescendo junto com a evolução
nos estudos da computação quântica em geral sem ficar limitada a detalhes de baixo
nível necessários para uma melhor expressividade na elaboração de algoritmos
clássico-quânticos. Os próximos passos serão a descoberta de novos algoritmos ou
ainda a melhoria/refatoração dos algoritmos existentes para a solução de problemas
antes impossíveis para o modelo de computação clássico, pois nós já temos todas
as ferramentas que precisamos.
23
REFERÊNCIAS
AARONSON, Scott. Quantum computing since Democritus. New York, NY, USA:
Cambridge University Press, 2013.
BELL, J. S. Speakable and unspeakable in quantum mechanics. New York, NY,
USA: Cambridge University Press, 1987.
CALUDE, C. S.; CALUDE, E. The Road to Quantum Computational Supremacy.
arXiv: 1712.01356v1 [quant-ph], 2017. Disponível em:
<https://arxiv.org/pdf/1712.01356.pdf>. Acesso em: 5 ago. 2018.
EINSTEIN, A. et al. Can Quantum-Mechanical Description of Physical Reality be
Considered Complete? American Physical Society, 1935. Disponível em:
<http://cds.cern.ch/record/1060284/files/PhysRev.48.696.pdf>. Acesso em: 1 jul.
2019.
MATTHEW, D. P. A Practical Quantum Computer Programming Framework.
arXiv:0911.2423v1 [cs.PL], 2005. Disponível em:
<https://arxiv.org/ftp/arxiv/papers/0911/0911.2423.pdf>. Acesso em: 6 out. 2018.
MICHAEL J. C. H. et al. The challenges for Systems Engineers of non-classical
quantum technologies. arXiv:1710.05643v2 [quant-ph], 2017. Disponível em:
<https://arxiv.org/pdf/1710.05643.pdf>. Acesso em: 2 ago. 2018.
NIELSEN, M. A.; CHUANG I. L. Quantum Computation and Quantum
Information. New York, NY, USA: Cambridge University Press, 2010.
PAETZNICK, A.; SVORE, K. M. Repeat-Until-Success: Non-deterministic
decomposition of single-qubit unitaries. arXiv: 1311.1074v2 [quant-ph], 2014.
Disponível em: <https://arxiv.org/pdf/1311.1074.pdf>. Acesso em: 5 ago. 2018.
PHYSICS: THE QUANTUM HYPOTHESIS. In: Encyclopedia.com, 2016. Disponível
em:
<https://www.encyclopedia.com/science/science-magazines/physics-quantum-hypoth
esis>. Acesso em: 2 ago. 2018.
REBELO, M. N. Desenvolvimento de um Protótipo de um Gerador de Analisador
Léxico, 2002. Disponível em:
<http://dsc.inf.furb.br/arquivos/tccs/monografias/2002-2michelnogueirarebelovf.pdf>.
Acesso em: 5 ago. 2018.
SANTOS, A. C. O Computador Quântico da IBM e o IBM Quantum. Revista
Brasileira de Ensino de Física, Niterói, 1 Setembro 2016. Disponível em:
<http://www.scielo.br/pdf/rbef/v39n1/1806-1117-rbef-39-01-e1301.pdf>. Acesso em:
5 ago. 2018.
24
SVORE, K. M. et al. Q#: Enabling scalable quantum computing and development
with a high-level domain-specific language. arXiv: 1803.00652v1 [quant-ph], 2018.
Disponível em: <https://arxiv.org/pdf/1803.00652v1.pdf>. Acesso em: 4 ago. 2018.
Yin, J. et al. Bounding the speed of ‘spooky action at a distance’. arXiv: 1303.0614v2
[quant-ph], 2013. Disponível em: <https://arxiv.org/pdf/1303.0614v2.pdf>. Acesso
em: 1 jul. 2019.

Mais conteúdo relacionado

Mais procurados

Programação concorrente
Programação concorrenteProgramação concorrente
Programação concorrenteFabio Duarte
 
Programação 1
Programação 1Programação 1
Programação 1essa
 
Linguagens de programação 03-12-09
Linguagens de programação   03-12-09Linguagens de programação   03-12-09
Linguagens de programação 03-12-09essa
 
Introdução ao paradigma imperativo
Introdução ao paradigma imperativoIntrodução ao paradigma imperativo
Introdução ao paradigma imperativoTony Alexander Hild
 
Linguagens de Programação
Linguagens de ProgramaçãoLinguagens de Programação
Linguagens de Programação12anogolega
 
Linguagens de Programação
Linguagens de ProgramaçãoLinguagens de Programação
Linguagens de ProgramaçãoBeDMK
 
"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre...
"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre..."Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre...
"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre...lccausp
 

Mais procurados (7)

Programação concorrente
Programação concorrenteProgramação concorrente
Programação concorrente
 
Programação 1
Programação 1Programação 1
Programação 1
 
Linguagens de programação 03-12-09
Linguagens de programação   03-12-09Linguagens de programação   03-12-09
Linguagens de programação 03-12-09
 
Introdução ao paradigma imperativo
Introdução ao paradigma imperativoIntrodução ao paradigma imperativo
Introdução ao paradigma imperativo
 
Linguagens de Programação
Linguagens de ProgramaçãoLinguagens de Programação
Linguagens de Programação
 
Linguagens de Programação
Linguagens de ProgramaçãoLinguagens de Programação
Linguagens de Programação
 
"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre...
"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre..."Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre...
"Aula sobre Paralelização Automática". Rogério A. Gonçalves e Prof. Dr. Alfre...
 

Semelhante a Introdução à Q# para Computação Quântica

Linguagem c wellington telles - aula 01
Linguagem c   wellington telles - aula 01Linguagem c   wellington telles - aula 01
Linguagem c wellington telles - aula 01profwtelles
 
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”Kratos879
 
Palestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas EmbarcadosPalestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas EmbarcadosPET Computação
 
Plataformas cisc e risc
Plataformas cisc e riscPlataformas cisc e risc
Plataformas cisc e riscTiago
 
Research Group on High Performance Computing - MDCC/UFC - Fortaleza, Brazil
Research Group on High Performance Computing - MDCC/UFC - Fortaleza, BrazilResearch Group on High Performance Computing - MDCC/UFC - Fortaleza, Brazil
Research Group on High Performance Computing - MDCC/UFC - Fortaleza, BrazilHeron Carvalho
 
Livro -estruturas_de_dados_e_algoritmos_em_c.erivanildo
Livro  -estruturas_de_dados_e_algoritmos_em_c.erivanildoLivro  -estruturas_de_dados_e_algoritmos_em_c.erivanildo
Livro -estruturas_de_dados_e_algoritmos_em_c.erivanildoFernando Chuva
 

Semelhante a Introdução à Q# para Computação Quântica (20)

Linguagem c wellington telles - aula 01
Linguagem c   wellington telles - aula 01Linguagem c   wellington telles - aula 01
Linguagem c wellington telles - aula 01
 
Apostila SO
Apostila SOApostila SO
Apostila SO
 
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
Apostila C++ Básico - UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO”
 
Apostila c++ básico
Apostila c++ básicoApostila c++ básico
Apostila c++ básico
 
Apostila c++ básico (1)
Apostila c++ básico (1)Apostila c++ básico (1)
Apostila c++ básico (1)
 
Apostila chardwere
Apostila chardwereApostila chardwere
Apostila chardwere
 
C hardware
C hardwareC hardware
C hardware
 
Palestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas EmbarcadosPalestra PET.Com - Sistemas Embarcados
Palestra PET.Com - Sistemas Embarcados
 
Apostila de devc++ novo
Apostila de devc++ novoApostila de devc++ novo
Apostila de devc++ novo
 
Apostila de dev
Apostila de devApostila de dev
Apostila de dev
 
apostila de dev.pdf
apostila de dev.pdfapostila de dev.pdf
apostila de dev.pdf
 
Apostila de dev
Apostila de devApostila de dev
Apostila de dev
 
Apostila de dev
Apostila de devApostila de dev
Apostila de dev
 
Apostila de dev
Apostila de devApostila de dev
Apostila de dev
 
Plataformas cisc e risc
Plataformas cisc e riscPlataformas cisc e risc
Plataformas cisc e risc
 
Artigo jaquiel-paim-final
Artigo jaquiel-paim-finalArtigo jaquiel-paim-final
Artigo jaquiel-paim-final
 
Research Group on High Performance Computing - MDCC/UFC - Fortaleza, Brazil
Research Group on High Performance Computing - MDCC/UFC - Fortaleza, BrazilResearch Group on High Performance Computing - MDCC/UFC - Fortaleza, Brazil
Research Group on High Performance Computing - MDCC/UFC - Fortaleza, Brazil
 
AC nova-aula 1.pptx
AC nova-aula 1.pptxAC nova-aula 1.pptx
AC nova-aula 1.pptx
 
Livro -estruturas_de_dados_e_algoritmos_em_c.erivanildo
Livro  -estruturas_de_dados_e_algoritmos_em_c.erivanildoLivro  -estruturas_de_dados_e_algoritmos_em_c.erivanildo
Livro -estruturas_de_dados_e_algoritmos_em_c.erivanildo
 
LP002 - AULA 1.potx
LP002 - AULA 1.potxLP002 - AULA 1.potx
LP002 - AULA 1.potx
 

Introdução à Q# para Computação Quântica

  • 1. CELSO DE SOUZA JÚNIOR UMA INTRODUÇÃO À COMPUTAÇÃO QUÂNTICA COM Q# RIO DE JANEIRO Maio/2019 Resumo Computação quântica não é um assunto novo. Já existem estudos sobre essa disciplina a mais de cem anos. Até o próprio Albert Einstein usou a computação quântica em suas pesquisas e estudos. Hoje em dia existem algumas soluções sendo exploradas nas áreas de finanças, logística, saúde, entre outras. Como o hardware tem barateado bastante ultimamente, criou-se uma nova especulação acerca deste assunto. Pesquisadores dos dias atuais acreditam que talvez seja finalmente a hora da computação quântica ajudar a desenvolver a sociedade em que vivemos. Mas para isso, nós precisaremos de novos e avançados dispositivos de hardware bem como de softwares mais robustos e inteligentes. Para ajudar nessa revolução, têm surgido uma quantidade considerável de linguagens de programação quânticas nos últimos tempos, a maioria delas está embutida em alguma outra linguagem conhecida e é orientada a circuitos. Ou seja, elas recebem um circuito como entrada em produzem um circuito como saída. Sendo que alguns algoritmos quânticos podem empregar padrões que não podem ser expressados em circuitos. Programadores precisam que preocupações de baixo nível sejam abstraídas para que eles possam focar apenas na criação de algoritmos em uma linguagem de alto nível, aumentando a sua produtividade sem que eles estejam limitados a circuitos. Para resolver essa limitação imposta aos algoritmos pensados nas outras linguagens de computação quântica existentes e outros problemas de produtividade, basta adotar uma linguagem de programação nova, não orientada a circuitos que foi criada especialmente para a computação quântica. E neste trabalho, será apresentada essa nova linguagem e como é possível começar a trabalhar com ela visando um aumento de produtividade e o avanço nas pesquisas. Palavras-Chave: COMPUTAÇÃO QUÂNTICA; QSHARP; Q#;
  • 2. 2 1. Introdução A computação clássica e a computação quântica são dois paradigmas de computação diferentes. O modelo de computação utilizado hoje em dia na grande maioria dos dispositivos é denominado computação clássica. As informações são representadas por bits por meio de um sistema binário que opera basicamente entre dois estados 0 ou 1. O bit é a menor unidade endereçável em um dispositivo de computação clássica e pode representar, transmitir e/ou armazenar informações. Tudo o que é exibido na tela do computador, tudo o que é processado, toda entrada ou saída, seja texto, seja uma imagem, seja um arquivo, tudo é representado por uma abstração de um conjunto de bits. Desde os primórdios da computação por volta dos anos de 1945, onde começaram a surgir os primeiros computadores e as primeiras linguagens de programação, as coisas evoluíram numa velocidade inimaginável. Computadores que pesavam até uma tonelada e não cabiam numa única sala, hoje em dia cabem na palma da mão e são dez vezes mais potentes. Mas apesar dessa evolução absurda, uma coisa permanece a mesma desde sempre: o modelo computacional. A computação quântica não veio para substituir a computação clássica ao contrário do que muitos pensam. Enquanto o modelo clássico de computação se utiliza da lógica booleana para processamento de dados, as informações no modelo de computação quântico são armazenados em estados quânticos da matéria e são processados por meio de operações baseadas em interferência quântica. Assim como os valores binários individuais são armazenados em um bit, os estados quânticos são armazenados em qubits. O processamento de uma computação quântica que opera em um ou mais quibit é chamada de gate. E uma sequência de gates operando um conjunto de qubits é tradicionalmente chamada de circuito. A maioria das linguagens de computação quântica existentes são efetivamente descrições de circuitos. Ou seja, elas recebem um circuito como entrada e produzem um circuito também como saída. Sendo que isso acaba limitando a criação de alguns algoritmos que são muitas vezes impossíveis de serem representados por meio de circuitos devido ao nível de abstração necessário. Desenvolvedoresde
  • 3. 3 software precisam que alguns detalhes operacionais de baixo nível sejam abstraídos em uma linguagem de programação de alto nível, mas sem que eles sejam impedidos de abordar detalhes que exigem tratamento explícito como correções de erros, ruídos e temporizações. E essa é a idéia por trás da criação de uma nova linguagem de programação quântica como expressado na citação a seguir: No entanto, um desenvolvedor de software exige que esses detalhes sejam abstraídos para que o foco seja mantido na expressão de um algoritmo quântico de alto nível. (SVORE, GELLER, et al., 2018, p. 1, tradução nossa) Para atender a necessidade de expressividade e abstração, foi que os pesquisadores da Microsoft® Research em Readmond WA Estados Unidos desenvolveram “uma linguagem especial que fornece uma separação clara entre o código a ser executado no contexto quântico a partir do código do driver que pode ser programado em uma linguagem tradicional de alto nível.” (SVORE, GELLER, et al., 2018, p. 1, tradução nossa). O computador quântico não veio para substituir os computadores clássicos, mas sim para funcionar lado a lado com eles ou até com outros dispositivos. Além disso, uma vez que apenas algumas partes computacionais de um “programa” são de natureza quântica, é conveniente considerar um computador quântico não como um dispositivo de computação completo por si só (repleto de mecanismos para armazenamento, comunicação de rede, interação de usuário e assim por diante), mas sim como um co-processador externo, adjunto, para uma máquina clássica. (SVORE, GELLER, et al., 2018, p. 1, tradução nossa) E o Q# foi projetado para ajudar a abstrair a criação de códigos de baixo nível para que programadores possam manter o foco apenas na criação de algoritmos de alto nível com todo o poder oferecido pela linguagem. A seguir há uma explicação mais detalhada sobre como o Q# pode ajudar nesse processo de abstração através da automatização da geração do adjunto de uma transformação. Sem a computação simbólica, a única maneira de produzir o adjunto de uma transformação é explicitamente escrevê-la como parte do código-base. No entanto, o Q# é capaz de empregar computação simbólica poderosa e type-safe no corpo de uma determinada operação para gerar automaticamente o adjunto, se for logicamente
  • 4. 4 possível fazê-lo. (SVORE, GELLER, et al., 2018, p. 1, tradução nossa) Q# (Leia-se “Q /quiu/ Sharp”) é uma linguagem de programação quântica de alto nível — mais detalhes sobre linguagens de alto e de baixo nível são apresentados por (REBELO, 2002) — que, até a data de elaboração deste trabalho de pesquisa, era a única linguagem autônoma classificada como “linguagem de definição de algoritmo e como tal, representa naturalmente a composição de algoritmos clássicos e quânticos” (SVORE, GELLER, et al., 2018, p. 2, tradução nossa) e não é uma linguagem embutida como as outras DSLs, do acrônimo em inglês domain-specific language (Linguagem específica de domínio). Ela foi desenvolvida com objetivo de atender a necessidade de expressar algoritmos quânticos de forma clara e completa não orientada na criação, manipulação e/ou transformação de circuitos. Não há noção de um circuito em Q#, e há declarações Q#, por exemplo, repeat-until-success, que não podem ser representados como um circuito sem introduzir novas e especializadas portas e são mais facilmente tratados como construções híbridas quânticas- clássicas. Por exemplo, o Q# facilita a expressão de algoritmos de estimação de fase e de química quântica, os quais requerem interações quântico-clássicas ricas. (SVORE, GELLER, et al., 2018, p. 2, tradução nossa) Não serão abordados detalhes sobre algoritmos, no entanto PAETZNICK e SVORE (2014) trazem mais informações sobre o algoritmo repeat-until-success supracitado para aqueles mais interessados. Será abordado como Q# pode ser usada para implementar algoritmos quânticos existentes através de um olhar mais atento em algumas das características da linguagem. 2. Objetivos Este trabalho apresenta uma visão geral da computação quântica sob a perspectiva do Q#, uma linguagem de programação recentemente desenvolvida pelos pesquisadores da Microsoft® Research que é autônoma, de alto nível e
  • 5. 5 específica de domínio, a fim de habilitar a abstração e o desenvolvimento escalonável em favor da construção e análise de algoritmos claros e completos. Será apresentado um breve tutorial de introdução à linguagem através de uma demonstração de como usar os seus principais recursos. 1. Objetivo Geral Servir como um material de referência introdutório à computação quântica através da linguagem de programação Q#, bem como ilustrar a sua utilização básica por meio de exemplos práticos. 2. Objetivos Específicos ● Apresentar uma breve introdução à computação quântica e sua importância na transformação digital; ● Um pouco da história e evolução das linguagens de programação quântica desenvolvidas nos últimos anos; ● Apresentar o modelo de computação quântica e a sua arquitetura híbrida de execução; ● Como configurar um ambiente de desenvolvimento e começar a praticar; ● Apresentar palavras reservadas, tipos de dados primitivos, funções, operações, fluxo de controle, etc; ● Como debugar e testar programas em Q# bem como enviar mensagens de erro para a aplicação hospedeira; 3. Justificativa Já existe serviço de acesso à computação quântica (SANTOS, 2016), mas devido às dificuldades na implementação, os computadores quânticos ainda não estão disponíveis para o público geral apesar de várias empresas estarem trabalhando em projetos de pesquisa neste sentido (CALUDE e CALUDE, 2017). No entanto, os estudos de programação de computadores quânticos continuam
  • 6. 6 avançando por meio de modelos que representam o seu funcionamento, servindo como base para a concepção de linguagens de programação e permitindo a sua execução em computadores clássicos com algumas limitações. A computação quântica explora fenômenos quânticos que seriam impossíveis de serem reproduzidos na computação tradicional devido a sua natureza. Soluções que levariam centenas de anos para processar nos computadores de hoje poderiam ser processadas em segundos. Para ajudar na escrita de algoritmos que permitem esse tipo poderoso de processamento é que várias linguagens de programação quântica de alto nível têm sido criadas, mas a grande maioria das abstrações oferecidas acabam por criar também algumas limitações. Essa abordagem pode permitir cálculos sem sentido em um contexto quântico, proibir a expressão sucinta da interação entre a lógica clássica e a lógica quântica, e não fornecer construções importantes que são necessárias para a programação quântica. (SVORE, GELLER, et al., 2018, p.1, tradução nossa) Várias linguagens de programação quântica foram desenvolvidas nos últimos anos. Elas são conhecidas como “linguagens de definição de circuitos” (SVORE, GELLER, et al., 2018, p. 2, tradução nossa) 1 e o nível de abstração oferecido por elas possui foco na criação e manipulação de circuitos quânticos e/ou na transformação dos mesmos. Isso impede que essas DSLs modelem, por exemplo, algoritmos repeat-until-success e outros algoritmos com ramificação não trivial. Esta limitação pode ser parcialmente mitigada incluindo alguns tipos de realimentação clássica como elementos do circuito, como é feito em alto nível pelo LIQUi|> ou ProjectQ e em baixo nível pelo OpenQASM 2.0. Incluir feedback clássico diretamente nas representações de circuitos é impraticável para a interação de algoritmos clássicos robustos com processamento quântico, limitando a utilidade para caracterização adaptativa ou para computações híbridas quânticas-clássicas. (SVORE, GELLER, et al., 2018, p. 2, tradução nossa) 1 Do original: circuit definition languages.
  • 7. 7 Para atender a necessidade de expressar de forma clara e completa os algoritmos quânticos, foi que os pesquisadores da Microsoft® Research criaram essa linguagem especial e completamente nova. Q# fornece um sistema de tipos, um ambiente rigidamente restrito para intercalar com segurança computações clássicas e quânticas, sintaxe especializada, manipulação de código simbólico para gerar automaticamente transformações corretas de operações quânticas e poderosas construções funcionais que auxiliam na composição. (SVORE, GELLER, et al., 2018, p. 1, tradução nossa) Este trabalho visa trazer benefícios na criação e na manipulação de algoritmos quânticos de forma facilitada através da apresentação desta nova linguagem de programação. Alunos de Engenharia de Software e cursos similares os quais desejam se aprofundar na pesquisa com algoritmos e estruturas de dados, análise de algoritmos e afins, poderão abstrair a criação e manipulação de códigos de baixo nível e acelerar o desenvolvimento de algoritmos nos estudos da computação quântica. 4. Desenvolvimento 1. Um breve histórico Desde que os primeiros computadores surgiram entre 1940 e 1950, muitas coisas mudaram mas a computação tem seguido o mesmo modelo computacional mesmo após diversos avanços. Computadores pessoais e comerciais processam informações computacionais através de microprocessadores baseados em transistores variando entre 0 e 1 até os dias de hoje. A representação das informações nos computadores clássicos é uma abstração de um conjunto de bits. Um bit é a menor unidade endereçável de um computador. Hoje em dia, um programador não precisa se preocupar em como tratar um conjunto de bits para transmitir, armazenar e/ou representar informações. Pois isso está abstraído dele em uma linguagem de programação de alto nível para que ele se preocupe apenas com a lógica da aplicação, enquanto que o sistema operacional fica encarregado de
  • 8. 8 representar as informações e cuidar de muitas outras preocupações de forma automatizada. No decorrer dos anos muitas abstrações foram sendo implementadas a fim de diminuir as responsabilidades técnicas que dizem respeito à mecânica clássica da computação tradicional. E ainda hoje muitas outras abstrações estão sendo implementadas até mesmo como melhoria a medida que novos dispositivos de hardware são reinventados e são capazes de processar as informações de forma otimizada como o exemplo dos processadores e dos tipos de memória. A computação quântica já é um tópico de pesquisa há mais de 100 anos, desde que Max Planck lançou sua Hipótese Quântica em 1900 (PHYSICS: THE QUANTUM HYPOTHESIS, 2018) e muitos outros estudiosos demonstraram interesse pelo assunto. Até o Albert Einstein usou a teoria quântica para explicar várias hipóteses. Hoje em dia, como resultado de tantos anos de pesquisa, nós temos a promessa de que computação quântica pode trazer melhorias drásticas na resolução de problemas específicos. 4.2 A promessa da computação quântica Para entender o real potencial da computação quântica na promessa da transformação digital, vamos nos utilizar de um comparativo com a computação tradicional que — embora sejam modelos distintos de computação — pode nos ajudar a ter uma boa percepção pelas diferenças. Suponhamos que exista um algoritmo com 2^60 possibilidades de entrada e suponhamos também que seria necessário 1 nanosegundo para executar cada uma delas em um supercomputador — algo absurdamente otimista! O tempo total necessário para percorrer todas as entradas possíveis seria de 36,5 anos. É claro que seria muito melhor simplesmente executar a entrada com a qual você se importa e obter a resposta em um instante, em vez de esperar metade da vida para processar cada uma delas é selecionar apenas uma a partir de uma lista. Essa diferença fica mais clara se não considerarmos o nanosegundo otimista.
  • 9. 9 4.3 Superposição Um dos princípios mais fundamentais da mecânica quântica e, portanto da computação quântica, é o princípio da superposição. Como o estado quântico é especificado por momento, energia, momento angular ou spin e há uma incerteza na determinação de seu valor, isso implica que uma partícula pode ocupar muitos estados quânticos (com probabilidade diferente). Isso é chamado de superposição. Por exemplo, os elétrons possuem um recurso quântico chamado spin, um tipo de momento angular intrínseco. Na presença de um campo magnético, o elétron pode existir em dois possíveis estados de spin, geralmente chamados spin up e spin down. Cada elétron, até ser medido, terá uma chance finita de estar em qualquer estado. Apenas quando medido é observado estar em um estado de spin específico. Na experiência comum, uma moeda voltada para cima tem um valor definido: é cara ou coroa. Mesmo se você não tenha olhado para a moeda você já sabe que ela deve ser cara ou coroa. Na experiência quântica, a situação é mais inquietante: as propriedades materiais das coisas não existem até serem medidas. Até que você “olhe” (meça a propriedade particular) na moeda, por assim dizer, ela não é nem cara nem coroa. A Figura 1 ilustra a fórmula de um estado de superposição de um qubit que quando medido pode resultar em 0 cinquenta por cento das vezes, e resultar em 1 também cinquenta por cento das vezes. Figura 1. Superposição. (NIELSEN, M. A.; CHUANG I. L, 2010) Apenas quando o estado da partícula é medido é que se estabelece um estado definido. Mas assim que paramos de monitorar seu comportamento, a partícula se dissolve novamente retornando ao seu estado de superposição. O princípio da superposição afirma que dois ou mais estados quânticos válidos podem ser adicionados, ou sobrepostos, para criar um novo estado quântico
  • 10. 10 válido não importa quão contraintuitivo isso possa parecer para nós. Por outro lado, todo estado quântico pode ser representado como dois ou mais estados quânticos distintos também. Além disso, objetos quânticos — que são frequentemente elétrons ou átomos — podem estar em mais de um estado quântico ao mesmo tempo. Sim, ao mesmo tempo! Podem ter dois estados diferentes, tanto na aparência, quanto na velocidade e na localização. Se você pensar em partículas quânticas como ondas, essas ondas estarão em todos os estados possíveis ao mesmo tempo, em vez de estarem em um estado ou outro. É como se as ondas estivessem se sobrepondo e, ao mesmo tempo, não. Por mais estranho que seja, uma partícula pode estar em dois lugares ao mesmo tempo, assim que você a observa (mede) ela entrará em colapso, seu estado final. Isso significa que, assim que você fizer uma medição, todas as partículas quânticas serão paralisadas em um único estado. 4.4 Entrelaçamento (Entanglement) Entrelaçamento (ou emaranhamento) quântico é um fenômeno físico que ocorre quando pares ou grupos de partículas são gerados, interagem ou compartilham a proximidade espacial de maneiras que o estado quântico de cada partícula não pode ser descrito independentemente do estado das outras, mesmo quando as partículas são separadas por uma grande distância. Entrelaçamento quântico: é uma forma específica de superposição entre sistemas físicos distintos e diz respeito à correlação mais profunda que clássica do estado do sistema (como posição, momento, polarização e spin) de objetos muitas vezes separados amplamente no espaço e/ou tempo. Assim, a medição de um objeto definirá outro, mesmo que nenhuma informação tenha sido trocada. (MICHAEL J. C. H. et al, 2017, p.3, tradução nossa) Medidas de propriedades físicas, como posição, momento, spin e polarização, realizadas em partículas emaranhadas, são correlacionadas. Por exemplo, se um par de partículas for gerado de tal forma que seu spin total seja conhecido como zero, e se uma partícula tiver rotação no sentido horário em um determinado eixo, o
  • 11. 11 spin da outra partícula, medido no mesmo eixo, será encontrado no sentido anti- horário, como é de se esperar devido ao seu emaranhamento. Tais fenômenos foram o tema de um artigo de 1935 de Albert Einstein, Boris Podolsky e Nathan Rosen (EINSTEIN, A. et al, 1935), e vários trabalhos de Erwin Schrödinger logo depois, descrevendo o que veio a ser conhecido como o Paradoxo EPR. Einstein e outros consideraram tal comportamento impossível, uma vez que violava a visão de causalidade do realismo local. Einstein referindo-se a ele como "ação assustadora à distância" (BELLS, J. S., p. 143, 1987, tradução nossa). E argumentava que a formulação aceita da mecânica quântica deveria ser incompleta. Mais tarde, no entanto, as previsões contraintuitivas da mecânica quântica foram verificadas experimentalmente em testes onde a polarização ou spin de partículas emaranhadas foram medidas em locais separados. Em testes anteriores, não poderia ser absolutamente descartável que o resultado do teste em um ponto pudesse ter sido sutilmente transmitido ao ponto remoto, afetando o resultado no segundo local. No entanto, os chamados "testes livres de fendas" foram realizados nos quais os locais foram separados de forma que as comunicações na velocidade da luz levariam mais tempo — em um caso, 10.000 vezes mais tempo — do que o intervalo entre as medidas (Yin, J. et al, 2013). 4.5 Linguagens de programação Existem várias linguagens de programação quânticas hoje em dia. A maioria delas são incorporadas/embutidas em linguagens existentes permitindo a rápida adoção por programadores de diferentes gostos/estilos. Isso é como ver um filme em outra língua legendado para a sua língua nativa. O Quipper é uma linguagem de programação quântica funcional e fortemente tipada, incorporada em Haskell; O ScaffCC/Scaffold está embutido em C/C++, aproveitando a infraestrutura da LLVM; QWire é incorporado no sistema de prova Coq; LIQUi|> é incorporado em F#; e ProjectQ e Quil estão embutidos no Python. (SVORE, GELLER, et al., 2018, p.1-2, tradução nossa)
  • 12. 12 Várias linguagens de programação quântica têm sido propostas nos últimos anos, algumas no estilo imperativo outras no estilo funcional, umas de baixo nível outras de alto nível. As abstrações e os principais recursos, no entanto, concentram-se na criação e manipulação de circuitos quânticos. Enquanto várias linguagens como Quipper, LIQUi|> e ProjectQ, suportam funções de alto nível, elas são implementadas como transformações de circuitos: funções que recebem circuito(s) de entrada e produzem circuito(s) de saída. (SVORE, GELLER, et al., 2018, p. 2, tradução nossa) Porém, apesar de existir uma vasta quantidade de opções de linguagens de programação quânticas, a maioria delas é normalmente orientada na criação e/ou manipulação de circuito(s) quântico(s). Isso acontece até mesmo com as linguagens que suportam funções de alto nível. 4.6 Modelo quântico de computação A arquitetura de hardware de um computador quântico é completamente diferente dos computadores clássicos que já temos por muitos anos. Informações quânticas são armazenadas em estados quânticos da matéria e não em lógica booleana, a qual está limitada a apenas duas possibilidades. A computação quântica é efetuada por operações baseadas em interferência quântica e os estados quânticos são armazenados no que é conhecido como qubit. Um modelo natural para computação quântica é tratar o computador quântico como um co-processador, semelhante a GPUs, FPGAs e outros processadores adjuntos. A lógica de controle primária executa o código clássico em um computador host clássico. Quando apropriado e necessário, o programa host pode invocar um sub- programa executado no processador quântico adjunto. Quando o sub-programa termina, o programa host obtém acesso aos resultados do sub-programa. (SVORE, GELLER, et al., 2018, p. 3, tradução nossa) Na Figura 2 é possível ter uma idéia visual da arquitetura de computação quântica e fazer uma comparação com a arquitetura de computação clássica. Note
  • 13. 13 que na computação quântica, é possível processar diversos resultados simultaneamente. Figura 2. Programa quântico comparado com o clássico. (MATTHEW, 2005) O poder de paralelismo do modelo de computação quântico é absurdamente maior em comparação com o modelo tradicional. Porém o grande desafio agora é poder extrair o resultado correto antes que ocorra uma medição, o que anula as propriedades atômicas de processamento. Ainda não é possível ter acesso ao que está sendo processado dentro do contexto de uma computação no modelo quântico a fim de extrair resultados. Um programa Q# não tem capacidade de introspecção no estado de um qubit e, portanto, é totalmente agnóstico sobre o que um estado quântico é ou sobre como é realizado. Tudo o que se tem hoje são estatísticas probabilísticas de resultados que podem não ser muito práticas conforme o número de possibilidades de resultados aumenta e se mostra exponencial. 4.8 Debugando e testando um programa em Q# Debugar programas quânticos pode ser uma tarefa desafiadora principalmente no contexto do modelo de computação quântica o qual funciona apenas como um adjunto nos dias atuais, mas na concepção do Q# foram previstos
  • 14. 14 alguns recursos que podem auxiliar nessa difícil tarefa. Diferentemente de outras linguagens de programação do gênero, o Q# fornece abstração em alto nível para os desenvolvedores porém sem os limitar ao acesso a correções de erro e outros detalhes de baixo nível que são importantes em algumas situações mais específicas. Uma função que retorne uma tupla vazia pode ser ignorada por um programa host sem nenhuma preocupação adicional por exemplo. Ou seja, uma máquina de destino pode optar por não executar nenhuma função que retorne ()} com a garantia de que essa omissão não modificará o comportamento de qualquer código Q# seguinte. Essa consequência torna as funções uma ferramenta útil para incorporar a lógica de depuração e teste. (SVORE, GELLER, et al., 2018, p. 10, tradução nossa) O exemplo de código abaixo em Q# exibe uma função usada para representar efeitos colaterais de diagnóstico. Trata-se de uma função que recebe um valor do tipo Double o qual não deve ser menor ou igual a zero. Caso contrário, será enviada uma mensagem de falha formatada como uma string para o programa host. Figura 3. Assert Positive. (SVORE, GELLER, et al., 2018) Podemos notar a semelhança com o C# na estrutura do código apresentado, mas vale ressaltar que o Q# é uma linguagem completamente nova e não está embutida em nenhuma linguagem como as outras linguagens de programação quântica estão. 4.9 Configurando o ambiente de desenvolvimento Você também pode começar a trabalhar com computação quântica a partir do seu computador pessoal. O Quantum Development Kit pode ser usado com o Visual Studio 2017 ou com linha de comando e um editor de códigos como o Visual Studio Code. Também é possível usar o QDK a partir da linha de comando diretamente se você preferir.
  • 15. 15 Para mais informações basta acessar este link com instruções em inglês: https://docs.microsoft.com/en-us/quantum/install-guide/?view=qsharp-preview Após instalar a IDE (Do acrônimo em inglês: Integrated Development Environment) Visual Studio 2017 ou superior caso você ainda não o tenha feito, basta baixar e instalar o Microsoft® Quantum Development Kit: https://marketplace.visualstudio.com/items?itemName=quantum.DevKit Com o Visual Studio 2017 instalado e também o QDK, agora é hora de validar a instalação do QDK. Para isso, nós vamos criar a nossa primeira aplicação quântica Hello World apenas para verificar se o nosso ambiente Q# foi corretamente instalado e configurado. ● Abra o Visual Studio 2017; ● Acesse o menu File e clique em New > Project...; ● No navegador de modelos de projetos, abaixo de Installed > Visual C#, selecione o modelo Q# Application; ● Certifique-se de ter selecionado o .NET Framework 4.6.1 na lista na parte inferior da caixa de diálogo New Project;
  • 16. 16 Figura 4. Criando um novo projeto no Visual Studio 2017. (Fonte: O autor) Após a criação do projeto, o Visual Studio 2017 irá atualizar as dependências automaticamente. Antes de continuar, abra o arquivo Driver.cs e adicione a linha de código conforme destacado na imagem abaixo: Figura 5. Adicionando um comando de pausa para o console. (Fonte: O autor)
  • 17. 17 Agora basta pressionar F5 e o seu programa será compilado e executado. Parabéns, você acaba de criar o seu primeiro programa em Q#! O Q# lembra muito linguagens já consagradas como C# e Java no estilo de escrita de códigos, no uso de chaves para agrupamento de instruções, ponto-e- vírgula para finalizar instruções bem como barra dupla para comentários. Além disso, o Q# também nos permite trabalhar com namespaces de forma similar ao acontece no C# em muitos casos. No Q# é comum a utilização de operações. Operação é uma unidade básica que em essência, diz respeito a uma “função” que tem o poder de afetar o estado do dispositivo quântico e pode misturar computação clássica e quântica. O estilo de programação em Q# se assemelha ao estilo de programação funcional muitas vezes. Por padrão, as variáveis são imutáveis e o compilador faz interferência de tipos para as variáveis locais. Mas também há suporte para mutabilidade e o estilo imperativo de desenvolvimento desde que isso seja feito no mesmo escopo onde uma variável foi definida, pois não existem tipos de referência em Q#. Além do mais, operações e funções podem ser retornadas para outras funções ou podem ser usadas como argumento para outras operações. Funções em Q# são como operações, a não ser pelo fato de que as funções só podem realizar computação clássica. Elas não são capazes de chamar nenhuma operação que venha a afetar o estado quântico de um qubit, nem ter variantes. Ou seja, podemos garantir que uma função sempre retorna o mesmo resultado a partir da mesma entrada de dados. Sendo assim, um programa host clássico normalmente começa com uma chamada a uma operação em Q#. (SVORE, GELLER, et al., 2018, tradução nossa) 4.9.1 Tipos Primitivos Clássicos Q# possui os tipos de dados clássicos por padrão como Int, Double, Boolean e String. Os tipos Int, Double e Boolean suportam os operadores comuns de aritmética em numéricos e operações lógicas para Booleanos. Q# possui suporte para operações bitwise em inteiros o que significa que as informações podem ser computadas bit a bit, que menor unidade de dados de um
  • 18. 18 computador. Muitas outras linguagens de programação armazenam dados e executam instruções em grupos de bits múltiplos de tamanhos 4, 8, 16 ou 32 bits. O tipo string em Q# é usado apenas para informações de diagnóstico e, portanto, apenas funcionalidade mínima de manipulação de strings é oferecida reforçando o fato de que o Q# é projetado para execução em um processador quântico adjuntivo. No exemplo abaixo, as informações de depuração são passadas de volta para um programa host utilizando interpolação de strings como no C#, porém este trecho de código apresentado está em Q#. (SVORE, GELLER, et al., 2018, tradução nossa) Ex.: Figura 6. Interpolação de strings com Q#. (Fonte: O autor) Q# também tem um tipo Range que é basicamente uma sequência aritmética de inteiros e funciona de forma similar ao que podemos ver em linguagens como F# e também no C# a partir da versão 8. Por exemplo, o Range 1..4 é o mesmo que 1, 2, 3, 4. E como o Range é um primitivo, eles podem ser passados como parâmetros, como valores de funções ou até como retorno de operação. (SVORE, GELLER, et al., 2018, tradução nossa) 4.9.2 Tipos Primitivos Quânticos Devemos observar que o Q# é uma linguagem fortemente tipada, de modo que o uso cuidadoso desses tipos pode ajudar o compilador a fornecer fortes garantias sobre os programas Q# em tempo de compilação. Q# fornece tipos primitivos clássicos e quânticos que podem ser usados diretamente e uma variedade de maneiras de produzir novos tipos de outros tipos. Os tipos Pauli, Result e Qubit por exemplo são tipos usados exclusivamente em computação quântica. Ou seja, a utilização desses tipos não faz nenhum sentido em linguagens puramente clássicas como aquelas que já foram mencionadas anteriormente.
  • 19. 19 Valores do tipo Pauli especificam um operador Pauli de um qubit único. Existem variações de Pauli como PauliI, PauliX, PauliY e PauliZ cujos valores são utilizados para se especificar a base de uma medição. O tipo Result especifica o resultado de uma medição quântica. Q# espelha a maioria dos hardwares quânticos fornecendo medições em produtos de operadores Pauli de um único qubit. Um Result de Zero indica que o autovalor de +1 foi medido e um Result de Um indica que o autovalor -1 foi medido. Ou seja, Q# representa autovalores pela potência para a qual −1 é gerado, usando +1 = (−1)0 e −1 = (−1)1 . Essa convenção é mais comum na comunidade de algoritmos quânticos, pois mapeia mais de perto os bits clássicos. (SVORE, GELLER, et al., 2018, p. 6, tradução nossa) Existe também o tipo Unit que é o tipo que permite apenas um valor (). Este tipo é usado para indicar que uma função ou operação em Q# não retorna nenhuma informação. As constantes Pauli, PauliX, PauliY, PauliZ, One e Zero são todos símbolos reservados em Q#. 4.9.3 Qubits Q# considera os qubits como itens obscuros que podem ser passados para funções e operações com a restrição de que eles só podem ser usados em operações primitivas embutidas. De qualquer forma, um estado quântico não pode ser representado por nenhum tipo ou construção. Ao invés disso, assim como os bits em computadores clássicos, os qubits representam a menor unidade física endereçável de um computador quântico. E como um qubit é um item de vida longa, então o Q# não precisa de tipos lineares. Vale lembrar que estado não é referenciado de forma explícita no Q#, mas é feita uma descrição da transformação do estado. Assim como são acumuladas as transformações de cada vértice nos programas de computação gráfica, um programa em Q# acumula transformações em estados quânticos que são representados de forma totalmente obscura para um dispositivo de destino. (SVORE, GELLER, et al., 2018, tradução nossa)
  • 20. 20 É possível que um programa quântico permita-nos fazer medições e até modificar o estado de um qubit, mas não é possível saber o que é um estado quântico ou sobre como ele é realizado. Ao invés disso, é possível que um programa em Q# possa chamar operações que são capazes de aprender informações de um quibit e também operações que podem atuar no estado de um quibit embora que estas operações não tenham nenhuma definição dentro da linguagem em si mesma até que o programa host execute tal programa em Q#. Um programa em Q# pode combinar tais operações conforme definição a partir de uma máquina host de destino, para criar novas operações de alto nível a fim de expressar a computação quântica de uma solução completa. Essa flexibilidade oferecida pelo Q# torna mais fácil a expressão de lógica subjacente favorecendo a criação de algoritmos híbridos clássico-quânticos. Essas funções não podem modificar o estado dos qubits transmitidos, pois aos argumentos de entrada aplica-se então a restrição de que as funções só podem chamar outras funções e não podem chamar operações. (SVORE, GELLER, et al., 2018, p. 6, tradução nossa) Na computação clássica, não existe diferença essencial entre um método e uma função. Mas na computação quântica com Q#, é importante saber a diferença que há entre funções e operações. E isso é o que será explorado com mais detalhes no próximo tópico. 4.9.4 Operações e funções O Q# oferece suporte para dois tipos de chamadas, são elas as operações e as funções. As operações são capazes de afetar o estado quântico, já as funções garantem que isso não aconteça, além de sempre retornar o mesmo resultado a partir da mesma entrada de dados. Uma função pode ser encarregada de executar uma computação clássica como parte de um requisito de execução de um algoritmo quântico por exemplo. Tanto operações como funções trabalham com tuplas — uma tupla representa objeto composto. Elas recebem uma tupla como argumento de entrada e
  • 21. 21 produzem uma tupla como resultado da computação. Mesmo quando não nenhum resultado computado como saída, elas retornam uma tupla vazia. Por causa da equivalência de uma única instância de uma tupla singleton, operações e funções que retornam uma tupla singleton podem ser tratadas como se estivessem retornando um valor único, desembrulhado. Operações e funções são tipos de primeira classe em Q# e por isso elas podem ser passadas como argumentos para outras operações e/ou funções, e ainda serem retornadas como resultados de uma operação ou função criando uma composição, demonstrando com isso entre outras coisas que o Q# tem seu sabor de programação funcional. Operações e funções podem ser incluídas em tuplas e é possível se ter matrizes de operações e funções. (SVORE, GELLER, et al., 2018, tradução nossa) 4.9.5 Aprendendo mais sobre o Q# Existe um projeto de código aberto chamado Microsoft® Quantum Katas (https://github.com/Microsoft/QuantumKatas) no qual há uma série de exercícios de programação que oferecem feedback imediato a medida em que se avança nas tarefas propostas para que se possa aprender o Q# em um ritmo mais adequado. Cada uma dessas tarefas, espera que você preencha um pequeno trecho de código que aumenta de dificuldade gradativamente. Existem comentários explicativos nos arquivos de código e um framework de testes valida o código digitado nas soluções. Para mais informações sobre como utilizar esse excelente recurso de aprendizagem dessa nova linguagem de programação, é recomendado assistir ao vídeo da segunda sessão deste evento Microsoft® Ignite 2018 apresentado na língua inglesa pela Bettina Heim: https://cloudblogs.microsoft.com/quantum/2018/10/11/presenting-the-potential -of-quantum-computing-at-microsoft-ignite-2018/ 5. Considerações Finais Foi apresentada uma revisão bibliográfica do Q#, uma nova linguagem de programação quântica da Microsoft® a fim de fornecer maior flexibilidade de
  • 22. 22 abstração de circuitos quânticos visando a melhoria de performance na criação de algoritmos para computação quântica. Com essa nova linguagem desenvolvedores de software agora dispõem de mais flexibilidade na representação de circuitos quânticos podendo corrigir erros, tratar temporizações e ruídos de forma explícita. E além disso, ainda poderão escrever algoritmos mais precisos e eficientes sem se preocupar com detalhes de baixo nível utilizando uma linguagem de alto nível. Com essa linguagem fica mais fácil trabalhar com recursão e iteração por exemplo. Algo que abre um novo leque de possibilidade na escrita e na elaboração de algoritmos mantendo sempre uma separação clara entre o código computacional quântico e clássico. Vale ressaltar também que existem uma série de ferramentas dentro da IDE do Visual Studio como o framework de testes de unidade por exemplo que auxiliam e potencializam os recursos oferecidos pela linguagem em si, o que aumenta muito a produtividade. Também foram apresentadas formas de simular a execução de algoritmos quânticos em um computador de desenvolvimento local, de baixo custo, visando aumentar a produtividade das pesquisas em computação quântica. E analisando os resultados obtidos, é possível concluir que essa nova linguagem de programação coloca os estudos e pesquisas na criação de algoritmos quânticos em uma certa vantagem em relação às outras linguagens já existentes em alguns aspectos. Outro fato importante para o avanço e desenvolvimento desta linguagem é que a Microsoft® está abrindo o código fonte do QDK no Github para que toda a comunidade de desenvolvedores ao redor do mundo possa contribuir com suas ideias, com suas descobertas e com suas dúvidas. Essa nova linguagem tem todos os recursos necessários para continuar crescendo junto com a evolução nos estudos da computação quântica em geral sem ficar limitada a detalhes de baixo nível necessários para uma melhor expressividade na elaboração de algoritmos clássico-quânticos. Os próximos passos serão a descoberta de novos algoritmos ou ainda a melhoria/refatoração dos algoritmos existentes para a solução de problemas antes impossíveis para o modelo de computação clássico, pois nós já temos todas as ferramentas que precisamos.
  • 23. 23 REFERÊNCIAS AARONSON, Scott. Quantum computing since Democritus. New York, NY, USA: Cambridge University Press, 2013. BELL, J. S. Speakable and unspeakable in quantum mechanics. New York, NY, USA: Cambridge University Press, 1987. CALUDE, C. S.; CALUDE, E. The Road to Quantum Computational Supremacy. arXiv: 1712.01356v1 [quant-ph], 2017. Disponível em: <https://arxiv.org/pdf/1712.01356.pdf>. Acesso em: 5 ago. 2018. EINSTEIN, A. et al. Can Quantum-Mechanical Description of Physical Reality be Considered Complete? American Physical Society, 1935. Disponível em: <http://cds.cern.ch/record/1060284/files/PhysRev.48.696.pdf>. Acesso em: 1 jul. 2019. MATTHEW, D. P. A Practical Quantum Computer Programming Framework. arXiv:0911.2423v1 [cs.PL], 2005. Disponível em: <https://arxiv.org/ftp/arxiv/papers/0911/0911.2423.pdf>. Acesso em: 6 out. 2018. MICHAEL J. C. H. et al. The challenges for Systems Engineers of non-classical quantum technologies. arXiv:1710.05643v2 [quant-ph], 2017. Disponível em: <https://arxiv.org/pdf/1710.05643.pdf>. Acesso em: 2 ago. 2018. NIELSEN, M. A.; CHUANG I. L. Quantum Computation and Quantum Information. New York, NY, USA: Cambridge University Press, 2010. PAETZNICK, A.; SVORE, K. M. Repeat-Until-Success: Non-deterministic decomposition of single-qubit unitaries. arXiv: 1311.1074v2 [quant-ph], 2014. Disponível em: <https://arxiv.org/pdf/1311.1074.pdf>. Acesso em: 5 ago. 2018. PHYSICS: THE QUANTUM HYPOTHESIS. In: Encyclopedia.com, 2016. Disponível em: <https://www.encyclopedia.com/science/science-magazines/physics-quantum-hypoth esis>. Acesso em: 2 ago. 2018. REBELO, M. N. Desenvolvimento de um Protótipo de um Gerador de Analisador Léxico, 2002. Disponível em: <http://dsc.inf.furb.br/arquivos/tccs/monografias/2002-2michelnogueirarebelovf.pdf>. Acesso em: 5 ago. 2018. SANTOS, A. C. O Computador Quântico da IBM e o IBM Quantum. Revista Brasileira de Ensino de Física, Niterói, 1 Setembro 2016. Disponível em: <http://www.scielo.br/pdf/rbef/v39n1/1806-1117-rbef-39-01-e1301.pdf>. Acesso em: 5 ago. 2018.
  • 24. 24 SVORE, K. M. et al. Q#: Enabling scalable quantum computing and development with a high-level domain-specific language. arXiv: 1803.00652v1 [quant-ph], 2018. Disponível em: <https://arxiv.org/pdf/1803.00652v1.pdf>. Acesso em: 4 ago. 2018. Yin, J. et al. Bounding the speed of ‘spooky action at a distance’. arXiv: 1303.0614v2 [quant-ph], 2013. Disponível em: <https://arxiv.org/pdf/1303.0614v2.pdf>. Acesso em: 1 jul. 2019.