Sdílet prostřednictvím


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 podporuje Adjoint 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 podporuje Controlled 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.