Operace a funkce
Jak je podrobněji popsáno v popisu datového typu qubitu, kvantové výpočty se provádějí ve formě vedlejších účinků operací, které jsou nativně podporovány na cílovém kvantovém procesoru. To jsou ve skutečnosti jediné vedlejší účinky v Q#. Vzhledem k tomu, že všechny typy jsou neměnné, neexistují žádné vedlejší účinky, které mají vliv na hodnotu, která je explicitně reprezentována v Q#. Pokud tedy implementace určitého volatelného volání přímo ani nepřímo nevyvolá žádnou z těchto nativně implementovaných operací, její spuštění vždy vytvoří stejný výstup vzhledem ke stejnému vstupu.
Q# umožňuje explicitně rozdělit tyto čistě deterministické výpočty na funkce. Vzhledem k tomu, že sada nativně podporovaných instrukcí není pevná a integrovaná do samotného jazyka, ale spíše plně konfigurovatelná a vyjádřená jako knihovna Q#, determinismus je zaručen tím, že funkce můžou volat pouze jiné funkce a nemohou volat žádné operace. Nativní instrukce, které nejsou deterministické, to znamená, že ovlivňují kvantový stav, jsou navíc reprezentovány jako operace. S těmito dvěma omezeními je možné funkce vyhodnotit hned, jak je známa jejich vstupní hodnota, a v zásadě není nutné vyhodnocovat více než jednou pro stejný vstup.
Q# proto rozlišuje dva typy volatelných: operace a funkce. Všechny volatelné vezmou jako vstup jeden argument (potenciálně řazenou kolekci členů) a jako výstup vytvoří jednu hodnotu (řazenou kolekci členů). Syntakticky se typ operace vyjadřuje jako <TIn> => <TOut> is <Char>
, kde <TIn>
se má nahradit typem argumentu, <TOut>
se nahradí návratový typ a <Char>
se nahradí vlastnostmi operace . Pokud není nutné zadávat žádné charakteristiky, syntaxe zjednodušuje <TIn> => <TOut>
. Podobně jsou typy funkcí vyjádřeny jako <TIn> -> <TOut>
.
Kromě této determinismu existuje malý rozdíl mezi operacemi a funkcemi. Oba jsou prvotřídní hodnoty, které lze volně předávat; dají se použít jako návratové hodnoty nebo argumenty jiným volatelným hodnotám, jak je znázorněno v následujícím příkladu:
function Pow<'T>(op : 'T => Unit, pow : Int) : 'T => Unit {
return PowImpl(op, pow, _);
}
Obě instance lze vytvořit na základě definice typově parametrizované, například typ parametrizované funkce Pow
dříve a dají se částečně použít jako v příkazu return
v příkladu.
Charakteristiky operací
Kromě informací o vstupním a výstupním typu obsahuje typ operace informace o vlastnostech operace. Tyto informace například popisují, jaké funktory operace podporuje. Kromě toho interní reprezentace obsahuje také informace relevantní pro optimalizaci, které kompilátor odvodí.
Charakteristiky operace jsou sada předdefinovaných a předdefinovaných popisků. Jsou vyjádřeny ve formě speciálního výrazu, který je součástí podpisu typu. Výraz se skládá z jedné z předdefinovaných sad popisků nebo kombinace výrazů charakteristik prostřednictvím podporovaného binárního operátoru.
Existují dvě předdefinované sady, Adj
a Ctl
.
-
Adj
je sada obsahující jeden popisek označující, že operace je adjointable, což znamená, že podporujeAdjoint
functor a použitá kvantová transformace může být "zpět", to znamená, že se dá invertovat. -
Ctl
je sada, která obsahuje jeden popisek označující, že operace je ovládatelná, což znamená, že podporujeControlled
functor a jeho spuštění může být podmíněno stavem jiných qubitů.
Dva operátory, které jsou podporovány jako součást výrazů charakteristik, jsou sjednocovací +
sady a průnik množiny *
.
V EBNF (rozšířený backus-naur formulář),
predefined = "Adj" | "Ctl";
characteristics = predefined
| "(", characteristics, ")"
| characteristics ("+"|"*") characteristics;
Jak byste očekávali, *
má vyšší prioritu než +
a oba jsou asociativní. Typ jednotné operace je například vyjádřen jako <TIn> => <TOut> is Adj + Ctl
, kde <TIn>
by měl být nahrazen typem argumentu operace a <TOut>
nahrazen typem vrácené hodnoty.
Poznámka:
Označení charakteristik operace v této podobě má dvě hlavní výhody; pro jednu je možné zavést nové popisky bez exponenciálně velkého počtu klíčových slov jazyka pro všechny kombinace popisků. Důležitější je, že použití výrazů k označení charakteristik operace také podporuje parametrizace nad charakteristikami operací v budoucnu.