Closed Calavoow closed 7 years ago
Yes. This is expected behavior. You cannot nest Circuit.Compile, Circuit.Run or Circuit.Fold. The standard technique is do each of these once. Here is a version of your code as an fsx script in samples:
#if INTERACTIVE
#I @"..\bin" // Tell fsi where to find the Liquid dll
#r "Liquid1.dll"
#r "Liquid2.dll"
#else
namespace Microsoft.Research.Liquid // Tell the compiler our namespace
#endif
open System // Open any support libraries
open Microsoft.Research.Liquid // Get necessary Liquid libraries
open Util // General utilites
open Operations // Basic gates and operations
open Tests // Just gets us the RenderTest call for dumping files
module Script = // The script module allows for incremental loading
[<LQD>] // LQD flags this as being callable from the command line
let Main() = // Name of callable function
logOpen "Liquid.log" false
show "Starting sample script..." // show does printf + logs and ensemble runs
let k = Ket(4)
let qs = k.Qubits
let expand (qs: Qubits) =
match (List.map(fun l -> [l]) qs) with
| [_;_;_;_] ->
let labellingStart (qbs: Qubits) =
LabelL "\\ket{k_i}" [qbs.[3]]
LabelL "\\ket{k_{i+1}}" [qbs.[2]]
LabelL "\\ket{k_{i+2}}" [qbs.[1]]
LabelL "\\ket{k_{i+3}}" [qbs.[0]]
labellingStart qs
// ... Remainder of circuit function ....
H >< qs
M >< qs
| x -> failwithf "4 qubits must be given, instead was given %A" x
let circ = Circuit.Compile expand qs
let circ = circ.Fold()
circ.RenderHT "Test"
#if INTERACTIVE
do Script.Main() // If interactive, then run the routine automatically
#endif
This will generate a drawing of the circuit as "Test.htm" (and Test.tex). What you really want to do comes under the area of Circuit manipulation. You can take any function and compile it to a circuit (as well as fold it). If you made your labels in one circuit and your real algorithm in one (or more) other compiled circuits, then you could just walk the circuit data structure and splice them together (this functionality is not built into the system).
If you take a look in the kit at \Liquid\UserCode\DaveWecker\AltOutput.fs
you'll see an example where I programmatically walk the circuit data structure to emit QASM
code. you could just walk your separate circuits to generate a single new one for execution or rendering.
I would like to partially Circuit.Fold a function, because circuit folding also includes moving labels on the right to the left. In this example I'm labelling the inputs of a function using the function
labellingStart
. I then compile the labelling to a circuit, to fold it so the labelling is executed in parallel. The labelling must then be applied to the larger circuit function in which it is embedded (not shown); I apply the Circuit.Run to make sure that thecircStart
is included in the larger circuit (otherwisecircStart
is not included in the output). This, however, seems to not be possible since it throws an error. Is this intended? What alternative way is there to put labels on the left and on the right which are shown in parallel, but are not moved by Circuit.Fold?I get the following error: