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 cílovým kvantovým procesorem. 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é by ovlivnily hodnotu, která je explicitně reprezentována v Q#. Pokud tedy implementace určitého volatelného typu přímo nebo nepřímo nevolá žádnou z těchto nativně implementovaných operací, její spuštění vždy vytvoří stejný výstup, a to se stejným vstupem.

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 Q# knihovna, determinismus je zaručen tím, že vyžaduje, aby funkce mohly volat pouze jiné funkce a nemohly 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 lze funkce vyhodnotit, jakmile je známa jejich vstupní hodnota, a v zásadě se pro stejný vstup nemusí vyhodnocovat více než jednou.

Q# proto rozlišuje mezi dvěma typy volatelných funkcí: operacemi a funkcemi. Všechny volatelné položky přebírají jako vstup jeden argument (potenciálně s hodnotou řazené kolekce členů) a jako výstup vygenerují jednu hodnotu (řazenou kolekci členů). Syntakticky se typ operace vyjadřuje jako <TIn> => <TOut> is <Char>, kde <TIn> se má nahradit typem argumentu, <TOut> má být nahrazen návratový typ a <Char> má být nahrazen vlastnostmi operace. Pokud není nutné zadávat žádné vlastnosti, syntaxe zjednodušuje hodnotu .<TIn> => <TOut> Podobně jsou typy funkcí vyjádřeny jako <TIn> -> <TOut>.

Kromě této záruky determinismu je mezi operacemi a funkcemi malý rozdíl. Obě jsou hodnoty první třídy, které lze volně předávat kolem; Dají se použít jako návratové hodnoty nebo argumenty pro jiné volatelné položky, 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 mohou být vytvořena na základě typ-parametrizované definice, například typ parametrizované funkce Pow výše, a mohou být částečně použity jako v příkazu v return 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í.

Charakteristikou operace je 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á buď z jedné z předdefinovaných sad popisků, nebo z kombinace charakteristických výrazů prostřednictvím podporovaného binárního operátoru.

Existují dvě předdefinované sady, Adj a Ctl.

  • Adj je sada, která obsahuje jeden popisek, který označuje, že operace je adjointable, což znamená, že podporuje Adjoint funktor a použitou kvantovou transformaci lze vrátit zpět, to znamená, že ji lze převrátit.
  • Ctl je sada, která obsahuje jeden popisek označující, že operace je kontrolovatelná, což znamená, že podporuje Controlled funktor a její provádě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 sjednocení + sady a průnik *sady . V EBNF

    predefined = "Adj" | "Ctl";
    characteristics = predefined 
        | "(", characteristics, ")" 
        | characteristics ("+"|"*") characteristics;

Jak by se očekávalo, * má vyšší prioritu než + a obě jsou asociativní zleva. Například typ unitární operace je 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 formě má dvě hlavní výhody; za prvé, nové popisky mohou být zavedeny bez exponenciálně mnoho klíčových slov jazyka pro všechny kombinace popisků. Možná důležitější je, že použití výrazů k označení charakteristik operace také podporuje parametrizace nad charakteristikami operací v budoucnosti.