Q# krótka składnia

Q# jest językiem programowania wykorzystywanym przez Microsoft do wykonywania obliczeń kwantowych. Język ten jest podobny do pod wieloma względami podobny do języka C# tego samego producenta niemniej posiada operacje umożliwiające prace na obiektach kwantowych. Poniżej znajduję się skrótowa składnia tego języka.

//helloWorld w języku Q#

namespace HelloQuantumWorld { //namespace 
    open Microsoft.Quantum.Intrinsic; // open importuje bibloteki
    operation HelloWorld() : Unit { // funkcje, operacje wykonywane przez program
        Message("Hello quantum world!");
    }
}

Typy danych:

Int – 64-bitowa wartość całkowitoliczbowa jak 16, 21, 56484
BigInt – liczba całkowita zo dowolnym rozmiarze, używana dla dużych liczb
Double – 64-bitowa liczba zmiennoprzecinkowa jak 25.598, 3156.864512
Bool – wartość True/False
String – Ciąg znaków jak „Lubie placki”
Range – Sekwencja liczb całkowitych zapisywana w formie wyrażenia start..step..stop. W wyrażeniu tym podajemy wartość początkową, o ile ma się się zmieniać ta wartość i jaki jest warunek końcowy. Podobnie jak ma to miejsce w klasycznej pętli for.
1..1..100 (można też zapisać 1..100), 1..-5.0, 17..12..75 itd.

let someRange = 1..2..50

Result – Reprezentuje wynik pomiaru. Wartości mogą być równe Zero lub One
Unit – Typ z jedną możliwą wartością
Qubit – unikalna zmienna reprezentująca kwant informacji

 

Struktury danych:

Array – tablice danych działające jak w większości znanych językach programowania. Ich inicjalizacja może wyglądać następująco:

let zeroArray = new Int[8]; // create array [0,0,0,0,0,0,0,0]
let oneArray = [1, size = 2]; // create array [1,1]
let arrayOfNumbers = [3, 4, 5, 6]; // create array [3,4,5,6]

Tuple – Pozwalają na zapis wielu różnych wartości w jednej zmiennej.

let tupleValue = (12.13, false, „OK”);
let (first, second, third) = tupleValue; //first = 12.13, second = false, third = „OK”

UDT – User Defined Types – Podobnie jak Tuple pozwala na stworzenie zmiennej zawierającej różne wartości posiadające anonimowe lub nazwane parametry.

newtype NamedPair = (Name : String, Value : Int);
let accuracy= NamedPair(„Accuracy”,  82);
let name = accuracy::Name; // Accuracy
let acValue = accuracy:: Value; // 82

Zmienne:

Q# ma dwie rodzaje zmiennych muttable i unmutable. Unmutable variable nie pozwala na zmianę swojej wartości i jest w zasadzie stałą. Muttable zaś może zachowuję się tak jak zwykła zmienna zmienna. Wartość unmutable przypisujemy do zmiennej poprzez słowo kluczowe let. Aby przypisać wartość muttable do zmiennej korzystamy ze słowa kluczowego mutabble. Żeby później ponownie przypisać wartość do zmiennej mutable konieczne jest skorzystanie z funkcji set

let a = [1, 2, 3];
mutable b = 123;
set b = 259;

Przydzielanie kubitów:

Kubity są wyjątkowymi typami danych i reprezentują kwanty informacji. Stan kubita można zmienić jedynie korzystając z bramek kwantowych. Q# nie tworzy nowych kubitów a jedynie przydziela i zwalnia dostępne dla siebie zasoby. Przydzielenie i zwalnianie kubitow możliwe jest poprzez użycie słowa kluczowego use.

use oneQubit = Qubit(); // przydziel pojedynczego kubita
use (qubit1, qubit2) = (Qubit(), Qubit());   // przydziela dwa kubity
use registryQubit = Qubit[n]; // przydziel tablice n kubitów

Use alokuje kubity zawsze w stanie |0> i po ich użyciu użytkownik powinien zwrócić je do tego stanu. Można alokować również kubity w nieznanym stanie korzystając ze słowa kluczowego borrow. Wynika to z faktu ze kubity takie mogą być wykorzystywane z innych operacji.

borrow oneQubit = Qubit();
borrow (qubit1, qubit2) = (Qubit(), Qubit());
borrow registryQubit = Qubit[n];

Operatory:

q# wykorzystuje standardowe operatory do porównywania wartości
równości: ==
nierówności: !=
mniej od: < więcej od: >
mniej lub równo od: <= więcej lub równo od: >=
 

Operatory logiczne:

Q# nie wykorzystuje standardowych operatorów logicznych && || ! a korzysta z słów kluczowych:
and: first and second
or: first or second
not: not first
 

Komentarze:

komentarze tworzone są przy wykorzystaniu // w czasie pisania tej instrukcji możliwe jest tworzenie komentarzy tylko jedno liniowych.

//komentarz

 

Funkcje i operacje:

Język ten rozróżnia dwa rodzaje wywołań funkcje i operacje. Sposób budowania funkcji jest następujący:

function sumFunction(first : Int, second : Int ) : Int {
    let sum = first + second;
    return sum;
}

function NazwaFunkcji(NazwaParametru: TypParametru, …) : ZwracanyTyp{
//code
}

Operacje budowane są i działają podobnie jak funkcje ale pozwalają na wykonywanie niedeterministycznych działań na elementach kwantowych.

    operation GetRandomResult() : Result {
        use qubit = Qubit();
        H(qubit);
        return M(qubit);
    }

Ponadto operacje mogą zostać oznaczone czy są to operacje typu adjoin czy controled:
Adj – obsługuje funktor Adjoint i oznacza ze zastosowaną transformację kwantową można cofnąć.
Ctl – obsługuje funktor Controlled i oznacza ze jego wykonanie może być uzależnione od stanu innych kubitów
 

Sterowanie:

Funkcje sterowania zbliżone są do innych języków i nie powinny sprawiać problemu osobom z nimi obeznanymi.
if else:

If first == 5 {
    Return 2;
}
Elif first == 2{
    Return 1;
}
Else{
    Return 0;
}

petla for:

mutable power = 2;
for i in 1 .. 10 {
    set power *= power;
}

enchanced for:

let array = [1, 2, 3, 4]; 
for i in array {
    Message(i);
}

while:

while someValue > 0 {
    set someValue += 1;
}

Repete until podobnie jak pętla while pozwala na powtarzanie iteracji dopóki nie zostanie spełniony odpowiedni warunek. Wyrażenie to zostało stworzone głównie w celu pracy nad zdarzeniami kwantowymi i może być wykorzystywane jedynie w operacjach.

use qubit = Qubit();
repeat {
    H(qubit);
    let result = M(qubit);
} until result == Zero;

within-apply
Możliwy tylko do wykonywania na operacja. Wykonuje pojedyncze transformacje na qubitach. Składa się ze słów kluczowych within i apply. W bloku within wykonywana jest pierwsza transformacja, w bloku apply wykonywana jest druga transformacja. Po czym automatycznie wykonywana jest odwrotność pierwszej transformacji.

within {
    ApplyToEachA(X, qubitArray);
} apply {
    Controlled X(qubitArray, auxQubit);
}

 

Fail:

fail "Wynik powinien być większy od 0"; 
// obsługa wyjątków najczęściej spotykany jako throw w innych językach programowania

 
Przydatnym streszczeniem całej tej wiedzy może być Q# Languge Quick Reference Guide dostępny pod:

https://github.com/microsoft/QuantumKatas/blob/main/quickref/qsharp-quick-reference.pdf

Dodaj komentarz

WordPress Video Lightbox Plugin