diff --git a/.gitignore b/.gitignore index 49220a0..590d502 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /docs/src/assets/indigo.css /docs/Manifest.toml .vscode +.JuliaFormatter.toml diff --git a/Project.toml b/Project.toml index 48d664e..82d97d6 100644 --- a/Project.toml +++ b/Project.toml @@ -14,6 +14,13 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" YaoHIR = "6769671a-fce8-4286-b3f7-6099e1b1298a" YaoLocations = "66df03fb-d475-48f7-b449-3d9064bf085b" +[weakdeps] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Vega = "239c3e63-733f-47ad-beb7-a12fde22c578" + +[extensions] +ZXCalculusExt = ["Vega", "DataFrames"] + [compat] Expronicon = "0.10.3" Graphs = "1" @@ -22,11 +29,12 @@ Multigraphs = "0.3" OMEinsum = "0.7, 0.8" YaoHIR = "0.2" YaoLocations = "0.1" -julia = "1.9" +julia = ">= 1.9" [extras] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +Vega = "239c3e63-733f-47ad-beb7-a12fde22c578" [targets] -test = ["Test", "Documenter"] +test = ["Test", "Documenter", "Vega", "DataFrames"] diff --git a/ext/ZXCalculusExt.jl b/ext/ZXCalculusExt.jl new file mode 100644 index 0000000..16601ee --- /dev/null +++ b/ext/ZXCalculusExt.jl @@ -0,0 +1,266 @@ +module ZXCalculusExt + +using Graphs +import Graphs: AbstractEdge, src, dst +using Vega, DataFrames +using ZXCalculus, ZXCalculus.ZX +using ZXCalculus: ZX + +function spider_type_string(st1) + st1 == SpiderType.X && return "X" + st1 == SpiderType.Z && return "Z" + st1 == SpiderType.H && return "H" + st1 == SpiderType.Out && return "Out" + st1 == SpiderType.In && return "In" +end + +function generate_d_spiders(vs, st, ps, x_locs_normal, y_locs_normal) + return DataFrame( + id = [v for v in vs], + x = [get(x_locs_normal, v, nothing) for v in vs], + y = [get(y_locs_normal, v, nothing) for v in vs], + spider_type = [spider_type_string(st[v]) for v in vs], + phase = [iszero(ps[v]) ? "" : "$(ps[v])" for v in vs], + ) +end + +function generate_d_edges(zxd::ZXDiagram) + s = Int[] + d = Int[] + isH = Bool[] + for e in ZXCalculus.ZX.edges(zxd.mg) + push!(s, src(e)) + push!(d, dst(e)) + push!(isH, false) + end + return DataFrame(src = s, dst = d, isHadamard = isH) +end +function generate_d_edges(zxd::ZXGraph) + s = Int[] + d = Int[] + isH = Bool[] + for e in ZXCalculus.ZX.edges(zxd.mg) + push!(s, src(e)) + push!(d, dst(e)) + push!(isH, ZXCalculus.ZX.is_hadamard(zxd, src(e), dst(e))) + end + return DataFrame(src = s, dst = d, isHadamard = isH) +end + +function ZXCalculus.ZX.plot(zxd::Union{ZXDiagram,ZXGraph}; kwargs...) + scale = 2 + lattice_unit = 50 * scale + zxd = copy(zxd) + ZXCalculus.ZX.generate_layout!(zxd) + vs = spiders(zxd) + x_locs = zxd.layout.spider_col + x_min = minimum(values(x_locs), init = 0) + x_max = maximum(values(x_locs), init = 1) + x_range = (x_max - x_min) * lattice_unit + y_locs = zxd.layout.spider_q + y_min = minimum(values(y_locs), init = 0) + y_max = maximum(values(y_locs), init = 1) + y_range = (y_max - y_min) * lattice_unit + x_locs_normal = copy(x_locs) + for (k, v) in x_locs_normal + x_locs_normal[k] = v * lattice_unit + end + y_locs_normal = copy(y_locs) + for (k, v) in y_locs_normal + y_locs_normal[k] = v * lattice_unit + end + + st = zxd.st + ps = zxd.ps + + d_spiders = generate_d_spiders(vs, st, ps, x_locs_normal, y_locs_normal) + d_edges = generate_d_edges(zxd) + + spec = @vgplot( + $schema = "https://vega.github.io/schema/vega/v5.json", + height = y_range, + width = x_range, + padding = 0.5 * lattice_unit, + marks = [ + { + encode = { + update = {strokeWidth = {signal = "edgeWidth"}, path = {field = "path"}}, + enter = {stroke = {field = "color"}}, + }, + from = {data = "edges"}, + type = "path", + }, + { + encode = { + update = { + stroke = {value = "black"}, + x = {field = "x"}, + strokeWidth = {signal = "strokeWidth"}, + size = {signal = "spiderSize"}, + y = {field = "y"}, + }, + enter = {shape = {field = "shape"}, fill = {field = "color"}}, + }, + from = {data = "spiders"}, + type = "symbol", + }, + { + encode = { + update = { + align = {value = "center"}, + x = {field = "x"}, + ne = {value = "top"}, + opacity = {signal = "showIds"}, + y = {field = "y"}, + fontSize = {value = 6 * lattice_unit / 50}, + dy = {value = 18 * lattice_unit / 50}, + }, + enter = {fill = {value = "lightgray"}, text = {field = "id"}}, + }, + from = {data = "spiders"}, + type = "text", + }, + { + encode = { + update = { + align = {value = "center"}, + x = {field = "x"}, + dy = {value = lattice_unit / 50}, + baseline = {value = "middle"}, + opacity = {signal = "showPhases"}, + fontSize = {value = 6 * lattice_unit / 50}, + y = {field = "y"}, + }, + enter = {fill = {value = "black"}, text = {field = "phase"}}, + }, + from = {data = "spiders"}, + type = "text", + }, + ], + data = [ + { + name = "spiders", + values = d_spiders, + on = [{ + modify = "whichSymbol", + values = "newLoc && {x: newLoc.x, y: newLoc.y}", + trigger = "newLoc", + }], + transform = [ + { + as = "shape", + expr = "datum.spider_type === 'Z' ? 'circle' : (datum.spider_type === 'X' ? 'circle' : (datum.spider_type === 'H' ? 'square' : 'circle'))", + type = "formula", + }, + { + as = "color", + expr = "datum.spider_type === 'Z' ? '#D8F8D8' : (datum.spider_type === 'X' ? '#E8A5A5' : (datum.spider_type === 'H' ? 'yellow' : '#9558B2'))", + type = "formula", + }, + ], + }, + { + name = "edges", + values = d_edges, + transform = [ + { + key = "id", + fields = ["src", "dst"], + as = ["source", "target"], + from = "spiders", + type = "lookup", + }, + { + targetX = "target.x", + shape = {signal = "shape"}, + sourceX = "source.x", + targetY = "target.y", + type = "linkpath", + sourceY = "source.y", + orient = {signal = "orient"}, + }, + { + as = "color", + expr = "datum.isHadamard ? '#4063D8' : 'black'", + type = "formula", + }, + ], + }, + ], + signals = [ + {name = "showIds", bind = {input = "checkbox"}, value = true}, + {name = "showPhases", bind = {input = "checkbox"}, value = true}, + { + name = "spiderSize", + bind = { + step = lattice_unit / 5, + max = 40 * lattice_unit, + min = 2 * lattice_unit, + input = "range", + }, + value = 20 * lattice_unit, + }, + { + name = "strokeWidth", + bind = { + step = 0.001 * lattice_unit, + max = 3 * lattice_unit / 50, + min = 0, + input = "range", + }, + value = 1.5 * lattice_unit / 50, + }, + { + name = "edgeWidth", + bind = { + step = 0.001 * lattice_unit, + max = 3 * lattice_unit / 50, + min = 0.002 * lattice_unit, + input = "range", + }, + value = 1.5 * lattice_unit / 50, + }, + { + name = "orient", + bind = {options = ["horizontal", "vertical"], input = "select"}, + value = "horizontal", + }, + { + name = "shape", + bind = { + options = ["line", "arc", "curve", "diagonal", "orthogonal"], + input = "select", + }, + value = "diagonal", + }, + { + name = "whichSymbol", + on = [ + {events = "symbol:mousedown", update = "datum"}, + {events = "*:mouseup", update = "{}"}, + ], + value = {}, + }, + { + name = "newLoc", + on = [ + {events = "symbol:mouseout[!event.buttons], window:mouseup", update = "false"}, + {events = "symbol:mouseover", update = "{x: x(), y: y()}"}, + { + events = "[symbol:mousedown, window:mouseup] > window:mousemove!", + update = "{x: x(), y: y()}", + }, + ], + value = false, + }, + ] + ) + return spec +end + + + + + + +end diff --git a/notebooks/demonstration.jl b/notebooks/demonstration.jl new file mode 100644 index 0000000..4738fa8 --- /dev/null +++ b/notebooks/demonstration.jl @@ -0,0 +1,1360 @@ +### A Pluto.jl notebook ### +# v0.19.38 + +using Markdown +using InteractiveUtils + +# ╔═╡ aa11ea12-6a9c-11ee-11b6-77a1fbfdf4b5 +begin + # Extensions + using OpenQASM + using Vega + using DataFrames + + # ZX Calculus Tools + using ZXCalculus, ZXCalculus.ZX + using YaoHIR: BlockIR + + + using PlutoUI + +end + +# ╔═╡ c467fe63-487b-4087-b166-01ed41a47eec +using MLStyle + +# ╔═╡ 6ebebc14-6b0f-48b7-a8e4-fb6f7f9f7f0e +begin + function Base.show(io::IO, mime::MIME"text/html", zx::Union{ZXDiagram,ZXGraph}) + g = ZXCalculus.plot(zx) + Base.show(io, mime, g) + end +end + + +# ╔═╡ 639aaf18-e63b-4b07-8557-8e21a874d91a +begin + b1 = BlockIR(""" + // Benchmark was created by MQT Bench on 2023-06-29 + // For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ + // MQT Bench version: v1.0.0 + // TKET version: 1.16.0 + + OPENQASM 2.0; + include "qelib1.inc"; + + qreg q[107]; + creg c[106]; + h q[0]; + h q[1]; + h q[2]; + h q[3]; + h q[4]; + h q[5]; + h q[6]; + h q[7]; + h q[8]; + h q[9]; + h q[10]; + h q[11]; + h q[12]; + h q[13]; + h q[14]; + h q[15]; + h q[16]; + h q[17]; + h q[18]; + h q[19]; + h q[20]; + h q[21]; + h q[22]; + h q[23]; + h q[24]; + h q[25]; + h q[26]; + h q[27]; + h q[28]; + h q[29]; + h q[30]; + h q[31]; + h q[32]; + h q[33]; + h q[34]; + h q[35]; + h q[36]; + h q[37]; + h q[38]; + h q[39]; + h q[40]; + h q[41]; + h q[42]; + h q[43]; + h q[44]; + h q[45]; + h q[46]; + h q[47]; + h q[48]; + h q[49]; + h q[50]; + h q[51]; + h q[52]; + h q[53]; + h q[54]; + h q[55]; + h q[56]; + h q[57]; + h q[58]; + h q[59]; + h q[60]; + h q[61]; + h q[62]; + h q[63]; + h q[64]; + h q[65]; + h q[66]; + h q[67]; + h q[68]; + h q[69]; + h q[70]; + h q[71]; + h q[72]; + h q[73]; + h q[74]; + h q[75]; + h q[76]; + + h q[105]; + """) + c1 = ZXDiagram(b1) + +end + +# ╔═╡ 69587b8e-26cf-4862-abe6-f81cc6967db3 +b1 + +# ╔═╡ 97eae154-ce25-4f22-b89a-af653f79dcd7 +g1_reduced = full_reduction(c1) + +# ╔═╡ 15e4062a-37b3-40dc-add3-9d8ad7520b4d +c2 = ZXDiagram(BlockIR(""" +// Benchmark was created by MQT Bench on 2023-06-29 +// For more information about MQT Bench, please visit https://www.cda.cit.tum.de/mqtbench/ +// MQT Bench version: v1.0.0 +// TKET version: 1.16.0 + +OPENQASM 2.0; +include "qelib1.inc"; + +qreg q[107]; +creg c[106]; +h q[0]; +h q[1]; +h q[2]; +h q[3]; +h q[4]; +h q[5]; +h q[6]; +h q[7]; +h q[8]; +h q[9]; +h q[10]; +h q[11]; +h q[12]; +h q[13]; +h q[14]; +h q[15]; +h q[16]; +h q[17]; +h q[18]; +h q[19]; +h q[20]; +h q[21]; +h q[22]; +h q[23]; +h q[24]; +h q[25]; +h q[26]; +h q[27]; +h q[28]; +h q[29]; +h q[30]; +h q[31]; +h q[32]; +h q[33]; +h q[34]; +h q[35]; +h q[36]; +h q[37]; +h q[38]; +h q[39]; +h q[40]; +h q[41]; +h q[42]; +h q[43]; +h q[44]; +h q[45]; +h q[46]; +h q[47]; +h q[48]; +h q[49]; +h q[50]; +h q[51]; +h q[52]; +h q[53]; +h q[54]; +h q[55]; +h q[56]; +h q[57]; +h q[58]; +h q[59]; +h q[60]; +h q[61]; +h q[62]; +h q[63]; +h q[64]; +h q[65]; +h q[66]; +h q[67]; +h q[68]; +h q[69]; +h q[70]; +h q[71]; +h q[72]; +h q[73]; +h q[74]; +h q[75]; +h q[76]; +h q[77]; +h q[78]; +h q[79]; +h q[80]; +h q[81]; +h q[82]; +h q[83]; +h q[84]; +h q[85]; +h q[86]; +h q[87]; +h q[88]; +h q[89]; +h q[90]; +h q[91]; +h q[92]; +h q[93]; +h q[94]; +h q[95]; +h q[96]; +h q[97]; +h q[98]; +h q[99]; +h q[100]; +h q[101]; +h q[102]; +h q[103]; +h q[104]; +h q[105]; +x q[106]; +x q[0]; +x q[1]; +x q[3]; +x q[5]; +x q[6]; +x q[8]; +x q[9]; +x q[11]; +x q[12]; +x q[15]; +x q[21]; +x q[24]; +x q[25]; +x q[28]; +x q[31]; +x q[35]; +x q[36]; +x q[38]; +x q[39]; +x q[40]; +x q[41]; +x q[42]; +x q[44]; +x q[49]; +x q[51]; +x q[52]; +x q[53]; +x q[55]; +x q[57]; +x q[58]; +x q[60]; +x q[63]; +x q[67]; +x q[68]; +x q[72]; +x q[74]; +x q[75]; +x q[77]; +x q[78]; +x q[80]; +x q[86]; +x q[88]; +x q[96]; +x q[97]; +x q[99]; +x q[100]; +x q[103]; +h q[106]; +cx q[0],q[106]; +x q[0]; +cx q[1],q[106]; +h q[0]; +x q[1]; +cx q[2],q[106]; +h q[1]; +h q[2]; +cx q[3],q[106]; +x q[3]; +cx q[4],q[106]; +h q[3]; +h q[4]; +cx q[5],q[106]; +x q[5]; +cx q[6],q[106]; +h q[5]; +x q[6]; +cx q[7],q[106]; +h q[6]; +h q[7]; +cx q[8],q[106]; +x q[8]; +cx q[9],q[106]; +h q[8]; +x q[9]; +cx q[10],q[106]; +h q[9]; +h q[10]; +cx q[11],q[106]; +x q[11]; +cx q[12],q[106]; +h q[11]; +x q[12]; +cx q[13],q[106]; +h q[12]; +h q[13]; +cx q[14],q[106]; +h q[14]; +cx q[15],q[106]; +x q[15]; +cx q[16],q[106]; +h q[15]; +h q[16]; +cx q[17],q[106]; +h q[17]; +cx q[18],q[106]; +h q[18]; +cx q[19],q[106]; +h q[19]; +cx q[20],q[106]; +h q[20]; +cx q[21],q[106]; +x q[21]; +cx q[22],q[106]; +h q[21]; +h q[22]; +cx q[23],q[106]; +h q[23]; +cx q[24],q[106]; +x q[24]; +cx q[25],q[106]; +h q[24]; +x q[25]; +cx q[26],q[106]; +h q[25]; +h q[26]; +cx q[27],q[106]; +h q[27]; +cx q[28],q[106]; +x q[28]; +cx q[29],q[106]; +h q[28]; +h q[29]; +cx q[30],q[106]; +h q[30]; +cx q[31],q[106]; +x q[31]; +cx q[32],q[106]; +h q[31]; +h q[32]; +cx q[33],q[106]; +h q[33]; +cx q[34],q[106]; +h q[34]; +cx q[35],q[106]; +x q[35]; +cx q[36],q[106]; +h q[35]; +x q[36]; +cx q[37],q[106]; +h q[36]; +h q[37]; +cx q[38],q[106]; +x q[38]; +cx q[39],q[106]; +h q[38]; +x q[39]; +cx q[40],q[106]; +h q[39]; +x q[40]; +cx q[41],q[106]; +h q[40]; +x q[41]; +cx q[42],q[106]; +h q[41]; +x q[42]; +cx q[43],q[106]; +h q[42]; +h q[43]; +cx q[44],q[106]; +x q[44]; +cx q[45],q[106]; +h q[44]; +h q[45]; +cx q[46],q[106]; +h q[46]; +cx q[47],q[106]; +h q[47]; +cx q[48],q[106]; +h q[48]; +cx q[49],q[106]; +x q[49]; +cx q[50],q[106]; +h q[49]; +h q[50]; +cx q[51],q[106]; +x q[51]; +cx q[52],q[106]; +h q[51]; +x q[52]; +cx q[53],q[106]; +h q[52]; +x q[53]; +cx q[54],q[106]; +h q[53]; +h q[54]; +cx q[55],q[106]; +x q[55]; +cx q[56],q[106]; +h q[55]; +h q[56]; +cx q[57],q[106]; +x q[57]; +cx q[58],q[106]; +h q[57]; +x q[58]; +cx q[59],q[106]; +h q[58]; +h q[59]; +cx q[60],q[106]; +x q[60]; +cx q[61],q[106]; +h q[60]; +h q[61]; +cx q[62],q[106]; +h q[62]; +cx q[63],q[106]; +x q[63]; +cx q[64],q[106]; +h q[63]; +h q[64]; +cx q[65],q[106]; +h q[65]; +cx q[66],q[106]; +h q[66]; +cx q[67],q[106]; +x q[67]; +cx q[68],q[106]; +h q[67]; +x q[68]; +cx q[69],q[106]; +h q[68]; +h q[69]; +cx q[70],q[106]; +h q[70]; +cx q[71],q[106]; +h q[71]; +cx q[72],q[106]; +x q[72]; +cx q[73],q[106]; +h q[72]; +h q[73]; +cx q[74],q[106]; +x q[74]; +cx q[75],q[106]; +h q[74]; +x q[75]; +cx q[76],q[106]; +h q[75]; +h q[76]; +cx q[77],q[106]; +x q[77]; +cx q[78],q[106]; +h q[77]; +x q[78]; +cx q[79],q[106]; +h q[78]; +h q[79]; +cx q[80],q[106]; +x q[80]; +cx q[81],q[106]; +h q[80]; +h q[81]; +cx q[82],q[106]; +h q[82]; +cx q[83],q[106]; +h q[83]; +cx q[84],q[106]; +h q[84]; +cx q[85],q[106]; +h q[85]; +cx q[86],q[106]; +x q[86]; +cx q[87],q[106]; +h q[86]; +h q[87]; +cx q[88],q[106]; +x q[88]; +cx q[89],q[106]; +h q[88]; +h q[89]; +cx q[90],q[106]; +h q[90]; +cx q[91],q[106]; +h q[91]; +cx q[92],q[106]; +h q[92]; +cx q[93],q[106]; +h q[93]; +cx q[94],q[106]; +h q[94]; +cx q[95],q[106]; +h q[95]; +cx q[96],q[106]; +x q[96]; +cx q[97],q[106]; +h q[96]; +x q[97]; +cx q[98],q[106]; +h q[97]; +h q[98]; +cx q[99],q[106]; +x q[99]; +cx q[100],q[106]; +h q[99]; +x q[100]; +cx q[101],q[106]; +h q[100]; +h q[101]; +cx q[102],q[106]; +h q[102]; +cx q[103],q[106]; +x q[103]; +cx q[104],q[106]; +h q[103]; +h q[104]; +cx q[105],q[106]; +h q[105]; + """)) + + +# ╔═╡ e22922f8-5a54-475b-b325-dda82547c556 + + +# ╔═╡ 37954f01-da8c-4018-a7e1-811d4a86fb26 +c2_inv = dagger(c2) + +# ╔═╡ c984b469-89d0-4d02-9264-e967697e50b3 +g2_reduced = full_reduction(c2) + +# ╔═╡ 996a236f-90b5-42bb-8627-19d5a7facef6 +m_2 = concat!(c1, dagger(c2)) + +# ╔═╡ df136e09-4958-433d-a3ce-60f73a10968a +verify_equality(c1, c2) + +# ╔═╡ 69d97139-73d2-4b3f-8d1f-aa8437880754 +m = concat!(c1, c2_inv) + +# ╔═╡ 57c4c6eb-54e1-4412-b3ca-3bd7588e4e34 +full_reduction(m) + +# ╔═╡ a092392c-eff5-4c5a-be9b-c9e67881cf46 +verify_equality(c1, c2) + +# ╔═╡ a6819a4e-3029-4fec-9baa-8ec842755e49 +contains_only_bare_wires(m) + +# ╔═╡ d9da3492-048d-4458-aa37-801e84b61ec7 +typeof(c2.st[3]) + +# ╔═╡ d65ab9bd-6dcc-4502-a8fb-301abf404856 +vs = spider_sequence(c2) + +# ╔═╡ 27b7b121-0c13-49ed-97e6-c73386e844a0 +st = SpiderType.Z + +# ╔═╡ ed656d2d-c4af-45a3-a5d8-5fd8c1cccac8 +st + +# ╔═╡ 1b36a6ba-5498-4aa5-ab67-67dff42c8422 +st == SpiderType.Z || st == SpiderType.Z || st == SpiderType.H + +# ╔═╡ ab841776-6b79-4662-9998-04f513370fee +Int(SpiderType.X) + +# ╔═╡ 4ff2d0e2-9dda-405d-aa77-9abb70eace77 +SpiderType.H == SpiderType.Out + +# ╔═╡ 7bec3f25-507a-42e8-8547-cae8bfc317d8 +dj3 = ZXDiagram(BlockIR(""" +OPENQASM 2.0; +include "qelib1.inc"; + +qreg q[3]; +creg c[2]; +h q[0]; +h q[1]; +x q[2]; +x q[0]; +x q[1]; +h q[2]; +cx q[0],q[2]; +x q[0]; +cx q[1],q[2]; +h q[0]; +x q[1]; +h q[1]; +""")) + +# ╔═╡ f3235791-4582-44a3-ba68-6c39a0d0b26b +verify_equality(dj3, dj3) + +# ╔═╡ 7220947a-f153-4bb7-a0ba-972af51d3fe7 +dj_m = concat!(copy(dj3), dagger(dj3)) + +# ╔═╡ 3f98b870-a534-4f69-b460-64c59cd8ef96 +dj3_reduced = full_reduction(dj_m) + +# ╔═╡ dd5c40da-0530-4975-8245-78538ad6d244 +replace!(Rule{:id}(), dj3_reduced) + + +# ╔═╡ a48d68b5-559a-4937-a2b7-c13e5f5181b0 +show(dj3_reduced) + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078" +OpenQASM = "a8821629-a4c0-4df7-9e00-12969ff383a7" +PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +Vega = "239c3e63-733f-47ad-beb7-a12fde22c578" +YaoHIR = "6769671a-fce8-4286-b3f7-6099e1b1298a" +ZXCalculus = "3525faa3-032d-4235-a8d4-8c2939a218dd" + +[compat] +DataFrames = "~1.6.1" +MLStyle = "~0.4.17" +OpenQASM = "~2.1.4" +PlutoUI = "~0.7.55" +Vega = "~2.6.2" +YaoHIR = "~0.2.2" +ZXCalculus = "~0.6.0" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.0" +manifest_format = "2.0" +project_hash = "dc2131f03a0dd356c9b167032d6d5c79ba566e98" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "c278dfab760520b8bb7e9511b968bf4ba38b7acc" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.2.3" + +[[deps.AbstractTrees]] +git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.4" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "62e51b39331de8911e4a7ff6f5aaf38a5f4cc0ae" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.2.0" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BatchedRoutines]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "441db9f0399bcfb4eeb8b891a6b03f7acc5dc731" +uuid = "a9ab73d0-e05c-5df1-8fde-d6a4645b8d8e" +version = "0.2.2" + +[[deps.BetterExp]] +git-tree-sha1 = "dd3448f3d5b2664db7eceeec5f744535ce6e759b" +uuid = "7cffe744-45fd-4178-b173-cf893948b8b7" +version = "0.1.0" + +[[deps.BufferedStreams]] +git-tree-sha1 = "4ae47f9a4b1dc19897d3743ff13685925c5202ec" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.2.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "ad25e7d21ce10e01de973cdc68ad0f850a953c52" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.21.1" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.4" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.12.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.0.5+1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.4" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "ac67408d9ddf207de5cfa9a97e114352430f01ed" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.16" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.DataValues]] +deps = ["DataValueInterfaces", "Dates"] +git-tree-sha1 = "d88a19299eba280a6d062e135a43f00323ae70bf" +uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" +version = "0.4.13" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.Expronicon]] +deps = ["MLStyle"] +git-tree-sha1 = "d64373d3c6ca8605baf3f8569e92c0564c17479b" +uuid = "6b7a57c9-7cc1-4fdf-b7f5-e857abae3636" +version = "0.10.5" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.2" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "899050ace26649433ef1af25bc17a815b3db52b7" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.9.0" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "8b72179abc660bfab5e28472e019392b97d0985c" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.4" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JSONSchema]] +deps = ["Downloads", "JSON", "JSON3", "URIs"] +git-tree-sha1 = "5f0bd0cd69df978fa64ccdcb5c152fbc705455a1" +uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692" +version = "1.3.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.MIMEs]] +git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "0.1.4" + +[[deps.MLStyle]] +git-tree-sha1 = "bc38dff0548128765760c79eb7388a4b37fae2c8" +uuid = "d8e11817-5142-5d16-987a-aa16d5891078" +version = "0.4.17" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multigraphs]] +deps = ["Graphs", "LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "055a7c49a626e17a8c99bcaaf472d0de60848929" +uuid = "7ebac608-6c66-46e6-9856-b5f43e107bac" +version = "0.3.0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.NodeJS]] +deps = ["Pkg"] +git-tree-sha1 = "bf1f49fd62754064bc42490a8ddc2aa3694a8e7a" +uuid = "2bd173c7-0d6d-553b-b6af-13a54713934c" +version = "2.0.0" + +[[deps.OMEinsum]] +deps = ["AbstractTrees", "BatchedRoutines", "ChainRulesCore", "Combinatorics", "LinearAlgebra", "MacroTools", "OMEinsumContractionOrders", "Test", "TupleTools"] +git-tree-sha1 = "3b7f8f3ffb63e3c7fd0d9b364862a2e35f70478e" +uuid = "ebe7aa44-baf0-506c-a96f-8464559b3922" +version = "0.7.6" + + [deps.OMEinsum.extensions] + CUDAExt = "CUDA" + + [deps.OMEinsum.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.OMEinsumContractionOrders]] +deps = ["AbstractTrees", "BetterExp", "JSON", "SparseArrays", "Suppressor"] +git-tree-sha1 = "b0cba9f4a6f021a63b066f0bb29a6fd63c93be44" +uuid = "6f22d1fd-8eed-4bb7-9776-e7d684900715" +version = "0.8.3" + + [deps.OMEinsumContractionOrders.extensions] + KaHyParExt = ["KaHyPar"] + + [deps.OMEinsumContractionOrders.weakdeps] + KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+2" + +[[deps.OpenQASM]] +deps = ["MLStyle", "RBNF"] +git-tree-sha1 = "aa6c47be6512e3299d9e56224d13d6a2303e3d6e" +uuid = "a8821629-a4c0-4df7-9e00-12969ff383a7" +version = "2.1.4" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "68723afdb616445c6caaef6255067a8339f91325" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.55" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.0" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.1" + +[[deps.PrettyPrint]] +git-tree-sha1 = "632eb4abab3449ab30c5e1afaa874f0b98b586e4" +uuid = "8162dcfd-2161-5ef2-ae6c-7681170c5f98" +version = "0.2.0" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.RBNF]] +deps = ["DataStructures", "MLStyle", "PrettyPrint"] +git-tree-sha1 = "c7da51b46fb5d206ffe19f7c2e86d1cae7bd7fd5" +uuid = "83ef0002-5b9e-11e9-219b-65bac3c6d69c" +version = "0.2.3" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "7b0e9c14c624e435076d19aea1e5cbdec2b9ca37" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.2" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.Suppressor]] +deps = ["Logging"] +git-tree-sha1 = "6cd9e4a207964c07bf6395beff7a1e8f21d0f3b2" +uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb" +version = "0.2.6" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.TableTraitsUtils]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits"] +git-tree-sha1 = "78fecfe140d7abb480b53a44f3f85b6aa373c293" +uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" +version = "1.0.2" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Tricks]] +git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.8" + +[[deps.TupleTools]] +git-tree-sha1 = "155515ed4c4236db30049ac1495e2969cc06be9d" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.4.3" + +[[deps.URIParser]] +deps = ["Unicode"] +git-tree-sha1 = "53a9f49546b8d2dd2e688d216421d050c9a31d0d" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.1" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.Vega]] +deps = ["BufferedStreams", "DataStructures", "DataValues", "Dates", "FileIO", "FilePaths", "IteratorInterfaceExtensions", "JSON", "JSONSchema", "MacroTools", "NodeJS", "Pkg", "REPL", "Random", "Setfield", "TableTraits", "TableTraitsUtils", "URIParser"] +git-tree-sha1 = "9d5c73642d291cb5aa34eb47b9d71428c4132398" +uuid = "239c3e63-733f-47ad-beb7-a12fde22c578" +version = "2.6.2" + +[[deps.YaoHIR]] +deps = ["Expronicon", "MLStyle", "YaoLocations"] +git-tree-sha1 = "7fa66adcb137e2b3025642b758ce612d2d8ff1fa" +uuid = "6769671a-fce8-4286-b3f7-6099e1b1298a" +version = "0.2.2" + +[[deps.YaoLocations]] +git-tree-sha1 = "c90c42c8668c9096deb0c861822f0f8f80cbdc68" +uuid = "66df03fb-d475-48f7-b449-3d9064bf085b" +version = "0.1.6" + +[[deps.ZXCalculus]] +deps = ["Expronicon", "Graphs", "LinearAlgebra", "MLStyle", "Multigraphs", "OMEinsum", "SparseArrays", "YaoHIR", "YaoLocations"] +git-tree-sha1 = "9110975b06644a0844c98e13944c00af26087bf4" +uuid = "3525faa3-032d-4235-a8d4-8c2939a218dd" +version = "0.6.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" +""" + +# ╔═╡ Cell order: +# ╠═aa11ea12-6a9c-11ee-11b6-77a1fbfdf4b5 +# ╟─6ebebc14-6b0f-48b7-a8e4-fb6f7f9f7f0e +# ╠═639aaf18-e63b-4b07-8557-8e21a874d91a +# ╠═69587b8e-26cf-4862-abe6-f81cc6967db3 +# ╠═97eae154-ce25-4f22-b89a-af653f79dcd7 +# ╠═15e4062a-37b3-40dc-add3-9d8ad7520b4d +# ╠═e22922f8-5a54-475b-b325-dda82547c556 +# ╟─37954f01-da8c-4018-a7e1-811d4a86fb26 +# ╠═c984b469-89d0-4d02-9264-e967697e50b3 +# ╠═996a236f-90b5-42bb-8627-19d5a7facef6 +# ╠═df136e09-4958-433d-a3ce-60f73a10968a +# ╠═69d97139-73d2-4b3f-8d1f-aa8437880754 +# ╠═57c4c6eb-54e1-4412-b3ca-3bd7588e4e34 +# ╠═a092392c-eff5-4c5a-be9b-c9e67881cf46 +# ╠═a6819a4e-3029-4fec-9baa-8ec842755e49 +# ╠═d9da3492-048d-4458-aa37-801e84b61ec7 +# ╠═d65ab9bd-6dcc-4502-a8fb-301abf404856 +# ╠═c467fe63-487b-4087-b166-01ed41a47eec +# ╠═27b7b121-0c13-49ed-97e6-c73386e844a0 +# ╠═ed656d2d-c4af-45a3-a5d8-5fd8c1cccac8 +# ╠═1b36a6ba-5498-4aa5-ab67-67dff42c8422 +# ╠═ab841776-6b79-4662-9998-04f513370fee +# ╠═4ff2d0e2-9dda-405d-aa77-9abb70eace77 +# ╠═7bec3f25-507a-42e8-8547-cae8bfc317d8 +# ╠═f3235791-4582-44a3-ba68-6c39a0d0b26b +# ╠═7220947a-f153-4bb7-a0ba-972af51d3fe7 +# ╠═3f98b870-a534-4f69-b460-64c59cd8ef96 +# ╠═dd5c40da-0530-4975-8245-78538ad6d244 +# ╠═a48d68b5-559a-4937-a2b7-c13e5f5181b0 +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/notebooks/research.jl b/notebooks/research.jl new file mode 100644 index 0000000..708bc7b --- /dev/null +++ b/notebooks/research.jl @@ -0,0 +1,1135 @@ +### A Pluto.jl notebook ### +# v0.19.43 + +using Markdown +using InteractiveUtils + +# ╔═╡ dd08aa73-0d86-4f8b-970b-59f9ad9fac2d +begin + # Used for creating the IRCode for a BlockIR + using Core.Compiler: IRCode + + # Pluto + using PlutoUI + + # Weak Dependencies + using Vega + using OpenQASM + using DataFrames + using YaoHIR + using YaoLocations + using YaoHIR: BlockIR + using YaoHIR.IntrinsicOperation + using ZXCalculus, ZXCalculus.ZX, ZXCalculus.ZXW + using DynamicQuantumCircuits + +end + +# ╔═╡ 506db9e1-4260-408d-ba72-51581b548e53 +function Base.show(io::IO, mime::MIME"text/html", zx::Union{ZXDiagram,ZXGraph}) + g = plot(zx) + Base.show(io, mime, g) +end + + +# ╔═╡ db7e9cf8-9abf-448b-be68-43231853faff +md""" + + +## Equivalence Checking of Quantum Circuits +### Principle of Quantum Circuit Equality +#### Reversiblity +Equivalence checking the equality of two quantum circuits relies on the reversibility +of quantum operations. Every quantum operation is *unitary* and thus reversible. The product of any quantum operation and its inverse (adjoint) +will always yield the identity. + + +#### Unitary +For a matrix to be unitary, this property needs to hold: +`` U \cdot U^\dagger = U^\dagger \cdot U = I_n | U \in \mathbb{R}^{n \times n} `` + +If ``U_1`` and ``U_2`` are unitary matrices, so is their matrix product ``U_1 \cdot U_2``. +Unitary matrices preserve inner products. Thus, if ``U`` is unitary, then for all ``V , V′ \in \mathbb{C}^n`` we have: +``⟨U V |U V ′ ⟩ = ⟨U |V ′ ⟩`` + +### Equality +In order to verify the equality of two quantum circuits we exploit their reversibility. + +Given two quantum circuits ``G_1`` and ``G_2`` as well the systems matrices ``U_1`` and ``U_1`` that describe the operations of these quantum circuits we ask ourself, the problem of equivalence checking is to verify if there is no difference ``D = U_1 \cdot U_2^\dagger`` between the first and second quantum circuit. + +To verify if the two quantum circuits are equal we check if ``tr(D) = 0``, as this implies that the difference is the idenity matrix. + ``U_1 \cdot U_2^\dagger = D````U_1 \cdot U_2^\dagger = D = I``. + +If the two quantum circuits are not equal, ``U_1 \cdot U_2^\dagger = D != I``, the +problem is to +- approximate how close the quantum circuits are +- debug the quantum circuits, in order to reduce the difference `D` between them. + + + +## ZX Calculus Diagram +### Introduction +ZX-Calculus is a unified formalism for describing quantum computation, mainly over +qubits. It is a rigorous graphical language, that utilizes the powerful set of rewrite +rules for reasoning about linear maps between qubits, which are represented as string diagrams called ZX-Diagrams. + +#### Example +Of three CNOT Gats that are equal to a SWAP Gate + +""" + + + + +# ╔═╡ c06c5b9f-e5c1-4d0c-8ed5-937ad3871d3d +begin + zx1 = ZXDiagram(2) + push_gate!(zx1, Val(:CNOT), 1, 2) + push_gate!(zx1, Val(:CNOT), 2, 1) + push_gate!(zx1, Val(:CNOT), 1, 2) + +end + +# ╔═╡ 5e0fb39e-68b3-45f6-8cb2-2dd0b79b35d4 +md""" +### Applications +ZX-Calculus has been successfully applied to +- quantum circuit compilationoptimization and equivalence checking. + +ZX-Calculus is a generaliation of Quantum Computing. It is complete, meaning that all equations concerning quantum processes can be derived using linear algebra, can also be obtained using a handful of graphical rules. + + +### Example Bernstein-Vazirani ZX-Diagram +""" + +# ╔═╡ 587be022-6005-44d5-bb72-53cc9e3ba3bb +bv_101_static = ZXDiagram(BlockIR(""" +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[4]; +creg c[3]; +x q[3]; +h q[0]; +h q[1]; +h q[2]; +h q[3]; +CX q[0],q[3]; +CX q[2],q[3]; +h q[0]; +h q[1]; +h q[2]; +measure q[0] -> c[0]; +measure q[1] -> c[1]; +measure q[2] -> c[2]; +""")) + +# ╔═╡ 482fdb57-2b0b-44b9-a5a0-f4dc26e15a7d +bv_101_dynamic = ZXDiagram(BlockIR(unitary_reconstruction(OpenQASM.parse(""" +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[2]; +creg c[3]; +x q[1]; +h q[0]; +h q[1]; +CX q[0],q[1]; +h q[0]; +measure q[0] -> c[0]; +reset q[0]; +h q[0]; +h q[0]; +measure q[0] -> c[1]; +reset q[0]; +h q[0]; +CX q[0],q[1]; +h q[0]; +measure q[0] -> c[2]; +""")))) + +# ╔═╡ 57301b22-969f-481e-ae0b-0336e1ee5055 +md""" +## Logic Verification of Quantum Circuits +### Informal Definition of Quantum Circuit Equality +> Two circuits are equivalent if they produce the same output for every possible input +`` U_1 \cdot U_2 = I `` + +""" + +# ╔═╡ a8470d1a-8dc1-4a86-85b9-efd1836cf42c +verify_equality(bv_101_dynamic, bv_101_static) + +# ╔═╡ 6e823d50-9107-4488-897e-d647334573f9 +md""" +What happens if we add an extra Z gate to the first qubit? +""" + +# ╔═╡ e3aa4e99-cb1f-478b-9e80-82b0ab02f606 +begin + push_gate!(bv_101_static, Val(:X), 1, 1 // 1) + verify_equality(bv_101_dynamic, bv_101_static) +end + +# ╔═╡ a44ef98a-61fb-4271-9d36-c4d096f7e600 +md""" +## Differenciation of ZX-Calculus +""" + +# ╔═╡ fb2448ef-aebe-419f-ad1d-a161edacd5a0 +md""" +### Difference of two quantum circuits +Approximation equality of ZX-Diagrams using algebraic ZX-Calculus + +""" + +# ╔═╡ 38da72a7-7e81-426f-ba08-b4158dc6a011 +bv_101_difference = full_reduction(concat!(ZXDiagram(BlockIR(unitary_reconstruction(OpenQASM.parse(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[3]; + x q[1]; + h q[0]; + h q[1]; + CX q[0],q[1]; + h q[0]; + measure q[0] -> c[0]; + reset q[0]; + h q[0]; + h q[0]; + measure q[0] -> c[1]; + reset q[0]; + h q[0]; + CX q[0],q[1]; + h q[0]; + measure q[0] -> c[2]; + """)))), dagger(ZXDiagram(BlockIR(unitary_reconstruction(OpenQASM.parse(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q[2]; + creg c[3]; + x q[1]; + h q[0]; + h q[1]; + CX q[0],q[1]; + h q[0]; + measure q[0] -> c[0]; + reset q[0]; + h q[0]; + h q[0]; + measure q[0] -> c[1]; + reset q[0]; + h q[0]; + CX q[0],q[1]; + h q[0]; + x q[0]; + measure q[0] -> c[2]; + """))))))) + +# ╔═╡ 742750be-1262-4cbe-b476-f62e5e5c1fcf +bir = circuit_extraction(bv_101_difference) + +# ╔═╡ 686cfe18-598b-4184-8a6d-85711109b055 +ZXW.convert_to_zxwd(BlockIR(IRCode(), 4, bir)) + +# ╔═╡ 9af85660-a4e3-4f27-b6cb-cf36d9b50d91 +z1 = ZXDiagram(1) + + +# ╔═╡ 785ec008-63af-4f56-9792-f66b27a27388 +md""" +Add a green spider +""" + +# ╔═╡ 44cbd3d8-6d36-4a0b-8613-552bbba48f3d +begin + zx_z = ZXDiagram(1) + push_gate!(zx_z, Val(:Z), 1) +end + +# ╔═╡ 0c2b4e33-5dcc-476d-8a9c-1e4244231e05 +begin + zx_x = ZXDiagram(1) + push_gate!(zx_x, Val(:X), 1, 1 // 1) +end + + +# ╔═╡ eebd1e46-0c0f-487d-8bee-07b1c17552c4 +begin + zx_s = ZXDiagram(1) + push_gate!(zx_s, Val(:Z), 1, 1 // 2) +end + + + + +# ╔═╡ 9200a1b1-11f7-4428-8840-c52dd4403c45 +begin + zx_t = ZXDiagram(1) + push_gate!(zx_t, Val(:Z), 1, 1 // 4) +end + + + + +# ╔═╡ 924efc08-681b-4804-93c6-38acc125315a +begin + zx_h = ZXDiagram(1) + push_gate!(zx_h, Val(:H), 1) +end + + + + +# ╔═╡ 5fdc6a08-c284-414e-9e96-8734289a98de +begin + zx_cnot = ZXDiagram(2) + push_gate!(zx_cnot, Val(:CNOT), 1, 2) + +end + +# ╔═╡ 0523c034-06ac-4383-b50f-6b68e6b1739f +begin + zx = ZXDiagram(3) + push_gate!(zx, Val(:X), 1, 1 // 1) + push_gate!(zx, Val(:CNOT), 1, 2) + push_gate!(zx, Val(:H), 1) + push_gate!(zx, Val(:CNOT), 2, 3) + push_gate!(zx, Val(:H), 2) +end + + +# ╔═╡ 4d7d8a96-5aba-4b63-a5da-959716f2d2bf +md"## Converting ZXDiagrams into ZXGraphs" + +# ╔═╡ 7da637f0-e359-41d9-b395-27168459c20c +zx_graph = ZXGraph(zx) + +# ╔═╡ bed7a0c5-da16-40b5-9d84-4dad2dfb8739 +begin + zx_id = ZXDiagram(2) + push_gate!(zx_id, Val(:X), 1) + push_gate!(zx_id, Val(:X), 1) +end + + +# ╔═╡ 8cde99fd-ee0a-4d94-a94e-23ebc9ac8608 +zx_id_graph = ZXGraph(zx_id) + +# ╔═╡ 17389edf-33d2-4dd8-bf86-df0467e65059 +full_reduction(zx_id) + +# ╔═╡ 99bb5eff-79e7-4c0e-95ae-a6d2130f46cb +md"Equality" + +# ╔═╡ f240382f-b682-4947-938f-c98d9c901c90 +zx_dagger = dagger(zx) + +# ╔═╡ 89f14c32-895d-4101-b4a8-bc410a2adaa5 +concat!(zx, zx_dagger) + +# ╔═╡ 0b838710-91e4-4572-9fe0-5c97e579ddd1 +m_simple = full_reduction(zx) + + +# ╔═╡ fdb7ca6a-bf5c-4216-8a18-a7c3603240ea +contains_only_bare_wires(m_simple) + +# ╔═╡ 6da61df3-b6e7-4991-ab9f-5994b55841e0 +full_reduction(zx) + +# ╔═╡ 6b431ff3-f644-4123-82fd-704c054eb5bb +md"DQC Example" + +# ╔═╡ cee877f2-8fd8-4a4e-9b8c-199411d449c5 +begin + traditional = """ + OPENQASM 2.0; + include "qelib1.inc"; + qreg q0[3]; + creg c0[2]; + h q0[0]; + h q0[1]; + x q0[2]; + h q0[2]; + CX q0[0],q0[2]; + h q0[0]; + CX q0[1],q0[2]; + h q0[1]; + measure q0[0] -> c0[0]; + measure q0[1] -> c0[1]; + """ + c1 = ZXDiagram(BlockIR(traditional)) +end + +# ╔═╡ 20886e57-0c2c-4bf3-8c3d-8ed7d4f33fec +begin + dynamic = OpenQASM.parse(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q0[2]; + creg mcm[1]; + creg end[1]; + h q0[0]; + x q0[1]; + h q0[1]; + CX q0[0],q0[1]; + h q0[0]; + measure q0[0] -> mcm[0]; + reset q0[0]; + h q0[0]; + CX q0[0],q0[1]; + h q0[0]; + measure q0[0] -> end[0]; + """) + unitary = unitary_reconstruction(dynamic) + c2 = ZXDiagram(BlockIR(unitary)) + + +end + +# ╔═╡ 9b838e52-79f6-49bd-9574-62d94f941558 +c2_dagger = dagger(c2) + + +# ╔═╡ 91ea0d20-8f8b-4bec-a98d-6aebbc4228e1 +dqc_merged = concat!(c1, c2_dagger) + +# ╔═╡ fbbe52e6-40d0-48ab-aa92-58a5125a33b2 +reduced = full_reduction(concat!(ZXDiagram(BlockIR(traditional)), dagger(ZXDiagram(BlockIR(unitary))))) + +# ╔═╡ f7982574-ddff-4e7b-a4fc-52462a59d21c +contains_only_bare_wires(reduced) + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +OpenQASM = "a8821629-a4c0-4df7-9e00-12969ff383a7" +PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +Vega = "239c3e63-733f-47ad-beb7-a12fde22c578" +YaoHIR = "6769671a-fce8-4286-b3f7-6099e1b1298a" +YaoLocations = "66df03fb-d475-48f7-b449-3d9064bf085b" +ZXCalculus = "3525faa3-032d-4235-a8d4-8c2939a218dd" + +[compat] +DataFrames = "~1.6.1" +OpenQASM = "~2.1.4" +PlutoUI = "~0.7.59" +Vega = "~2.7.0" +YaoHIR = "~0.2.3" +YaoLocations = "~0.1.6" +ZXCalculus = "~0.6.0" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.4" +manifest_format = "2.0" +project_hash = "e6f4606be1811753c50082763b6d71d5d123551f" + +[[deps.AbstractPlutoDingetjes]] +deps = ["Pkg"] +git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" +uuid = "6e696c72-6542-2067-7265-42206c756150" +version = "1.3.2" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BatchedRoutines]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "441db9f0399bcfb4eeb8b891a6b03f7acc5dc731" +uuid = "a9ab73d0-e05c-5df1-8fde-d6a4645b8d8e" +version = "0.2.2" + +[[deps.BetterExp]] +git-tree-sha1 = "dd3448f3d5b2664db7eceeec5f744535ce6e759b" +uuid = "7cffe744-45fd-4178-b173-cf893948b8b7" +version = "0.1.0" + +[[deps.BufferedStreams]] +git-tree-sha1 = "4ae47f9a4b1dc19897d3743ff13685925c5202ec" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.2.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.24.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.15.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.1+0" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + + [deps.ConstructionBase.weakdeps] + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.20" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.DataValues]] +deps = ["DataValueInterfaces", "Dates"] +git-tree-sha1 = "d88a19299eba280a6d062e135a43f00323ae70bf" +uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5" +version = "0.4.13" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.Expronicon]] +deps = ["MLStyle"] +git-tree-sha1 = "35141514242193e3e820d90007f973bf35bf5da0" +uuid = "6b7a57c9-7cc1-4fdf-b7f5-e857abae3636" +version = "0.10.10" + +[[deps.FileIO]] +deps = ["Pkg", "Requires", "UUIDs"] +git-tree-sha1 = "82d8afa92ecf4b52d78d869f038ebfb881267322" +uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" +version = "1.16.3" + +[[deps.FilePaths]] +deps = ["FilePathsBase", "MacroTools", "Reexport", "Requires"] +git-tree-sha1 = "919d9412dbf53a2e6fe74af62a73ceed0bce0629" +uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" +version = "0.8.3" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "ebd18c326fa6cee1efb7da9a3b45cf69da2ed4d9" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.11.2" + +[[deps.Hyperscript]] +deps = ["Test"] +git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" +uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" +version = "0.0.5" + +[[deps.HypertextLiteral]] +deps = ["Tricks"] +git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" +uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" +version = "0.9.5" + +[[deps.IOCapture]] +deps = ["Logging", "Random"] +git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" +uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" +version = "0.2.5" + +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "86356004f30f8e737eff143d57d41bd580e437aa" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.1" + + [deps.InlineStrings.extensions] + ArrowTypesExt = "ArrowTypes" + + [deps.InlineStrings.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JSON3]] +deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] +git-tree-sha1 = "eb3edce0ed4fa32f75a0a11217433c31d56bd48b" +uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" +version = "1.14.0" + + [deps.JSON3.extensions] + JSON3ArrowExt = ["ArrowTypes"] + + [deps.JSON3.weakdeps] + ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" + +[[deps.JSONSchema]] +deps = ["Downloads", "JSON", "JSON3", "URIs"] +git-tree-sha1 = "5f0bd0cd69df978fa64ccdcb5c152fbc705455a1" +uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692" +version = "1.3.0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.MIMEs]] +git-tree-sha1 = "65f28ad4b594aebe22157d6fac869786a255b7eb" +uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +version = "0.1.4" + +[[deps.MLStyle]] +git-tree-sha1 = "bc38dff0548128765760c79eb7388a4b37fae2c8" +uuid = "d8e11817-5142-5d16-987a-aa16d5891078" +version = "0.4.17" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.Multigraphs]] +deps = ["Graphs", "LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "055a7c49a626e17a8c99bcaaf472d0de60848929" +uuid = "7ebac608-6c66-46e6-9856-b5f43e107bac" +version = "0.3.0" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.NodeJS]] +deps = ["Pkg"] +git-tree-sha1 = "bf1f49fd62754064bc42490a8ddc2aa3694a8e7a" +uuid = "2bd173c7-0d6d-553b-b6af-13a54713934c" +version = "2.0.0" + +[[deps.OMEinsum]] +deps = ["AbstractTrees", "BatchedRoutines", "ChainRulesCore", "Combinatorics", "LinearAlgebra", "MacroTools", "OMEinsumContractionOrders", "Test", "TupleTools"] +git-tree-sha1 = "3b7f8f3ffb63e3c7fd0d9b364862a2e35f70478e" +uuid = "ebe7aa44-baf0-506c-a96f-8464559b3922" +version = "0.7.6" + + [deps.OMEinsum.extensions] + CUDAExt = "CUDA" + + [deps.OMEinsum.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + +[[deps.OMEinsumContractionOrders]] +deps = ["AbstractTrees", "BetterExp", "JSON", "SparseArrays", "Suppressor"] +git-tree-sha1 = "b0cba9f4a6f021a63b066f0bb29a6fd63c93be44" +uuid = "6f22d1fd-8eed-4bb7-9776-e7d684900715" +version = "0.8.3" + + [deps.OMEinsumContractionOrders.extensions] + KaHyParExt = ["KaHyPar"] + + [deps.OMEinsumContractionOrders.weakdeps] + KaHyPar = "2a6221f6-aa48-11e9-3542-2d9e0ef01880" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenQASM]] +deps = ["MLStyle", "RBNF"] +git-tree-sha1 = "aa6c47be6512e3299d9e56224d13d6a2303e3d6e" +uuid = "a8821629-a4c0-4df7-9e00-12969ff383a7" +version = "2.1.4" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PlutoUI]] +deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] +git-tree-sha1 = "ab55ee1510ad2af0ff674dbcced5e94921f867a9" +uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" +version = "0.7.59" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.PrettyPrint]] +git-tree-sha1 = "632eb4abab3449ab30c5e1afaa874f0b98b586e4" +uuid = "8162dcfd-2161-5ef2-ae6c-7681170c5f98" +version = "0.2.0" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "66b20dd35966a748321d3b2537c4584cf40387c7" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.2" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.RBNF]] +deps = ["DataStructures", "MLStyle", "PrettyPrint"] +git-tree-sha1 = "12c19821099177fad12336af5e3d0ca8f41eb3d3" +uuid = "83ef0002-5b9e-11e9-219b-65bac3c6d69c" +version = "0.2.4" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "ff11acffdb082493657550959d4feb4b6149e73a" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.5" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "eeafab08ae20c62c44c8399ccb9354a04b80db50" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.7" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.3" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.StructTypes]] +deps = ["Dates", "UUIDs"] +git-tree-sha1 = "ca4bccb03acf9faaf4137a9abc1881ed1841aa70" +uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" +version = "1.10.0" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.Suppressor]] +deps = ["Logging"] +git-tree-sha1 = "9143c41bd539a8885c79728b9dedb0ce47dc9819" +uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb" +version = "0.2.7" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.TableTraitsUtils]] +deps = ["DataValues", "IteratorInterfaceExtensions", "Missings", "TableTraits"] +git-tree-sha1 = "78fecfe140d7abb480b53a44f3f85b6aa373c293" +uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" +version = "1.0.2" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.Tricks]] +git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.8" + +[[deps.TupleTools]] +git-tree-sha1 = "41d61b1c545b06279871ef1a4b5fcb2cac2191cd" +uuid = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6" +version = "1.5.0" + +[[deps.URIParser]] +deps = ["Unicode"] +git-tree-sha1 = "53a9f49546b8d2dd2e688d216421d050c9a31d0d" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.1" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.Vega]] +deps = ["BufferedStreams", "DataStructures", "DataValues", "Dates", "FileIO", "FilePaths", "IteratorInterfaceExtensions", "JSON", "JSONSchema", "MacroTools", "NodeJS", "Pkg", "REPL", "Random", "Setfield", "TableTraits", "TableTraitsUtils", "URIParser"] +git-tree-sha1 = "0efd71a3df864e86d24236c99aaae3970e6f0ed0" +uuid = "239c3e63-733f-47ad-beb7-a12fde22c578" +version = "2.7.0" + +[[deps.YaoHIR]] +deps = ["Expronicon", "MLStyle", "YaoLocations"] +git-tree-sha1 = "b1e17fb84f1b322bef9910c942c1c9beb3e919ef" +uuid = "6769671a-fce8-4286-b3f7-6099e1b1298a" +version = "0.2.3" +weakdeps = ["OpenQASM"] + + [deps.YaoHIR.extensions] + YaoHIRExt = ["OpenQASM"] + +[[deps.YaoLocations]] +git-tree-sha1 = "c90c42c8668c9096deb0c861822f0f8f80cbdc68" +uuid = "66df03fb-d475-48f7-b449-3d9064bf085b" +version = "0.1.6" + +[[deps.ZXCalculus]] +deps = ["Expronicon", "Graphs", "LinearAlgebra", "MLStyle", "Multigraphs", "OMEinsum", "SparseArrays", "YaoHIR", "YaoLocations"] +git-tree-sha1 = "9110975b06644a0844c98e13944c00af26087bf4" +uuid = "3525faa3-032d-4235-a8d4-8c2939a218dd" +version = "0.6.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" +""" + +# ╔═╡ Cell order: +# ╠═dd08aa73-0d86-4f8b-970b-59f9ad9fac2d +# ╠═506db9e1-4260-408d-ba72-51581b548e53 +# ╟─db7e9cf8-9abf-448b-be68-43231853faff +# ╟─c06c5b9f-e5c1-4d0c-8ed5-937ad3871d3d +# ╟─5e0fb39e-68b3-45f6-8cb2-2dd0b79b35d4 +# ╠═587be022-6005-44d5-bb72-53cc9e3ba3bb +# ╠═482fdb57-2b0b-44b9-a5a0-f4dc26e15a7d +# ╠═57301b22-969f-481e-ae0b-0336e1ee5055 +# ╠═a8470d1a-8dc1-4a86-85b9-efd1836cf42c +# ╠═6e823d50-9107-4488-897e-d647334573f9 +# ╠═e3aa4e99-cb1f-478b-9e80-82b0ab02f606 +# ╠═a44ef98a-61fb-4271-9d36-c4d096f7e600 +# ╠═fb2448ef-aebe-419f-ad1d-a161edacd5a0 +# ╠═38da72a7-7e81-426f-ba08-b4158dc6a011 +# ╠═742750be-1262-4cbe-b476-f62e5e5c1fcf +# ╠═686cfe18-598b-4184-8a6d-85711109b055 +# ╠═9af85660-a4e3-4f27-b6cb-cf36d9b50d91 +# ╟─785ec008-63af-4f56-9792-f66b27a27388 +# ╠═44cbd3d8-6d36-4a0b-8613-552bbba48f3d +# ╠═0c2b4e33-5dcc-476d-8a9c-1e4244231e05 +# ╠═eebd1e46-0c0f-487d-8bee-07b1c17552c4 +# ╠═9200a1b1-11f7-4428-8840-c52dd4403c45 +# ╠═924efc08-681b-4804-93c6-38acc125315a +# ╠═5fdc6a08-c284-414e-9e96-8734289a98de +# ╠═0523c034-06ac-4383-b50f-6b68e6b1739f +# ╠═4d7d8a96-5aba-4b63-a5da-959716f2d2bf +# ╠═7da637f0-e359-41d9-b395-27168459c20c +# ╠═bed7a0c5-da16-40b5-9d84-4dad2dfb8739 +# ╠═8cde99fd-ee0a-4d94-a94e-23ebc9ac8608 +# ╠═17389edf-33d2-4dd8-bf86-df0467e65059 +# ╠═99bb5eff-79e7-4c0e-95ae-a6d2130f46cb +# ╠═f240382f-b682-4947-938f-c98d9c901c90 +# ╠═89f14c32-895d-4101-b4a8-bc410a2adaa5 +# ╠═0b838710-91e4-4572-9fe0-5c97e579ddd1 +# ╠═fdb7ca6a-bf5c-4216-8a18-a7c3603240ea +# ╠═6da61df3-b6e7-4991-ab9f-5994b55841e0 +# ╠═6b431ff3-f644-4123-82fd-704c054eb5bb +# ╠═cee877f2-8fd8-4a4e-9b8c-199411d449c5 +# ╠═20886e57-0c2c-4bf3-8c3d-8ed7d4f33fec +# ╠═9b838e52-79f6-49bd-9574-62d94f941558 +# ╠═91ea0d20-8f8b-4bec-a98d-6aebbc4228e1 +# ╠═fbbe52e6-40d0-48ab-aa92-58a5125a33b2 +# ╠═f7982574-ddff-4e7b-a4fc-52462a59d21c +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/notebooks/tutorial.jl b/notebooks/tutorial.jl index 1baf7a0..282256a 100644 --- a/notebooks/tutorial.jl +++ b/notebooks/tutorial.jl @@ -1,22 +1,40 @@ ### A Pluto.jl notebook ### -# v0.11.9 +# v0.19.43 using Markdown using InteractiveUtils # ╔═╡ 8ab9b70a-e98d-11ea-239c-73dc659722c2 -using YaoLang, YaoPlots, ZXCalculus, Compose, Revise +begin + using OpenQASM + using Vega + using DataFrames + using YaoHIR: BlockIR + using ZXCalculus, ZXCalculus.ZX + using YaoHIR, YaoLocations + using YaoHIR.IntrinsicOperation + + # Used for creating the IRCode for a BlockIR + using Core.Compiler: IRCode + using PlutoUI + +end -# ╔═╡ 282bd90e-e9fd-11ea-0b79-174cade05905 -using Yao, YaoExtensions +# ╔═╡ a9bf8e31-686a-4057-acec-bd04e8b5a3dc +using Multigraphs -# ╔═╡ e0a83244-e98e-11ea-3213-fdf02f4df920 -function Base.show(io::IO, mime::MIME"text/html", zx::Union{ZXDiagram, ZXGraph}) - g = plot(zx; size_x=13, size_y = 3, NODELABELSIZE=8pt) - Compose.set_default_graphic_size(18cm, 5cm) - Base.show(io, mime, compose(context(0.0, 0.0, 1.0, 1.0), g)) +# ╔═╡ 1e11009f-7b70-49fd-a6f3-ef8b5a79636e +using ZXCalculus.ZXW + +# ╔═╡ fdfa8ed2-f19c-4b80-b64e-f4bb22d09327 +function Base.show(io::IO, mime::MIME"text/html", zx::Union{ZXDiagram,ZXGraph}) + g = plot(zx) + Base.show(io, mime, g) end +# ╔═╡ 03405af4-0984-43c6-9312-f18fc3b23792 +TableOfContents(title="📚 Table of Contents", indent=true, depth=4, aside=true) + # ╔═╡ 227f7884-e99a-11ea-3a90-0beb697a2da6 md"# Construct a ZX diagram" @@ -24,47 +42,61 @@ md"# Construct a ZX diagram" z1 = ZXDiagram(4) # ╔═╡ 51e72d20-e994-11ea-1a50-854039f728aa -push_gate!(z1, Val(:Z), 1, 3//2) +push_gate!(z1, Val(:Z), 1, 3 // 2) # ╔═╡ e1dbb828-e995-11ea-385d-fb20b58d1b49 let - push_gate!(z1, Val(:H), 1) - push_gate!(z1, Val(:H), 1) - push_gate!(z1, Val(:Z), 1, 1//2) - push_gate!(z1, Val(:H), 4) - push_gate!(z1, Val(:CZ), 4, 1) - push_gate!(z1, Val(:CNOT), 1, 4) + push_gate!(z1, Val(:H), 1) + push_gate!(z1, Val(:H), 1) + push_gate!(z1, Val(:Z), 1, 1 // 2) + push_gate!(z1, Val(:H), 4) + push_gate!(z1, Val(:CZ), 4, 1) + push_gate!(z1, Val(:CNOT), 1, 4) end # ╔═╡ 60c59c0a-e994-11ea-02da-7360cbcf81f7 function load_graph() - zxd = ZXDiagram(4) - push_gate!(zxd, Val(:Z), 1, 3//2) - push_gate!(zxd, Val(:H), 1) - push_gate!(zxd, Val(:Z), 1, 1//2) + zxd = ZXDiagram(4) + push_gate!(zxd, Val(:Z), 1, 3 // 2) + push_gate!(zxd, Val(:H), 1) + push_gate!(zxd, Val(:Z), 1, 1 // 2) push_gate!(zxd, Val(:H), 4) push_gate!(zxd, Val(:CZ), 4, 1) push_gate!(zxd, Val(:CNOT), 1, 4) push_gate!(zxd, Val(:H), 1) push_gate!(zxd, Val(:H), 4) - push_gate!(zxd, Val(:Z), 1, 1//4) - push_gate!(zxd, Val(:Z), 4, 3//2) - push_gate!(zxd, Val(:X), 4, 1//1) + push_gate!(zxd, Val(:Z), 1, 1 // 4) + push_gate!(zxd, Val(:Z), 4, 3 // 2) + push_gate!(zxd, Val(:X), 4, 1 // 1) push_gate!(zxd, Val(:H), 1) - push_gate!(zxd, Val(:Z), 4, 1//2) - push_gate!(zxd, Val(:X), 4, 1//1) - push_gate!(zxd, Val(:Z), 2, 1//2) + push_gate!(zxd, Val(:Z), 4, 1 // 2) + push_gate!(zxd, Val(:X), 4, 1 // 1) + push_gate!(zxd, Val(:Z), 2, 1 // 2) push_gate!(zxd, Val(:CNOT), 3, 2) push_gate!(zxd, Val(:H), 2) push_gate!(zxd, Val(:CNOT), 3, 2) - push_gate!(zxd, Val(:Z), 2, 1//4) - push_gate!(zxd, Val(:Z), 3, 1//2) + push_gate!(zxd, Val(:Z), 2, 1 // 4) + push_gate!(zxd, Val(:Z), 3, 1 // 2) push_gate!(zxd, Val(:H), 2) push_gate!(zxd, Val(:H), 3) - push_gate!(zxd, Val(:Z), 3, 1//2) + push_gate!(zxd, Val(:Z), 3, 1 // 2) push_gate!(zxd, Val(:CNOT), 3, 2) end +# ╔═╡ ba769665-063b-4a17-8aa8-afa1fffc574c +md""" +# Multigraph ZXDigram +""" + + +# ╔═╡ b9d32b41-8bff-4faa-b198-db096582fb2e +begin + g = Multigraph([0 1 0; 1 0 1; 0 1 0]) + ps = [Rational(0) for i = 1:3] + v_t = [SpiderType.X, SpiderType.Z, SpiderType.X] + zxd_m = ZXDiagram(g, v_t, ps) +end + # ╔═╡ 90b83d5e-e99a-11ea-1fb2-95c907668262 md"# Simplify the ZX diagram" @@ -132,81 +164,161 @@ ex_zxd = clifford_simplification(zxd2) # ╔═╡ c0f046ea-e9b5-11ea-302c-c5fd4399d400 pt_zxd = phase_teleportation(zxd2) +# ╔═╡ 52c1ae46-a440-4d72-8dc1-fa9903feac80 +pt_zxg = ZXGraph(pt_zxd) + # ╔═╡ c3e8b5b4-e99a-11ea-0e56-6b18757f94df md"# Extract circuit" # ╔═╡ c1b9828c-e99a-11ea-006a-013a2eab8cf3 -zxd_simplified = circuit_extraction(zxg) +chain_simplified = circuit_extraction(pt_zxg) # ╔═╡ 6ddffea2-e9a4-11ea-1c32-0975a45aba7c -tcount(zxd_simplified) +tcount(pt_zxg) + +# ╔═╡ 4f07895a-58aa-4555-aa14-b0526bc1de2d +md""" +## ZXWDiagram as a Matrix +Convert a ZXWDiagram into a matrix using Einsum.jl +""" + +# ╔═╡ 80c79503-b85e-4938-9253-58dd45cf42b0 +begin + zxw1 = ZXWDiagram(2) + push_gate!(zxw1, Val(:Z), 1, 1 // 2) + push_gate!(zxw1, Val(:H), 2) + push_gate!(zxw1, Val(:CZ), 2, 1) +end + +# ╔═╡ a5b21163-7e60-409f-ad59-66ca72375094 +Matrix(zxw1) # ╔═╡ 2082486e-e9fd-11ea-1a46-6395b4b34657 -md"# Porting Yao" +md""" +# Porting Yao + +We can define a Yao Chain and push gates into the chain -# ╔═╡ 3a2c5d22-e9fd-11ea-1e48-a9be2e8b213b -zxd3 = ZXDiagram(4) +""" -# ╔═╡ d341cde4-e9fd-11ea-1c3b-63f35fc648d5 +# ╔═╡ d1789ff9-3628-4fd3-aa39-823191e78ee0 begin -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::AbstractBlock) - error("Block type `$c` is not supported.") -end -# rotation blocks -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::PutBlock{N,1,RotationGate{1,T,XGate}}) where {N,T} - push_gate!(zxd, Val(:X), c.locs[1], c.content.theta) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::PutBlock{N,1,RotationGate{1,T,ZGate}}) where {N,T} - push_gate!(zxd, Val(:Z), c.locs[1], c.content.theta) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::PutBlock{N,1,ShiftGate{T}}) where {N,T} - push_gate!(zxd, Val(:Z), c.locs[1], c.content.theta) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::PutBlock{N,1,HGate}) where {N} - push_gate!(zxd, Val(:H), c.locs[1]) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::ChainBlock{N}) where {N} - push_gate!.(Ref(zxd), subblocks(c)) - zxd + chain_t = Chain() + push_gate!(chain_t, Val(:H), 1) + push_gate!(chain_t, Val(:H), 2) + push_gate!(chain_t, Val(:X), 3) + push_gate!(chain_t, Val(:H), 3) + push_gate!(chain_t, Val(:CNOT), 1, 3) + push_gate!(chain_t, Val(:X), 1) + push_gate!(chain_t, Val(:CNOT), 2, 3) + push_gate!(chain_t, Val(:H), 2) end -# constant block -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::PutBlock{N,1,RotationGate{1,T,XGate}}) where {N,T} - push_gate!(zxd, Val(:X), c.locs[1], c.content.theta) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::PutBlock{N,1,RotationGate{1,T,ZGate}}) where {N,T} - push_gate!(zxd, Val(:Z), c.locs[1], c.content.theta) -end +# ╔═╡ 9ba5aa18-9e6b-4f75-a35c-e7a3e548d557 +md""" +## Convert BlockIR to ZXDiagram +Create a BlockIR and convert it into a ZXDiagram +""" -# control blocks -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::ControlBlock{N,1,RotationGate{1,T,XGate}}) where {N,T} - push_gate!(zxd, Val(:X), c.locs[1], c.content.theta) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::ControBlock{N,1,RotationGate{1,T,ZGate}}) where {N,T} - push_gate!(zxd, Val(:Z), c.locs[1], c.content.theta) -end -function ZXCalculus.push_gate!(zxd::ZXDiagram, c::ControlBlock{N,1,ShiftGate{T}}) where {N,T} - push_gate!(zxd, Val(:Z), c.locs[1], c.content.theta) -end +# ╔═╡ 71fc6836-3c30-43de-aa2b-2d3d48bdb3da +begin + + ir_t = IRCode() + bir_t = BlockIR(ir_t, 4, chain_t) + zxd_t = convert_to_zxd(bir_t) end -# ╔═╡ 581e847c-e9fd-11ea-3fd0-6bbc0f6efd56 -c = qft_circuit(4) +# ╔═╡ 31753c83-847a-4c2a-a6b3-8be6aaa8f792 +zxg_t = ZXGraph(zxd_t) -# ╔═╡ 2e84a5ce-e9fd-11ea-12d0-b3a3dd75a76f -push_gate!(zxd3, c) +# ╔═╡ 4a189a46-9ae6-458c-94c4-7cc8d5dab788 +md""" +# Equivalence Checking + +## Equivalence Checking of Quantum Circuits +### Principle of Quantum Circuit Equality +#### Reversiblity +Equivalence checking the equality of two quantum circuits relies on the reversibility +of quantum operations. Every quantum operation is *unitary* and thus reversible. The product of any quantum operation and its inverse (adjoint) +will always yield the identity. + + +#### Unitary +For a matrix to be unitary, this property needs to hold: +`` U \cdot U^\dagger = U^\dagger \cdot U = I_n | U \in \mathbb{R}^{n \times n} `` + +If ``U_1`` and ``U_2`` are unitary matrices, so is their matrix product ``U_1 \cdot U_2``. +Unitary matrices preserve inner products. Thus, if ``U`` is unitary, then for all ``V , V′ \in \mathbb{C}^n`` we have: +``⟨U V |U V ′ ⟩ = ⟨U |V ′ ⟩`` + +### Equality +In order to verify the equality of two quantum circuits we exploit their reversibility. + +Given two quantum circuits ``G_1`` and ``G_2`` as well the systems matrices ``U_1`` and ``U_1`` that describe the operations of these quantum circuits we ask ourself, the problem of equivalence checking is to verify if there is no difference ``D = U_1 \cdot U_2^\dagger`` between the first and second quantum circuit. + +To verify if the two quantum circuits are equal we check if ``tr(D) = 0``, as this implies that the difference is the idenity matrix. + ``U_1 \cdot U_2^\dagger = D````U_1 \cdot U_2^\dagger = D = I``. + +If the two quantum circuits are not equal, ``U_1 \cdot U_2^\dagger = D != I``, the +problem is to +- approximate how close the quantum circuits are +- debug the quantum circuits, in order to reduce the difference `D` between them. + + +""" -# ╔═╡ 7b850816-ea02-11ea-183c-5db2d670be24 -ZXDiagram(4) |> typeof +# ╔═╡ daa4e9e7-aefa-490d-b8ba-876643b4c7f3 +bv_010 = full_reduction(concat!(ZXDiagram(BlockIR(""" +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[4]; +creg c[3]; +x q[3]; +h q[2]; +h q[3]; +h q[2]; +h q[1]; +CX q[1], q[3]; +h q[1]; +h q[0]; +h q[0]; +measure q[0] -> c[2]; +measure q[2] -> c[0]; +measure q[1] -> c[1]; + """)), dagger(ZXDiagram(BlockIR(""" +OPENQASM 2.0; +include "qelib1.inc"; +qreg q[4]; +creg c[3]; +x q[3]; +h q[0]; +h q[1]; +h q[2]; +h q[3]; +CX q[1],q[3]; +h q[0]; +h q[1]; +h q[2]; +measure q[0] -> c[0]; +measure q[1] -> c[1]; +measure q[2] -> c[2]; + """))))) + +# ╔═╡ 7bcc5502-a6d3-44fc-85a1-5ee33d855fa9 +contains_only_bare_wires(bv_010) # ╔═╡ Cell order: # ╠═8ab9b70a-e98d-11ea-239c-73dc659722c2 -# ╟─e0a83244-e98e-11ea-3213-fdf02f4df920 +# ╠═fdfa8ed2-f19c-4b80-b64e-f4bb22d09327 +# ╠═03405af4-0984-43c6-9312-f18fc3b23792 # ╟─227f7884-e99a-11ea-3a90-0beb697a2da6 # ╠═49d6e6ac-e994-11ea-2ac5-27ab8242e297 # ╠═51e72d20-e994-11ea-1a50-854039f728aa # ╠═e1dbb828-e995-11ea-385d-fb20b58d1b49 # ╠═60c59c0a-e994-11ea-02da-7360cbcf81f7 +# ╟─ba769665-063b-4a17-8aa8-afa1fffc574c +# ╠═a9bf8e31-686a-4057-acec-bd04e8b5a3dc +# ╠═b9d32b41-8bff-4faa-b198-db096582fb2e # ╟─90b83d5e-e99a-11ea-1fb2-95c907668262 # ╠═64bff9ec-e9b5-11ea-3b23-c51d2149697a # ╠═5dbf9f96-e9a4-11ea-19d7-e15e7f2327c9 @@ -227,13 +339,19 @@ ZXDiagram(4) |> typeof # ╠═b6eaa762-e9b5-11ea-145e-7b5fa6b01872 # ╠═5464bc40-e9b5-11ea-2a2e-dfb0d31a33d3 # ╠═c0f046ea-e9b5-11ea-302c-c5fd4399d400 +# ╠═52c1ae46-a440-4d72-8dc1-fa9903feac80 # ╟─c3e8b5b4-e99a-11ea-0e56-6b18757f94df # ╠═c1b9828c-e99a-11ea-006a-013a2eab8cf3 # ╠═6ddffea2-e9a4-11ea-1c32-0975a45aba7c -# ╠═2082486e-e9fd-11ea-1a46-6395b4b34657 -# ╠═282bd90e-e9fd-11ea-0b79-174cade05905 -# ╠═3a2c5d22-e9fd-11ea-1e48-a9be2e8b213b -# ╠═d341cde4-e9fd-11ea-1c3b-63f35fc648d5 -# ╠═581e847c-e9fd-11ea-3fd0-6bbc0f6efd56 -# ╠═2e84a5ce-e9fd-11ea-12d0-b3a3dd75a76f -# ╠═7b850816-ea02-11ea-183c-5db2d670be24 +# ╟─4f07895a-58aa-4555-aa14-b0526bc1de2d +# ╠═1e11009f-7b70-49fd-a6f3-ef8b5a79636e +# ╠═80c79503-b85e-4938-9253-58dd45cf42b0 +# ╠═a5b21163-7e60-409f-ad59-66ca72375094 +# ╟─2082486e-e9fd-11ea-1a46-6395b4b34657 +# ╠═d1789ff9-3628-4fd3-aa39-823191e78ee0 +# ╟─9ba5aa18-9e6b-4f75-a35c-e7a3e548d557 +# ╠═71fc6836-3c30-43de-aa2b-2d3d48bdb3da +# ╠═31753c83-847a-4c2a-a6b3-8be6aaa8f792 +# ╟─4a189a46-9ae6-458c-94c4-7cc8d5dab788 +# ╠═daa4e9e7-aefa-490d-b8ba-876643b4c7f3 +# ╠═7bcc5502-a6d3-44fc-85a1-5ee33d855fa9 diff --git a/notebooks/zx_intro.jl b/notebooks/zx_intro.jl new file mode 100644 index 0000000..c9ba72f --- /dev/null +++ b/notebooks/zx_intro.jl @@ -0,0 +1,451 @@ +### A Pluto.jl notebook ### +# v0.19.38 + +using Markdown +using InteractiveUtils + +# ╔═╡ dd08aa73-0d86-4f8b-970b-59f9ad9fac2d +begin + using OpenQASM + using Vega + using DataFrames + using YaoHIR: BlockIR + using ZXCalculus, ZXCalculus.ZX + using PlutoUI +end + +# ╔═╡ 741c3ca4-2dd5-406c-9ae5-7d19a3192e7d +TableOfContents(title = "📚 Table of Contents", indent = true, depth = 2, aside = true) + +# ╔═╡ 24749683-0566-4f46-989d-22336d296517 +html""" + +""" + + +# ╔═╡ 506db9e1-4260-408d-ba72-51581b548e53 +function Base.show(io::IO, mime::MIME"text/html", zx::Union{ZXDiagram,ZXGraph}) + g = plot(zx) + Base.show(io, mime, g) +end + +# ╔═╡ 92dccd1c-6582-40bf-9b57-f326b2aff67a +html"" + +# ╔═╡ a93915fc-01ef-4411-bc98-ea1fe8674fa9 +md""" +# Introduction +ZX-Calculus is a unified formalism for describing quantum computation, mainly over +qubits. It is a rigorous graphical language, that utilizes the powerful set of rewrite +rules [1] for reasoning about linear maps between qubits, which are represented as string diagrams called ZX-Diagrams [2-3]. + +ZX-Calculus was invented in 2008 by Bob Coecke and Russ Duncan as an extension +of categorical quantum mechanics. They introduced the fundamental concepts of +spiders, strong complementarity and most the rewrite rules + +All equations +concerning quantum processes can be derived using a handful of graphical rules [4]. + +The ZX-Calculus is universal, because any linear map between qubits can be rep- +resented as a ZX-Diagram. It is complete, meaning that all equations concerning +quantum processes can be derived using linear algebra, can also be obtained using a +handful of graphical rules [5, 6]. This makes the ZX-Calculus an alternative to the +Hilbert Space Formalism and a tool for generalization of quantum circuit notations +[1]. + +This section notebook demonstrates the universality of the ZX-Calculus by exhibiting how the Clifford group (CN OT , H, S) + T , one of the universal gate sets [7], is implemented. +The ZX-Calculus, which has been proven complete in [8], provides a powerful repre- +sentation of static quantum circuits. + + +## ZXDiagrams +ZXDiagrams can be created by specifying the number of qubits. +Bare wires are equivalent to an identiy gate. The identity gate is the identity matrix and does not modify the quantum state. + +The ZX-Calculus is built around the concept of wires, which serve as a visual representation of a system. The first diagram below shows a single wire, which corresponds to a quantum system with one qubit, emphasizing their equivalence. +It represents the identity I, since the state of the system does not change. +""" + +# ╔═╡ 9af85660-a4e3-4f27-b6cb-cf36d9b50d91 +z1 = ZXDiagram(1) + +# ╔═╡ 3f82bd5a-7528-4b1c-9b67-252ed076ed97 +md"The second diagram shows a quantum system with 3 qubits." + +# ╔═╡ df00b5c6-9217-11ee-0b09-632420c4e265 +z3 = ZXDiagram(3) + +# ╔═╡ 785ec008-63af-4f56-9792-f66b27a27388 +md""" +## Gates +Spiders, which represent gates can be pushed onto a Diagram. +The following example shows, how the clifford+T universal gate set, is constructed using ZXCalculus. + +### Pauli-X Gate +The Pauli-X Gate rotates around the x axis of the Bloch Sphere with a phase of ``\pi``. The quantum equivalent of the classical NOT gate is the Pauli-X gate with respect to the standard basis ``|0\rangle, |1\rangle`` +It flips the ``|0\rangle`` into the ``|1\rangle`` state and vice-versa. + +Its matrix is represented as: +`` X = \sigma_x =\operatorname{NOT} = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}`` + +""" + +# ╔═╡ 0c2b4e33-5dcc-476d-8a9c-1e4244231e05 +begin + zx_x = ZXDiagram(1) + push_gate!(zx_x, Val(:X), 1, 1 // 1) +end + + +# ╔═╡ 3cf7e1a1-7f99-4191-8e38-1533da8ebba1 +md""" +### Z-Gate +The effect of the Pauli-Z Gate is a phase flip. It leaves the basis state ``|0\rangle`` and maps +``|0\rangle`` to ``−|0\rangle``. + +`` Z = \begin{bmatrix} 1 & 0 \\ 0 & e^{i \pi} \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} = P\left(\pi\right)`` +""" + +# ╔═╡ eeb5001c-2599-4d01-8e45-d417bda4d83c +begin + zx_z = ZXDiagram(1) + push_gate!(zx_z, Val(:Z), 1, 1 // 1) +end + +# ╔═╡ 24609bab-a13b-49d9-be85-b8770a9153b1 +md""" +### S-Gate +The T-Gate has a phase of ``P(\frac{\pi}{2})`` + + +``S = \begin{bmatrix} 1 & 0 \\ 0 & e^{i \frac{\pi}{2}} \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & i \end{bmatrix} = P\left(\frac{\pi}{2}\right)=\sqrt{Z}`` +""" + +# ╔═╡ eebd1e46-0c0f-487d-8bee-07b1c17552c4 +begin + zx_s = ZXDiagram(1) + push_gate!(zx_s, Val(:Z), 1, 1 // 2) +end + +# ╔═╡ 3e0f5adc-c47c-4363-890f-f2c6a9843115 +md""" +### T-Gate +The T-Gate has a phase of ``P(\frac{\pi}{4})`` + + +``T = \begin{bmatrix} 1 & 0 \\ 0 & e^{i \frac{\pi}{4}} \end{bmatrix} =P\left(\frac{\pi}{4}\right) = \sqrt{S} = \sqrt[4]{Z}`` + +""" + +# ╔═╡ 9200a1b1-11f7-4428-8840-c52dd4403c45 +begin + zx_t = ZXDiagram(1) + push_gate!(zx_t, Val(:Z), 1, 1 // 4) +end + +# ╔═╡ 518c82ab-ee25-4929-b9c7-976c27482d51 +md""" +### H-Gate +The Hadamard gate is a fundamental gate used to create superposition states in quantum computing. +When applied to a qubit, the Hadamard gate creates a superposition of the basis +states ``|0\rangle`` and ``|1\rangle``. It transforms the basis states as follows: + +``H = \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}`` +""" + +# ╔═╡ 924efc08-681b-4804-93c6-38acc125315a +begin + zx_h = ZXDiagram(1) + push_gate!(zx_h, Val(:H), 1) +end + +# ╔═╡ 08199250-2746-4779-b2d7-347c321ceb55 +md""" +### H-Gate +Contary to quantum logic gates, CNOT is not a gate primitive but composed out of a red and a green spider. + +""" + +# ╔═╡ 5fdc6a08-c284-414e-9e96-8734289a98de +begin + zx_cnot = ZXDiagram(2) + push_gate!(zx_cnot, Val(:CNOT), 1, 2) + +end + +# ╔═╡ e2d695a4-7962-4d77-b348-74eb05c72b9c +md""" + +## Quantum Circuit + +""" + +# ╔═╡ 0523c034-06ac-4383-b50f-6b68e6b1739f +begin + zx = ZXDiagram(3) + push_gate!(zx, Val(:X), 1, 1 // 1) + push_gate!(zx, Val(:CNOT), 1, 2) + push_gate!(zx, Val(:H), 1) + push_gate!(zx, Val(:CNOT), 2, 3) + push_gate!(zx, Val(:H), 2) +end + + +# ╔═╡ 92fd5c2b-95a1-4820-99cb-45923429117c +md""" +# Rewrite Rules +The ZX-Calculus provides a set of rewrite rules that allow us to transform one diagram +into another equivalent diagram. These rules include the ability to move wires and +effects, cancel pairs of H and Z gates, and commute certain gates. Rewrite rules are +powerful, they allow us to change the structure of the ZX-Diagrams without changing +the quantum circuit, since the linear maps remain the same. + +## Spider Fusion Rule +Spiders of the same color can be fused together. Their phases are then added up. +In this example we have the equivalent of two Pauli-X Gates on a wire. + +> Spider Fusion (f): Two spiders of the same color can fuse together if touching, adding their phases. This is because spiders of the same color represent an orthonormal basis. +""" + +# ╔═╡ 5dabc4ae-ecd7-4339-837a-e1272b925acf +begin + push_gate!(zx_x, Val(:X), 1, 1 // 1) +end + + +# ╔═╡ 973ad229-2b87-48f8-9926-c833766d45cb +md""" +After fusion them together, we get a phaseless spider. +""" + +# ╔═╡ 852455dd-b95d-45a4-a771-053c1e95b82f +simplify!(Rule{:f}(), zx_x) + +# ╔═╡ b4702fb4-e21a-43b0-8be4-fbfca81b4a8b +md""" +## Identiy Rule +The identiy rules states, that phase less spiders are the idenity, as they do not change the phase of the Z or the X base. + +> Identity Rule (id): A phaseless arity 2 Z-or X-spider equals the identity. The Bell State (Definiton TODO) is the same if expressed in the computational basis or Hadamard basis. + +After applying the second idenity rule, we are left with a bare wire. + +""" + +# ╔═╡ 64be3d04-4983-467e-9b06-45b64132ee30 +simplify!(Rule{:i1}(), zx_x) + +# ╔═╡ c604a76d-9b95-4f0d-8133-df2a3e9dabe9 +md""" +We can verify, that these rules are correct by checking constructing the same qunatum circuit using matrices in the hilbert space. + +`` \fbox{x} \cdot \fbox{x} = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} = \mathbb{I}`` + +""" + +# ╔═╡ 4d7d8a96-5aba-4b63-a5da-959716f2d2bf +md"""# +## ZXDiagrams and ZXGraphs""" + +# ╔═╡ 7da637f0-e359-41d9-b395-27168459c20c +zx_graph = ZXGraph(zx) + +# ╔═╡ bed7a0c5-da16-40b5-9d84-4dad2dfb8739 +begin + zx_id = ZXDiagram(2) + push_gate!(zx_id, Val(:X), 1) + push_gate!(zx_id, Val(:X), 1) +end + + +# ╔═╡ 8cde99fd-ee0a-4d94-a94e-23ebc9ac8608 +zx_id_graph = ZXGraph(zx_id) + +# ╔═╡ 99bb5eff-79e7-4c0e-95ae-a6d2130f46cb +md"## Equality" + +# ╔═╡ f240382f-b682-4947-938f-c98d9c901c90 +zx_dagger = dagger(zx) + +# ╔═╡ 89f14c32-895d-4101-b4a8-bc410a2adaa5 +merged_diagram = concat!(zx, zx_dagger) + +# ╔═╡ 0b838710-91e4-4572-9fe0-5c97e579ddd1 +m_simple = full_reduction(merged_diagram) + + +# ╔═╡ fdb7ca6a-bf5c-4216-8a18-a7c3603240ea +contains_only_bare_wires(m_simple) + +# ╔═╡ 6b431ff3-f644-4123-82fd-704c054eb5bb +md"""# Circuit Verification +## Informal Definition +Equivalence checking the equality of two quantum circuits relies on the reversibility +of quantum operations. Every quantum operation is *unitary* and thus reversible. The product of any quantum operation and its inverse (adjoint) +will always yield the identity. + +## Formal Definition +### Unitary +For a matrix to be unitary, this property needs to hold: +`` U \cdot U^\dagger = U^\dagger \cdot U = I_n | U \in \mathbb{R}^{n \times n} `` + +If ``U_1`` and ``U_2`` are unitary matrices, so is their matrix product ``U_1 \cdot U_2``. +Unitary matrices preserve inner products. Thus, if ``U`` is unitary, then for all ``V , V′ \in \mathbb{C}^n`` we have: +``⟨U V |U V ′ ⟩ = ⟨U |V ′ ⟩`` + +### Equality +In order to verify the equality of two quantum circuits we exploit their reversibility. + +Given two quantum circuits ``G_1`` and ``G_2`` as well the systems matrices ``U_1`` and ``U_1`` that describe the operations of these quantum circuits we ask ourself, the problem of equivalence checking is to verify if there is no difference ``D = U_1 \cdot U_2^\dagger`` between the first and second quantum circuit. + +To verify if the two quantum circuits are equal we check if ``tr(D) = 0``, as this implies that the difference is the idenity matrix. + ``U_1 \cdot U_2^\dagger = D````U_1 \cdot U_2^\dagger = D = I``. + +If the two quantum circuits are not equal, ``U_1 \cdot U_2^\dagger = D != I``, the +problem is to +- approximate how close the quantum circuits are +- debug the quantum circuits, in order to reduce the difference `D` between them. + +### Example +Given circuits `b1` and `b2`. Can we proof that they are equal? +""" + +# ╔═╡ cee877f2-8fd8-4a4e-9b8c-199411d449c5 +begin + b1 = BlockIR(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q0[3]; + creg c0[2]; + h q0[0]; + h q0[1]; + x q0[2]; + h q0[2]; + CX q0[0],q0[2]; + h q0[0]; + CX q0[1],q0[2]; + h q0[1]; + x q0[2]; + x q0[2]; + measure q0[0] -> c0[0]; + measure q0[1] -> c0[1]; + """) + c1 = ZXDiagram(b1) +end + +# ╔═╡ 20886e57-0c2c-4bf3-8c3d-8ed7d4f33fec +begin + b2 = BlockIR(""" + OPENQASM 2.0; + include "qelib1.inc"; + qreg q0[3]; + creg mcm[1]; + creg end[1]; + h q0[1]; + x q0[2]; + h q0[2]; + CX q0[1], q0[2]; + h q0[1]; + h q0[0]; + CX q0[0], q0[2]; + h q0[0]; + measure q0[0] -> end[0]; + measure q0[1] -> mcm[0]; + """) + c2 = ZXDiagram(b2) + + +end + +# ╔═╡ 02be99e0-1b97-4fe0-b316-5151febe92d8 +concat!(c1, dagger(c2)) + +# ╔═╡ e529aa93-4f3e-4038-97dd-1ce570df8076 +c_reduced = full_reduction(c1) + +# ╔═╡ 94ac0dd1-390e-42d6-8300-f67a5a633043 +contains_only_bare_wires(c_reduced) + +# ╔═╡ 796e6c34-0664-488d-a186-c7810df06d77 +verify_equality(ZXDiagram(b1), ZXDiagram(b1)) + +# ╔═╡ f7982574-ddff-4e7b-a4fc-52462a59d21c +md""" +# Sources +1. [B. Coecke, D. Horsman, A. Kissinger, and Q. Wang. “Kindergarden quantum mechanics graduates ...or how I learned to stop gluing LEGO together and love the ZX-calculus”. In: Theoretical Computer Science 897 (2022), pp. 1–22. issn: 0304-3975](https://doi.org/10.1016/j.tcs.2021.07.024) + +2. [R. Duncan, A. Kissinger, S. Perdrix, and J. van de Wetering. “Graph-theoretic Simplification of Quantum Circuits with the ZX -calculus”. In: Quantum 4 (June 2020), p. 279. issn: 2521-327X](https://doi.org/10.22331/q-2020-06-04-279) + +3. [J. van de Wetering. ZX-calculus for the working quantum computer scientist. 2020. arXiv: 2012.13966 [quant-ph]](https://arxiv.org/abs/2012.13966) + +4. [A. Kissinger and J. van de Wetering. “PyZX: Large Scale Automated Diagrammatic Reasoning”. In: Electronic Proceedings in Theoretical Computer Science 318 (May 2020), pp. 229–241](https://doi.org/10.4204/eptcs.318.14) + +5. [A. Hadzihasanovic, K. F. Ng, and Q. Wang. “Two complete axiomatisations of pure-state qubit quantum computing”. In: Proceedings of the 33rd Annual ACM/IEEE Symposium on Logic in Computer Science (2018)](https://api.semanticscholar.org/CorpusID:195347007) + +6. [R. Vilmart. “A Near-Minimal Axiomatisation of ZX-Calculus for Pure Qubit Quantum Mechanics”. In: 2019 34th Annual ACM/IEEE Symposium on Logic in Computer Science (LICS). 2019, pp. 1–10](https://doi.org/10.1109/LICS.2019.8785765) + +7. [M. A. Nielsen and I. L. Chuang. Quantum computation and quantum information. 10th anniversary ed. Cambridge ; New York: Cambridge University Press, 2010. isbn: 9781107002173](#) + +8. [Q. Wang. Completeness of the ZX-calculus. 2023. arXiv: 2209 . 14894 [quant-ph]](https://arxiv.org/abs/2209.14894) + + +""" + +# ╔═╡ Cell order: +# ╠═dd08aa73-0d86-4f8b-970b-59f9ad9fac2d +# ╠═741c3ca4-2dd5-406c-9ae5-7d19a3192e7d +# ╠═24749683-0566-4f46-989d-22336d296517 +# ╠═506db9e1-4260-408d-ba72-51581b548e53 +# ╠═92dccd1c-6582-40bf-9b57-f326b2aff67a +# ╟─a93915fc-01ef-4411-bc98-ea1fe8674fa9 +# ╠═9af85660-a4e3-4f27-b6cb-cf36d9b50d91 +# ╟─3f82bd5a-7528-4b1c-9b67-252ed076ed97 +# ╠═df00b5c6-9217-11ee-0b09-632420c4e265 +# ╟─785ec008-63af-4f56-9792-f66b27a27388 +# ╠═0c2b4e33-5dcc-476d-8a9c-1e4244231e05 +# ╟─3cf7e1a1-7f99-4191-8e38-1533da8ebba1 +# ╠═eeb5001c-2599-4d01-8e45-d417bda4d83c +# ╟─24609bab-a13b-49d9-be85-b8770a9153b1 +# ╠═eebd1e46-0c0f-487d-8bee-07b1c17552c4 +# ╟─3e0f5adc-c47c-4363-890f-f2c6a9843115 +# ╠═9200a1b1-11f7-4428-8840-c52dd4403c45 +# ╟─518c82ab-ee25-4929-b9c7-976c27482d51 +# ╠═924efc08-681b-4804-93c6-38acc125315a +# ╟─08199250-2746-4779-b2d7-347c321ceb55 +# ╠═5fdc6a08-c284-414e-9e96-8734289a98de +# ╟─e2d695a4-7962-4d77-b348-74eb05c72b9c +# ╠═0523c034-06ac-4383-b50f-6b68e6b1739f +# ╟─92fd5c2b-95a1-4820-99cb-45923429117c +# ╠═5dabc4ae-ecd7-4339-837a-e1272b925acf +# ╟─973ad229-2b87-48f8-9926-c833766d45cb +# ╠═852455dd-b95d-45a4-a771-053c1e95b82f +# ╟─b4702fb4-e21a-43b0-8be4-fbfca81b4a8b +# ╠═64be3d04-4983-467e-9b06-45b64132ee30 +# ╟─c604a76d-9b95-4f0d-8133-df2a3e9dabe9 +# ╟─4d7d8a96-5aba-4b63-a5da-959716f2d2bf +# ╠═7da637f0-e359-41d9-b395-27168459c20c +# ╠═bed7a0c5-da16-40b5-9d84-4dad2dfb8739 +# ╠═8cde99fd-ee0a-4d94-a94e-23ebc9ac8608 +# ╟─99bb5eff-79e7-4c0e-95ae-a6d2130f46cb +# ╠═f240382f-b682-4947-938f-c98d9c901c90 +# ╠═89f14c32-895d-4101-b4a8-bc410a2adaa5 +# ╠═0b838710-91e4-4572-9fe0-5c97e579ddd1 +# ╠═fdb7ca6a-bf5c-4216-8a18-a7c3603240ea +# ╠═6b431ff3-f644-4123-82fd-704c054eb5bb +# ╠═cee877f2-8fd8-4a4e-9b8c-199411d449c5 +# ╠═20886e57-0c2c-4bf3-8c3d-8ed7d4f33fec +# ╠═02be99e0-1b97-4fe0-b316-5151febe92d8 +# ╠═e529aa93-4f3e-4038-97dd-1ce570df8076 +# ╠═94ac0dd1-390e-42d6-8300-f67a5a633043 +# ╠═796e6c34-0664-488d-a186-c7810df06d77 +# ╟─f7982574-ddff-4e7b-a4fc-52462a59d21c diff --git a/src/ZX/ZX.jl b/src/ZX/ZX.jl index f05e9dd..0f5688f 100644 --- a/src/ZX/ZX.jl +++ b/src/ZX/ZX.jl @@ -20,8 +20,10 @@ export Rule, Match export rewrite!, simplify! -export convert_to_chain, convert_to_zxd +export convert_to_chain, convert_to_zxd, convert_to_zxwd export clifford_simplification, full_reduction, circuit_extraction, phase_teleportation +export plot +export concat!, dagger, contains_only_bare_wires, verify_equality include("abstract_zx_diagram.jl") include("zx_layout.jl") @@ -35,4 +37,6 @@ include("circuit_extraction.jl") include("phase_teleportation.jl") include("ir.jl") + +include("equality.jl") end diff --git a/src/ZX/circuit_extraction.jl b/src/ZX/circuit_extraction.jl index 466fe75..2e592da 100644 --- a/src/ZX/circuit_extraction.jl +++ b/src/ZX/circuit_extraction.jl @@ -285,7 +285,7 @@ function update_frontier!(zxg::ZXGraph{T, P}, gads::Set{T}, frontier::Vector{T}, v = frontier[i] nb_v = neighbors(zxg, v) u = findfirst([u in gads for u in nb_v]) - if u !== nothing + if !isnothing(u) u = nb_v[u] gad_u = zero(T) for w in neighbors(zxg, u) @@ -474,7 +474,7 @@ function normalize_perm(M::Matrix{T}, steps::Vector{GEStep} = Vector{GEStep}()) tar_c = findfirst(isone, M[cur_r, :]) M[cur_r, cur_c] = 1 M[tar_r, cur_c] = 0 - if tar_c !== nothing + if !isnothing(tar_c) M[tar_r, tar_c] = 1 M[cur_r, tar_c] = 0 end @@ -488,7 +488,7 @@ end # """ # reverse_gaussian_elimination(M, steps) - +# # Apply back the operations in `steps` to `M`. # """ # function reverse_gaussian_elimination(M, steps) diff --git a/src/ZX/equality.jl b/src/ZX/equality.jl new file mode 100644 index 0000000..42132ea --- /dev/null +++ b/src/ZX/equality.jl @@ -0,0 +1,19 @@ +""" + verify_equality(zxd_1::ZXDiagram, zxd_2::ZXDiagram) + +checks the equivalence of two different ZXDiagrams + +""" +function verify_equality(zxd_1::ZXDiagram, zxd_2::ZXDiagram) + merged_diagram = concat!(zxd_1, dagger(zxd_2)) + m_simple = full_reduction(merged_diagram) + contains_only_bare_wires(m_simple) +end + +function contains_only_bare_wires(zxd::Union{ZXDiagram,ZXGraph}) + all(is_in_or_out_spider(st[2]) for st in zxd.st) +end + +function is_in_or_out_spider(st::SpiderType.SType) + st == SpiderType.In || st == SpiderType.Out +end diff --git a/src/ZX/ir.jl b/src/ZX/ir.jl index 5e91aba..16a956a 100644 --- a/src/ZX/ir.jl +++ b/src/ZX/ir.jl @@ -6,7 +6,7 @@ convert_to_gate(::Val{:Z}, loc) = Gate(Z, Locations(loc)) convert_to_gate(::Val{:H}, loc) = Gate(H, Locations(loc)) convert_to_gate(::Val{:S}, loc) = Gate(S, Locations(loc)) convert_to_gate(::Val{:Sdag}, loc) = Gate(AdjointOperation(S), Locations(loc)) -convert_to_gate(::Val{:T}, loc) = Gate(T, Locations(loc)) +convert_to_gate(::Val{:T}, loc) = Gate(T, Locations(loc)) convert_to_gate(::Val{:Tdag}, loc) = Gate(AdjointOperation(S), Locations(loc)) convert_to_gate(::Val{:SWAP}, loc1, loc2) = Gate(SWAP, Locations((loc1, loc2))) convert_to_gate(::Val{:CNOT}, loc, ctrl) = Ctrl(Gate(X, Locations(loc)), CtrlLocations(ctrl)) @@ -25,6 +25,14 @@ function convert_to_gate(::Val{:Rx}, loc, theta) end return Gate(Rx(theta), Locations(loc)) end + +function convert_to_gate(::Val{:Ry}, loc, theta) + if theta isa Phase + theta = theta * π + theta = theta.ex + end + return Gate(Ry(theta), Locations(loc)) +end function convert_to_gate(::Val{:shift}, loc, theta) if theta isa Phase theta = theta * π @@ -33,11 +41,11 @@ function convert_to_gate(::Val{:shift}, loc, theta) return Gate(shift(theta), Locations(loc)) end -function push_gate!(circ::Chain, gargs...) +function push_gate!(circ::Chain, gargs...) push!(circ.args, convert_to_gate(gargs...)) return circ end -function pushfirst_gate!(circ::Chain, gargs...) +function pushfirst_gate!(circ::Chain, gargs...) pushfirst!(circ.args, convert_to_gate(gargs...)) return circ end @@ -74,10 +82,7 @@ function canonicalize_single_location(node::YaoHIR.Gate) return YaoHIR.Gate(node.operation, node.locations[1]) end -function convert_to_zxd(root::YaoHIR.BlockIR) - circ = ZXDiagram(root.nqubits) - - circuit = canonicalize_single_location(root.circuit) +function gates_to_circ(circ, circuit, root) for gate in YaoHIR.leaves(circuit) @switch gate begin @case Gate(&Z, loc::Locations{Int}) @@ -92,18 +97,18 @@ function convert_to_zxd(root::YaoHIR.BlockIR) push_gate!(circ, Val(:Z), plain(loc), 1//4) @case Gate(shift(theta), loc::Locations{Int}) theta = unwrap_ssa_phase(theta, root.parent) - push_gate!(circ, Val(:Z), plain(loc), (1/π)*theta) + push_gate!(circ, Val(:Z), plain(loc), (1/π) * theta) @case Gate(Rx(theta), loc::Locations{Int}) theta = unwrap_ssa_phase(theta, root.parent) - push_gate!(circ, Val(:X), plain(loc), (1/π)*theta) + push_gate!(circ, Val(:X), plain(loc), (1/π) * theta) @case Gate(Ry(theta), loc::Locations{Int}) theta = unwrap_ssa_phase(theta, root.parent) - push_gate!(circ, Val(:X), plain(loc), 1//2) - push_gate!(circ, Val(:Z), plain(loc), (1/π) * theta) + push_gate!(circ, Val(:X), plain(loc), 1//2) + push_gate!(circ, Val(:Z), plain(loc), (1/π) * theta) push_gate!(circ, Val(:X), plain(loc), -1//2) @case Gate(Rz(theta), loc::Locations{Int}) theta = unwrap_ssa_phase(theta, root.parent) - push_gate!(circ, Val(:Z), plain(loc), (1/π)*theta) + push_gate!(circ, Val(:Z), plain(loc), (1/π) * theta) @case Gate(AdjointOperation(&S), loc::Locations{Int}) push_gate!(circ, Val(:Z), plain(loc), 3//2) @case Gate(AdjointOperation(&T), loc::Locations{Int}) @@ -127,7 +132,51 @@ function convert_to_zxd(root::YaoHIR.BlockIR) return circ end -function convert_to_chain(circ::ZXDiagram{TT, P}) where {TT, P} +function convert_to_zxd(root::YaoHIR.BlockIR) + diagram = ZXDiagram(root.nqubits) + circuit = canonicalize_single_location(root.circuit) + gates_to_circ(diagram, circuit, root) +end + + +function push_spider_to_chain!(qc, q, ps, st) + if ps != 0 + if st == SpiderType.Z + if ps == 1 + push!(qc, Gate(Z, Locations(q))) + elseif ps == 1 // 2 + push!(qc, Gate(S, Locations(q))) + elseif ps == 3 // 2 + push!(qc, Gate(AdjointOperation(S), Locations(q))) + elseif ps == 1 // 4 + push!(qc, Gate(T, Locations(q))) + elseif ps == 7 // 4 + push!(qc, Gate(AdjointOperation(T), Locations(q))) + elseif ps != 0 + θ = ps * π + if θ isa Phase + θ = θ.ex + end + push!(qc, Gate(shift(θ), Locations(q))) + end + elseif st == SpiderType.X + if ps == 1 + push!(qc, Gate(X, Locations(q))) + else + ps != 0 + θ = ps * π + if θ isa Phase + θ = θ.ex + end + push!(qc, Gate(Rx(θ), Locations(q))) + end + elseif st == SpiderType.H + push!(qc, Gate(H, Locations(q))) + end + end +end + +function convert_to_chain(circ::ZXDiagram{TT,P}) where {TT,P} spider_seq = spider_sequence(circ) qc = [] for vs in spider_seq @@ -167,38 +216,3 @@ function convert_to_chain(circ::ZXDiagram{TT, P}) where {TT, P} return Chain(qc...) end -function push_spider_to_chain!(qc, q, ps, st) - if ps != 0 - if st == SpiderType.Z - if ps == 1 - push!(qc, Gate(Z, Locations(q))) - elseif ps == 1//2 - push!(qc, Gate(S, Locations(q))) - elseif ps == 3//2 - push!(qc, Gate(AdjointOperation(S), Locations(q))) - elseif ps == 1//4 - push!(qc, Gate(T, Locations(q))) - elseif ps == 7//4 - push!(qc, Gate(AdjointOperation(T), Locations(q))) - elseif ps != 0 - θ = ps * π - if θ isa Phase - θ = θ.ex - end - push!(qc, Gate(shift(θ), Locations(q))) - end - elseif st == SpiderType.X - if ps == 1 - push!(qc, Gate(X, Locations(q))) - else ps != 0 - θ = ps * π - if θ isa Phase - θ = θ.ex - end - push!(qc, Gate(Rx(θ), Locations(q))) - end - elseif st == SpiderType.H - push!(qc, Gate(H, Locations(q))) - end - end -end \ No newline at end of file diff --git a/src/ZX/rules.jl b/src/ZX/rules.jl index fb709a2..9ac6897 100644 --- a/src/ZX/rules.jl +++ b/src/ZX/rules.jl @@ -273,17 +273,30 @@ function Base.match(::Rule{:p3}, zxg::ZXGraph{T, P}) where {T, P} return matches end -function Base.match(::Rule{:id}, zxg::ZXGraph{T, P}) where {T, P} +function Base.match(::Rule{:id}, zxg::ZXGraph{T,P}) where {T,P} matches = Match{T}[] for v2 in spiders(zxg) nb2 = neighbors(zxg, v2) - if spider_type(zxg, v2) == SpiderType.Z && length(nb2) == 2 + if spider_type(zxg, v2) == SpiderType.Z && length(nb2) == 2 v1, v3 = nb2 if phase(zxg, v2) == 0 if spider_type(zxg, v1) == SpiderType.Z && spider_type(zxg, v3) == SpiderType.Z push!(matches, Match{T}([v1, v2, v3])) end - else phase(zxg, v2) == 1 + + if ( + ( + spider_type(zxg, v1) == SpiderType.In || + spider_type(zxg, v1) == SpiderType.Out + ) && ( + spider_type(zxg, v3) == SpiderType.In || + spider_type(zxg, v3) == SpiderType.Out + ) + ) + push!(matches, Match{T}([v1, v2, v3])) + end + else + phase(zxg, v2) == 1 if spider_type(zxg, v1) == SpiderType.Z && spider_type(zxg, v3) == SpiderType.Z if degree(zxg, v1) == 1 push!(matches, Match{T}([v1, v2, v3])) @@ -896,6 +909,11 @@ function check_rule(::Rule{:id}, zxg::ZXGraph{T, P}, vs::Vector{T}) where {T, P} if spider_type(zxg, v1) == SpiderType.Z && spider_type(zxg, v3) == SpiderType.Z return true end + if ((spider_type(zxg, v1) == SpiderType.In || spider_type(zxg, v1) == SpiderType.Out) && + (spider_type(zxg, v3) == SpiderType.In || spider_type(zxg, v3) == SpiderType.Out)) + return true + end + else phase(zxg, v2) == 1 if spider_type(zxg, v1) == SpiderType.Z && spider_type(zxg, v3) == SpiderType.Z return degree(zxg, v1) == 1 || degree(zxg, v3) == 1 @@ -913,16 +931,23 @@ function rewrite!(::Rule{:id}, zxg::ZXGraph{T, P}, vs::Vector{T}) where {T, P} set_phase!(zxg, v1, -phase(zxg, v1)) zxg.phase_ids[v1] = (zxg.phase_ids[v1][1], -zxg.phase_ids[v1][2]) end - set_phase!(zxg, v3, phase(zxg, v3)+phase(zxg, v1)) - id1, mul1 = zxg.phase_ids[v1] - id3, mul3 = zxg.phase_ids[v3] - set_phase!(zxg.master, id3, (mul3 * phase(zxg.master, id3) + mul1 * phase(zxg.master, id1)) * mul3) - set_phase!(zxg.master, id1, zero(P)) - for v in neighbors(zxg, v1) - v == v2 && continue - add_edge!(zxg, v, v3, is_hadamard(zxg, v, v1) ? EdgeType.HAD : EdgeType.SIM) + if ((spider_type(zxg, v1) == SpiderType.In || spider_type(zxg, v1) == SpiderType.Out || + spider_type(zxg, v3) == SpiderType.In || spider_type(zxg, v3) == SpiderType.Out)) + rem_spider!(zxg, v2) + add_edge!(zxg, v1, v3, EdgeType.SIM) + + else + set_phase!(zxg, v3, phase(zxg, v3)+phase(zxg, v1)) + id1, mul1 = zxg.phase_ids[v1] + id3, mul3 = zxg.phase_ids[v3] + set_phase!(zxg.master, id3, (mul3 * phase(zxg.master, id3) + mul1 * phase(zxg.master, id1)) * mul3) + set_phase!(zxg.master, id1, zero(P)) + for v in neighbors(zxg, v1) + v == v2 && continue + add_edge!(zxg, v, v3, is_hadamard(zxg, v, v1) ? EdgeType.HAD : EdgeType.SIM) + end + rem_spiders!(zxg, [v1, v2]) end - rem_spiders!(zxg, [v1, v2]) return zxg end @@ -986,4 +1011,5 @@ function rewrite!(::Rule{:scalar}, zxg::Union{ZXGraph{T, P}, ZXDiagram{T, P}}, v @inbounds v = vs[1] rem_spider!(zxg, v) return zxg -end \ No newline at end of file +end + diff --git a/src/ZX/zx_diagram.jl b/src/ZX/zx_diagram.jl index c07eb27..abfac4b 100644 --- a/src/ZX/zx_diagram.jl +++ b/src/ZX/zx_diagram.jl @@ -19,10 +19,17 @@ struct ZXDiagram{T<:Integer, P} <: AbstractZXDiagram{T, P} inputs::Vector{T} outputs::Vector{T} - function ZXDiagram{T, P}(mg::Multigraph{T}, st::Dict{T, SpiderType.SType}, ps::Dict{T, P}, - layout::ZXLayout{T}, phase_ids::Dict{T, Tuple{T, Int}} = Dict{T, Tuple{T, Int}}(), - s::Scalar{P} = Scalar{P}(), - inputs::Vector{T} = Vector{T}(), outputs::Vector{T} = Vector{T}()) where {T<:Integer, P} + function ZXDiagram{T,P}( + mg::Multigraph{T}, + st::Dict{T,SpiderType.SType}, + ps::Dict{T,P}, + layout::ZXLayout{T}, + phase_ids::Dict{T,Tuple{T,Int}} = Dict{T,Tuple{T,Int}}(), + s::Scalar{P} = Scalar{P}(), + inputs::Vector{T} = Vector{T}(), + outputs::Vector{T} = Vector{T}(), + round_phases::Bool = true, + ) where {T<:Integer,P} if nv(mg) == length(ps) && nv(mg) == length(st) if length(phase_ids) == 0 for v in vertices(mg) @@ -52,7 +59,9 @@ struct ZXDiagram{T<:Integer, P} <: AbstractZXDiagram{T, P} end end zxd = new{T, P}(mg, st, ps, layout, phase_ids, s, inputs, outputs) - round_phases!(zxd) + if round_phases + round_phases!(zxd) + end return zxd else error("There should be a phase and a type for each spider!") @@ -549,7 +558,7 @@ function generate_layout!(zxd::ZXDiagram{T, P}, seq::Vector{Any} = []) where {T, for v1 in nb if !(v1 in vs_generated) q1 = findfirst(isequal(v1), vs_frontier) - if q1 !== nothing + if !isnothing(q1) col = maximum(frontier_col[min(q, q1):max(q, q1)]) set_loc!(layout, v, q, col) set_loc!(layout, v1, q1, col) @@ -571,7 +580,7 @@ function generate_layout!(zxd::ZXDiagram{T, P}, seq::Vector{Any} = []) where {T, nb_v1 = neighbors(zxd, v1) v2 = nb_v1[findfirst(!isequal(v), nb_v1)] q2 = findfirst(isequal(v2), vs_frontier) - if q2 !== nothing + if !isnothing(q2) col = maximum(frontier_col[min(q, q2):max(q, q2)]) set_loc!(layout, v, q, col) set_loc!(layout, v2, q2, col) @@ -629,3 +638,180 @@ function safe_convert(::Type{T}, x::Real) where T<:Rational @warn "converting phase to rational, but with rounding error $(abs(fr-x))." return fr end + +""" + plot(zxd::ZXDiagram{T, P}; kwargs...) where {T, P} + +Plots a ZXDiagram using Vega. + +If called from the REPL it will open in the Browser. +Please remeber to run "using Vega, DataFrames" before, as this uses an extension +""" +plot(zxd::ZXDiagram{T, P}; kwargs...) where {T, P} = + error("missing extension, please use Vega with 'using Vega, DataFrames'") + + +""" + get_output_idx(zxd::ZXDiagram{T,P}, q::T) where {T,P} + +Get spider index of output qubit q. Returns -1 is non-existant +""" +function get_output_idx(zxd::ZXDiagram{T,P}, q::T) where {T,P} + for v in get_outputs(zxd) + if spider_type(zxd, v) == SpiderType.Out && Int(qubit_loc(zxd, v)) == q + res = v + else + res = nothing + end + + !isnothing(res) && return res + end + return -1 +end + +""" + import_non_in_out!(d1::ZXDiagram{T,P}, d2::ZXDiagram{T,P}, v2tov1::Dict{T,T}) where {T,P} + +Add non input and output spiders of d2 to d1, modify d1. Record the mapping of vertex indices. +""" +function import_non_in_out!( + d1::ZXDiagram{T,P}, + d2::ZXDiagram{T,P}, + v2tov1::Dict{T,T}, +) where {T,P} + for v2 in vertices(d2.mg) + st = spider_type(d2, v2) + if st == SpiderType.In || st == SpiderType.Out + new_v = nothing + # FIXME why is Out = H ? + elseif st == SpiderType.Z || st == SpiderType.X || st == SpiderType.H + new_v = add_vertex!(d1.mg)[1] + else + throw(ArgumentError("Unknown spider type $(d2.st[v2])")) + end + if !isnothing(new_v) + v2tov1[v2] = new_v + d1.st[new_v] = spider_type(d2, v2) + d1.ps[new_v] = d2.ps[v2] + d1.phase_ids[new_v] = (v2, 1) + end + end +end + +nout(zxd::ZXDiagram) = length(zxd.outputs) +nin(zxd::ZXDiagram) = length(zxd.inputs) + +""" + get_input_idx(zwd::ZXDiagram{T,P}, q::T) where {T,P} + +Get spider index of input qubit q. Returns -1 if non-existant +""" +function get_input_idx(zxd::ZXDiagram{T,P}, q::T) where {T,P} + for v in get_inputs(zxd) + if spider_type(zxd, v) == SpiderType.In && Int(qubit_loc(zxd, v)) == q + res = v + else + res = nothing + end + + !isnothing(res) && return res + end + return -1 +end + + +""" + import_edges!(d1::ZXDiagram{T,P}, d2::ZXDiagram{T,P}, v2tov1::Dict{T,T}) where {T,P} + +Import edges of d2 to d1, modify d1 +""" +function import_edges!(d1::ZXDiagram{T,P}, d2::ZXDiagram{T,P}, v2tov1::Dict{T,T}) where {T,P} + for edge in edges(d2.mg) + src, dst, emul = edge.src, edge.dst, edge.mul + add_edge!(d1.mg, v2tov1[src], v2tov1[dst], emul) + end +end + +""" + concat!(zxd_1::ZXDiagram{T,P}, zxd_2::ZXDiagram{T,P})::ZXDiagram{T,P} where {T,P} + +Appends two diagrams, where the second diagram is inverted +""" +function concat!(zxd_1::ZXDiagram{T,P}, zxd_2::ZXDiagram{T,P})::ZXDiagram{T,P} where {T,P} + nqubits(zxd_1) == nqubits(zxd_2) || throw( + ArgumentError( + "number of qubits need to be equal, go $(nqubits(zxd_1)) and $(nqubits(zxd_2))", + ), + ) + + v2tov1 = Dict{T,T}() + import_non_in_out!(zxd_1, zxd_2, v2tov1) + + for i = 1:nout(zxd_1) + out_idx = get_output_idx(zxd_1, i) + # output spiders cannot be connected to multiple vertices or with multiedge + prior_vtx = neighbors(zxd_1, out_idx)[1] + rem_edge!(zxd_1, out_idx, prior_vtx) + # zxd_2 input vtx idx is mapped to the vtx prior to zxd_1 output + v2tov1[get_input_idx(zxd_2, i)] = prior_vtx + end + + for i = 1:nout(zxd_2) + v2tov1[get_output_idx(zxd_2, i)] = get_output_idx(zxd_1, i) + end + + import_edges!(zxd_1, zxd_2, v2tov1) + add_global_phase!(zxd_1, zxd_2.scalar.phase) + add_power!(zxd_1, zxd_2.scalar.power_of_sqrt_2) + + return zxd_1 +end + +""" + stype_to_val(st)::Union{SpiderType,nothing} + +Converts SpiderType into Val +""" +function stype_to_val(st)::Val + if st == SpiderType.Z + Val{:Z}() + elseif st == SpiderType.X + Val{:X}() + elseif st == SpiderType.H + Val{:H}() + else + throw(ArgumentError("$st has no corresponding SpiderType")) + end +end + + + +""" + dagger(zxd::ZXDiagram{T,P})::ZXDiagram{T,P} where {T,P} + +Dagger of a ZXDiagram by swapping input and outputs and negating the values of the phases +""" + +function dagger(zxd::ZXDiagram{T,P})::ZXDiagram{T,P} where {T,P} + ps_i = Dict([k => -v for (k, v) in zxd.ps]) + zxd_dg = ZXDiagram{T,P}( + copy(zxd.mg), + copy(zxd.st), + ps_i, + copy(zxd.layout), + deepcopy(zxd.phase_ids), + copy(zxd.scalar), + copy(zxd.outputs), + copy(zxd.inputs), + false, + ) + for v in vertices(zxd_dg.mg) + value = zxd_dg.st[v] + if value == SpiderType.In + zxd_dg.st[v] = SpiderType.Out + elseif (value == SpiderType.Out) + zxd_dg.st[v] = SpiderType.In + end + end + return zxd_dg +end diff --git a/src/ZX/zx_graph.jl b/src/ZX/zx_graph.jl index f70f95d..6d11b00 100644 --- a/src/ZX/zx_graph.jl +++ b/src/ZX/zx_graph.jl @@ -9,11 +9,14 @@ This is the type for representing the graph-like ZX-diagrams. """ struct ZXGraph{T<:Integer, P} <: AbstractZXDiagram{T, P} mg::Multigraph{T} + ps::Dict{T, P} st::Dict{T, SpiderType.SType} et::Dict{Tuple{T, T}, EdgeType.EType} + layout::ZXLayout{T} phase_ids::Dict{T,Tuple{T, Int}} + scalar::Scalar{P} master::ZXDiagram{T, P} inputs::Vector{T} @@ -160,7 +163,7 @@ nqubits(zxg::ZXGraph) = zxg.layout.nbits qubit_loc(zxg::ZXGraph{T, P}, v::T) where {T, P} = qubit_loc(zxg.layout, v) function column_loc(zxg::ZXGraph{T, P}, v::T) where {T, P} c_loc = column_loc(zxg.layout, v) - if c_loc !== nothing + if !isnothing(c_loc) if spider_type(zxg, v) == SpiderType.Out nb = neighbors(zxg, v) if length(nb) == 1 @@ -177,7 +180,7 @@ function column_loc(zxg::ZXGraph{T, P}, v::T) where {T, P} c_loc = ceil(column_loc(zxg, nb) - 2) end end - c_loc !== nothing && return c_loc + !isnothing(c_loc) && return c_loc return 0 end @@ -299,7 +302,7 @@ function spider_sequence(zxg::ZXGraph{T, P}) where {T, P} spider_seq[q] = Vector{T}() end for v in vs - if qubit_loc(zxg, v) !== nothing + if !isnothing(qubit_loc(zxg, v)) q_loc = Int(qubit_loc(zxg, v)) q_loc > 0 && push!(spider_seq[q_loc], v) end @@ -376,3 +379,7 @@ function add_power!(zxg::ZXGraph, n) add_power!(zxg.scalar, n) return zxg end + + +plot(zxd::ZXGraph{T, P}; kwargs...) where {T, P} = + error("missing extension, please use Vega with 'using Vega, DataFrames'") diff --git a/src/ZXW/ZXW.jl b/src/ZXW/ZXW.jl index fd0e220..bde7443 100644 --- a/src/ZXW/ZXW.jl +++ b/src/ZXW/ZXW.jl @@ -4,10 +4,12 @@ using Expronicon.ADT: @const_use, @adt using MLStyle, Multigraphs, Graphs using ..Utils: Scalar, Phase, Parameter, PiUnit, Factor, add_phase! using ..ZX: safe_convert, AbstractRule, Rule, Match +using YaoHIR +using YaoHIR: BlockIR import ..Utils: add_power! import ..ZX: - rewrite!, simplify!, push_gate!, pushfirst_gate!, spiders, rem_spider!, rem_spiders! + rewrite!, simplify!, push_gate!, pushfirst_gate!, spiders, rem_spider!, rem_spiders!, canonicalize_single_location, gates_to_circ export ZXWDiagram, substitute_variables! diff --git a/src/ZXW/utils.jl b/src/ZXW/utils.jl index 8b7c056..19179c9 100644 --- a/src/ZXW/utils.jl +++ b/src/ZXW/utils.jl @@ -667,3 +667,14 @@ function substitute_variables!( end return zxwd end + + +function convert_to_zxwd(root::YaoHIR.BlockIR) + # FIXME add test + diagram = ZXWDiagram(root.nqubits) + circuit = canonicalize_single_location(root.circuit) + gates_to_circ(diagram, circuit, root) +end + + + diff --git a/src/ZXW/zxw_diagram.jl b/src/ZXW/zxw_diagram.jl index dd4909b..adfd9f9 100644 --- a/src/ZXW/zxw_diagram.jl +++ b/src/ZXW/zxw_diagram.jl @@ -81,6 +81,10 @@ function ZXWDiagram(nbits::T) where {T<:Integer} end + +ZXWDiagram(bir::BlockIR) = convert_to_zxwd(bir) + + Base.copy(zxwd::ZXWDiagram{T,P}) where {T,P} = ZXWDiagram{T,P}( copy(zxwd.mg), copy(zxwd.st), diff --git a/test/ancilla_extraction.jl b/test/ancilla_extraction.jl index 1a5e787..1cc9531 100644 --- a/test/ancilla_extraction.jl +++ b/test/ancilla_extraction.jl @@ -17,14 +17,14 @@ zxd = gen_phase_gadget() zxg = full_reduction(zxd) anc_circ = ancilla_extraction(zxg) -# plot(anc_circ) +@test !isnothing(plot(anc_circ)) zxd_swap = ZXDiagram(2) pushfirst_gate!(zxd_swap, Val(:SWAP), [1, 2]) -# plot(zxd_swap) +plot(zxd_swap) convert_to_chain(zxd_swap) zxg_swap = ZXGraph(zxd_swap) zxd_anc = ancilla_extraction(zxg_swap) -# plot(zxd_anc) +@test !isnothing(plot(zxd_anc)) @test length(ZX.convert_to_chain(zxd_anc)) == 3 diff --git a/test/challenge.jl b/test/challenge.jl index b9eacf4..d63e69d 100644 --- a/test/challenge.jl +++ b/test/challenge.jl @@ -208,4 +208,5 @@ for i = 1:5 push!(zxg.outputs, i+23) end +@test !isnothing(plot(zxg)) ZX.ancilla_extraction(zxg) diff --git a/test/circuit_extraction.jl b/test/circuit_extraction.jl index 0c83041..561bb35 100644 --- a/test/circuit_extraction.jl +++ b/test/circuit_extraction.jl @@ -38,3 +38,9 @@ zxg2 = clifford_simplification(zxd) zxg3 = full_reduction(zxd) cir = circuit_extraction(zxg3) + +# Plotting +@test !isnothing(plot(zxd)) +@test !isnothing(plot(zxg)) +@test !isnothing(plot(zxg2)) +@test !isnothing(plot(zxg3)) diff --git a/test/equality.jl b/test/equality.jl new file mode 100644 index 0000000..03df647 --- /dev/null +++ b/test/equality.jl @@ -0,0 +1,25 @@ +using YaoHIR: BlockIR +using YaoHIR, YaoLocations +using Core.Compiler: IRCode + +chain = Chain() +push_gate!(chain, Val(:H), 1) +push_gate!(chain, Val(:H), 2) +push_gate!(chain, Val(:H), 3) +push_gate!(chain, Val(:H), 4) +push_gate!(chain, Val(:CNOT), 4, 1) +push_gate!(chain, Val(:CNOT), 4, 3) +push_gate!(chain, Val(:X), 1) +push_gate!(chain, Val(:X), 2) +push_gate!(chain, Val(:X), 3) + +bir = BlockIR(IRCode(), 4, chain) +d1 = ZXDiagram(bir) + +# create second version +d2 = copy(d1) +# Push H spider with Val spidertype +push_gate!(d2, Val(:H), 1) + +@test verify_equality(copy(d1), copy(d1)) == true +@test verify_equality(copy(d1), copy(d2)) == false diff --git a/test/ir.jl b/test/ir.jl index 3c7f3fa..f84bbdc 100644 --- a/test/ir.jl +++ b/test/ir.jl @@ -1,8 +1,8 @@ using Test -using ZXCalculus +using ZXCalculus.ZXW +using ZXCalculus, ZXCalculus.ZX, ZXCalculus.Utils using YaoHIR, YaoLocations -using YaoHIR.IntrinsicOperation -using CompilerPluginTools +using Core.Compiler: IRCode chain = Chain() push_gate!(chain, Val(:Sdag), 1) @@ -33,113 +33,293 @@ push_gate!(chain, Val(:S), 3) push_gate!(chain, Val(:X), 4) push_gate!(chain, Val(:CNOT), 3, 2) push_gate!(chain, Val(:H), 1) -push_gate!(chain, Val(:shift), 4, ZXCalculus.Phase(1//2)) -push_gate!(chain, Val(:Rx), 4, ZXCalculus.Phase(1//1)) -push_gate!(chain, Val(:Rx), 3, ZXCalculus.Phase(1//4)) -push_gate!(chain, Val(:Rx), 2, ZXCalculus.Phase(1//4)) +push_gate!(chain, Val(:shift), 4, Phase(1 // 2)) +push_gate!(chain, Val(:Rx), 4, Phase(1 // 1)) +push_gate!(chain, Val(:Rx), 3, Phase(1 // 4)) +push_gate!(chain, Val(:Rx), 2, Phase(1 // 4)) push_gate!(chain, Val(:S), 3) -ir = @make_ircode begin -end -bir = BlockIR(ir, 4, chain) -zxd = convert_to_zxd(bir) -convert_to_chain(zxd) -pt_zxd = phase_teleportation(zxd) -@test tcount(pt_zxd) <= tcount(zxd) -pt_chain = convert_to_chain(pt_zxd) -@test length(pt_chain) <= length(chain) - -zxg = clifford_simplification(zxd) -cl_chain = circuit_extraction(zxg) - -zxg = full_reduction(zxd) -fl_chain = circuit_extraction(zxg) -ZXCalculus.generate_layout!(zxg) -@test ZXCalculus.qubit_loc(zxg, 40) == 0//1 -ZXCalculus.spider_sequence(zxg) - -pt_bir = phase_teleportation(bir) -cl_bir = clifford_simplification(bir) -fl_bir = full_reduction(bir) - -@test length(pt_chain) == length(pt_bir.circuit) -@test length(cl_chain) == length(cl_bir.circuit) -@test length(fl_chain) == length(fl_bir.circuit) - -@testset "issue#80" begin - ir = @make_ircode begin - end - circuit = Chain(Gate(X, Locations(1)), Gate(X, Locations(1))) - bir = BlockIR(ir, 1, circuit) - bir = clifford_simplification(bir) - bir = clifford_simplification(bir) - @test bir.circuit == Chain(Gate(H, Locations((1, ))), Gate(H, Locations((1, )))) -end +@testset "ir.jl" begin + # Shadow operation in ir.jl testset, so that they do not overrride SpiderTypes + X = YaoHIR.IntrinsicOperation.X + Z = YaoHIR.IntrinsicOperation.Z + H = YaoHIR.IntrinsicOperation.H + T = YaoHIR.IntrinsicOperation.T + S = YaoHIR.IntrinsicOperation.S + SGate = YaoHIR.IntrinsicOperation.SGate -@testset "generate_layout!" begin - circ = Chain(Gate(H, Locations(2)), Gate(T, Locations(4)), Gate(H, Locations(1)), Gate(AdjointOperation{SGate}(S), Locations(2)), Gate(H, Locations(2)), Gate(X, Locations(3)), Gate(AdjointOperation{SGate}(S), Locations(1)), Gate(Z, Locations(1)), Gate(H, Locations(2)), Gate(X, Locations(1)), Gate(Z, Locations(1)), Gate(T, Locations(5)), Ctrl(Gate(X, Locations(5)), CtrlLocations(1)), Gate(H, Locations(1)), Gate(T, Locations(1)), Ctrl(Gate(X, Locations(3)), CtrlLocations(5)), Gate(H, Locations(1)), Gate(X, Locations(4)), Ctrl(Gate(X, Locations(5)), CtrlLocations(4)), Gate(S, Locations(2)), Ctrl(Gate(X, Locations(1)), CtrlLocations(3)), Gate(X, Locations(2)), Ctrl(Gate(X, Locations(3)), CtrlLocations(1)), Gate(X, Locations(2)), Gate(S, Locations(3)), Gate(Z, Locations(2)), Gate(Z, Locations(5)), Gate(X, Locations(2)), Gate(X, Locations(1)), Ctrl(Gate(X, Locations(3)), CtrlLocations(5)), Gate(S, Locations(4)), Gate(X, Locations(3)), Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), Gate(AdjointOperation{SGate}(S), Locations(4)), Gate(Z, Locations(2)), Gate(AdjointOperation{SGate}(S), Locations(5)), Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), Gate(Z, Locations(5)), Ctrl(Gate(X, Locations(1)), CtrlLocations(4)), Ctrl(Gate(X, Locations(3)), CtrlLocations(4)), Gate(H, Locations(4)), Gate(Z, Locations(1)), Gate(X, Locations(4)), Gate(Z, Locations(3)), Gate(H, Locations(4)), Ctrl(Gate(X, Locations(1)), CtrlLocations(4)), Ctrl(Gate(X, Locations(4)), CtrlLocations(1)), Gate(X, Locations(4)), Gate(S, Locations(3)), Gate(AdjointOperation{SGate}(S), Locations(2)), Gate(Z, Locations(3)), Gate(S, Locations(5)), Ctrl(Gate(X, Locations(3)), CtrlLocations(5)), Gate(H, Locations(2)), Gate(Z, Locations(4)), Gate(H, Locations(1)), Gate(X, Locations(1)), Gate(X, Locations(2)), Ctrl(Gate(X, Locations(5)), CtrlLocations(3)), Ctrl(Gate(X, Locations(1)), CtrlLocations(3)), Gate(Z, Locations(4)), Gate(S, Locations(5)), Gate(S, Locations(5)), Ctrl(Gate(X, Locations(5)), CtrlLocations(1)), Gate(T, Locations(4)), Gate(Z, Locations(2)), Gate(X, Locations(4)), Gate(H, Locations(2)), Gate(AdjointOperation{SGate}(S), Locations(3)), Gate(H, Locations(5)), Gate(T, Locations(2)), Gate(AdjointOperation{SGate}(S), Locations(5)), Gate(AdjointOperation{SGate}(S), Locations(4)), Gate(H, Locations(2)), Gate(S, Locations(2)), Gate(AdjointOperation{SGate}(S), Locations(3)), Ctrl(Gate(X, Locations(5)), CtrlLocations(1)), Gate(H, Locations(5)), Ctrl(Gate(X, Locations(4)), CtrlLocations(3)), Gate(H, Locations(4)), Gate(Z, Locations(2)), Gate(H, Locations(2)), Gate(S, Locations(2)), Gate(H, Locations(4)), Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), Gate(X, Locations(4)), Gate(H, Locations(1)), Gate(AdjointOperation{SGate}(S), Locations(5)), Gate(X, Locations(1)), Gate(X, Locations(3)), Gate(Z, Locations(1)), Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), Gate(T, Locations(3)), Gate(X, Locations(4)), Gate(X, Locations(3)), Gate(AdjointOperation{SGate}(S), Locations(1)), Gate(AdjointOperation{SGate}(S), Locations(3)), Gate(H, Locations(5)), Gate(S, Locations(4)), Gate(Z, Locations(4))) - ir = @make_ircode begin end - bir = BlockIR(ir, 5, circ) + + + ir = IRCode() + bir = BlockIR(ir, 4, chain) zxd = ZXDiagram(bir) - zxg = ZXGraph(zxd) - full_reduction(zxg) - ZXCalculus.generate_layout!(zxg) - @test ZXCalculus.generate_layout!(zxg) !== nothing -end + zxwd = ZXWDiagram(bir) -function random_circuit(nbits, ngates; T = 0.1, CZ = 0.0, CNOT = 0.1) - ir = @make_ircode begin + + @testset "convert SpiderType to Val" begin + @test ZX.stype_to_val(SpiderType.Z) == Val{:Z}() + @test ZX.stype_to_val(SpiderType.X) == Val{:X}() + @test ZX.stype_to_val(SpiderType.H) == Val{:H}() + @test_throws ArgumentError ZX.stype_to_val("anything else") end + + @testset "convert BlockIR into ZXWDiagram" begin + @test !isnothing(zxwd) end - CLIFF = 1 - T - CZ - CNOT - circ = Chain() - for _ = 1:ngates - x = rand() - nbits == 1 && (x = x*(CLIFF+T)) - if x <= CLIFF - g = rand([:X, :X, :Z, :Z, :S, :Sdag, :H, :H]) - push_gate!(circ, Val(g), rand(1:nbits)) - elseif x - CLIFF <= T - g = rand([:T, :Tdag]) - push_gate!(circ, Val(g), rand(1:nbits)) - elseif x - CLIFF - T <= CZ - loc = rand(1:nbits) - ctrl = loc - while ctrl == loc - ctrl = rand(1:nbits) - end - push_gate!(circ, Val(:CZ), loc, ctrl) - else - loc = rand(1:nbits) - ctrl = loc - while ctrl == loc - ctrl = rand(1:nbits) + + + @testset "create Matrix from ZXDiagram" begin + matrix_from_zxd = + Matrix(ZXWDiagram(BlockIR(IRCode(), 4, circuit_extraction(full_reduction(zxd))))) + @test !isnothing(matrix_from_zxd) + end + + + + @testset "BlockIR to Matrix" begin + @test !isnothing(Matrix(zxwd)) + end + + @test !isnothing(plot(zxd)) + convert_to_chain(zxd) + pt_zxd = phase_teleportation(zxd) + @test tcount(pt_zxd) <= tcount(zxd) + pt_chain = convert_to_chain(pt_zxd) + @test length(pt_chain) <= length(chain) + + zxg = clifford_simplification(zxd) + @test !isnothing(plot(zxg)) + cl_chain = circuit_extraction(zxg) + + zxg = full_reduction(zxd) + @test !isnothing(plot(zxg)) + fl_chain = circuit_extraction(zxg) + ZX.generate_layout!(zxg) + @test ZX.qubit_loc(zxg, 40) == 0 // 1 + ZX.spider_sequence(zxg) + + pt_bir = phase_teleportation(bir) + cl_bir = clifford_simplification(bir) + fl_bir = full_reduction(bir) + + @test length(pt_chain) == length(pt_bir.circuit) + @test length(cl_chain) == length(cl_bir.circuit) + @test length(fl_chain) == length(fl_bir.circuit) + + @testset "issue#80" begin + ir = IRCode() + circuit = Chain(Gate(X, Locations(1)), Gate(X, Locations(1))) + bir = BlockIR(ir, 1, circuit) + bir = clifford_simplification(bir) + bir = clifford_simplification(bir) + @test bir.circuit == Chain(Gate(H, Locations((1,))), Gate(H, Locations((1,)))) + end + + @testset "generate_layout!" begin + + circ = Chain( + Gate(H, Locations(2)), + Gate(T, Locations(4)), + Gate(H, Locations(1)), + Gate(AdjointOperation{SGate}(S), Locations(2)), + Gate(H, Locations(2)), + Gate(X, Locations(3)), + Gate(AdjointOperation{SGate}(S), Locations(1)), + Gate(Z, Locations(1)), + Gate(H, Locations(2)), + Gate(X, Locations(1)), + Gate(Z, Locations(1)), + Gate(T, Locations(5)), + Ctrl(Gate(X, Locations(5)), CtrlLocations(1)), + Gate(H, Locations(1)), + Gate(T, Locations(1)), + Ctrl(Gate(X, Locations(3)), CtrlLocations(5)), + Gate(H, Locations(1)), + Gate(X, Locations(4)), + Ctrl(Gate(X, Locations(5)), CtrlLocations(4)), + Gate(S, Locations(2)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(3)), + Gate(X, Locations(2)), + Ctrl(Gate(X, Locations(3)), CtrlLocations(1)), + Gate(X, Locations(2)), + Gate(S, Locations(3)), + Gate(Z, Locations(2)), + Gate(Z, Locations(5)), + Gate(X, Locations(2)), + Gate(X, Locations(1)), + Ctrl(Gate(X, Locations(3)), CtrlLocations(5)), + Gate(S, Locations(4)), + Gate(X, Locations(3)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), + Gate(AdjointOperation{SGate}(S), Locations(4)), + Gate(Z, Locations(2)), + Gate(AdjointOperation{SGate}(S), Locations(5)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), + Gate(Z, Locations(5)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(4)), + Ctrl(Gate(X, Locations(3)), CtrlLocations(4)), + Gate(H, Locations(4)), + Gate(Z, Locations(1)), + Gate(X, Locations(4)), + Gate(Z, Locations(3)), + Gate(H, Locations(4)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(4)), + Ctrl(Gate(X, Locations(4)), CtrlLocations(1)), + Gate(X, Locations(4)), + Gate(S, Locations(3)), + Gate(AdjointOperation{SGate}(S), Locations(2)), + Gate(Z, Locations(3)), + Gate(S, Locations(5)), + Ctrl(Gate(X, Locations(3)), CtrlLocations(5)), + Gate(H, Locations(2)), + Gate(Z, Locations(4)), + Gate(H, Locations(1)), + Gate(X, Locations(1)), + Gate(X, Locations(2)), + Ctrl(Gate(X, Locations(5)), CtrlLocations(3)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(3)), + Gate(Z, Locations(4)), + Gate(S, Locations(5)), + Gate(S, Locations(5)), + Ctrl(Gate(X, Locations(5)), CtrlLocations(1)), + Gate(T, Locations(4)), + Gate(Z, Locations(2)), + Gate(X, Locations(4)), + Gate(H, Locations(2)), + Gate(AdjointOperation{SGate}(S), Locations(3)), + Gate(H, Locations(5)), + Gate(T, Locations(2)), + Gate(AdjointOperation{SGate}(S), Locations(5)), + Gate(AdjointOperation{SGate}(S), Locations(4)), + Gate(H, Locations(2)), + Gate(S, Locations(2)), + Gate(AdjointOperation{SGate}(S), Locations(3)), + Ctrl(Gate(X, Locations(5)), CtrlLocations(1)), + Gate(H, Locations(5)), + Ctrl(Gate(X, Locations(4)), CtrlLocations(3)), + Gate(H, Locations(4)), + Gate(Z, Locations(2)), + Gate(H, Locations(2)), + Gate(S, Locations(2)), + Gate(H, Locations(4)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), + Gate(X, Locations(4)), + Gate(H, Locations(1)), + Gate(AdjointOperation{SGate}(S), Locations(5)), + Gate(X, Locations(1)), + Gate(X, Locations(3)), + Gate(Z, Locations(1)), + Ctrl(Gate(X, Locations(1)), CtrlLocations(2)), + Gate(T, Locations(3)), + Gate(X, Locations(4)), + Gate(X, Locations(3)), + Gate(AdjointOperation{SGate}(S), Locations(1)), + Gate(AdjointOperation{SGate}(S), Locations(3)), + Gate(H, Locations(5)), + Gate(S, Locations(4)), + Gate(Z, Locations(4)), + ) + ir = IRCode() + bir = BlockIR(ir, 5, circ) + zxd = ZXDiagram(bir) + zxg = ZXGraph(zxd) + full_reduction(zxg) + ZX.generate_layout!(zxg) + @test !isnothing(plot(zxg)) + @test !isnothing(ZX.generate_layout!(zxg)) + end + + + @testset "generate_layout with chain" begin + bir = BlockIR(ir, 5, chain) + zxd = ZXDiagram(bir) + zxg = ZXGraph(zxd) + full_reduction(zxg) + ZX.generate_layout!(zxg) + @test !isnothing(plot(zxg)) + @test !isnothing(ZX.generate_layout!(zxg)) + + end + + function random_circuit(nbits, ngates; T = 0.1, CZ = 0.0, CNOT = 0.1) + ir = IRCode() + CLIFF = 1 - T - CZ - CNOT + circ = Chain() + for _ = 1:ngates + x = rand() + nbits == 1 && (x = x * (CLIFF + T)) + if x <= CLIFF + g = rand([:X, :X, :Z, :Z, :S, :Sdag, :H, :H]) + push_gate!(circ, Val(g), rand(1:nbits)) + elseif x - CLIFF <= T + g = rand([:T, :Tdag]) + push_gate!(circ, Val(g), rand(1:nbits)) + elseif x - CLIFF - T <= CZ + loc = rand(1:nbits) + ctrl = loc + while ctrl == loc + ctrl = rand(1:nbits) + end + push_gate!(circ, Val(:CZ), loc, ctrl) + else + loc = rand(1:nbits) + ctrl = loc + while ctrl == loc + ctrl = rand(1:nbits) + end + push_gate!(circ, Val(:CNOT), loc, ctrl) end - push_gate!(circ, Val(:CNOT), loc, ctrl) end + return BlockIR(ir, nbits, circ) end - return BlockIR(ir, nbits, circ) -end -function random_identity(nbits, ngates; T = 0.1, CZ = 0.0, CNOT = 0.1) - bir = random_circuit(nbits, ngates; T = T, CZ = CZ, CNOT = CNOT) - c = bir.circuit.args - for i = length(c):-1:1 - if c[i] isa Gate - g = c[i].operation - if (g in (S, YaoHIR.IntrinsicOperation.T)) || (g isa AdjointOperation) - push!(c, Gate(g', c[i].locations)) + function random_identity(nbits, ngates; T = 0.1, CZ = 0.0, CNOT = 0.1) + bir = random_circuit(nbits, ngates; T = T, CZ = CZ, CNOT = CNOT) + c = bir.circuit.args + for i = length(c):-1:1 + if c[i] isa Gate + g = c[i].operation + if (g in (YaoHIR.IntrinsicOperation.S, YaoHIR.IntrinsicOperation.T)) || + (g isa AdjointOperation) + push!(c, Gate(g', c[i].locations)) + else + push!(c, c[i]) + end else push!(c, c[i]) end - else - push!(c, c[i]) end + return bir end - return bir -end -circ = random_identity(5, 50); -zxd = convert_to_zxd(circ) -zxg = ZXGraph(zxd) -zxg |> clifford_simplification |> full_reduction + @testset "plot random_identity" begin + circ = random_identity(5, 50) + zxd = convert_to_zxd(circ) + @test !isnothing(plot(zxd)) + zxg = ZXGraph(zxd) + @test !isnothing(plot(zxg)) + @test !isnothing(plot(zxg |> clifford_simplification |> full_reduction)) + end + + @testset "gates_to_circ with addition Ry" begin + n_qubits = 4 + # TODO add tests for Ry gate + chain_a = Chain() + push_gate!(chain_a, Val(:Ry), n_qubits, Phase(1 // 1)) + push_gate!(chain_a, Val(:Rz), 4, Phase(1 // 1)) + bir = BlockIR(ir, n_qubits, chain_a) + + diagram = ZXDiagram(n_qubits) + ZX.gates_to_circ(diagram, chain_a, bir) + end + + # TODO add test that checks if error is thrown for unkown gate + + @testset "Chain of ZXDiagram" begin + # FIXME add better equal for Chain + # @test chain.args == Chain(ZXDiagram(bir)).args + # @test chain.args == Chain(ZXDiagram(bir)).args + @test !isnothing(Chain(zxd)) + end + +end diff --git a/test/phase.jl b/test/phase.jl index b5865a0..dba45de 100644 --- a/test/phase.jl +++ b/test/phase.jl @@ -1,25 +1,19 @@ using Test using ZXCalculus.Utils: Phase -# ir = @make_ircode begin -# Expr(:call, :+, 1, 1)::Int -# Expr(:call, :+, 3, 3)::Int -# end +chain = Chain() +push_gate!(chain, Val(:shift), 1, Phase(1 // 1)) +push_gate!(chain, Val(:Rz), 1, Phase(2 // 1)) -# circ = Chain( -# Gate(shift(1.0), Locations(1)), -# Gate(Rz(Core.SSAValue(2)), Locations(1)), -# ) +bir = BlockIR(IRCode(), 4, chain) -# bir = BlockIR(ir, 4, circ) +zxd = convert_to_zxd(bir) +c = clifford_simplification(zxd) +ZX.generate_layout!(zxd) +qc_tl = convert_to_chain(phase_teleportation(zxd)) +@test length(qc_tl) == 1 -# zxd = convert_to_zxd(bir) -# c = clifford_simplification(zxd) -# ZXCalculus.generate_layout!(zxd) -# qc_tl = convert_to_chain(phase_teleportation(zxd)) -# @test length(qc_tl) == 1 - -p = Phase(1//1) +p = Phase(1 // 1) @test p + 1 == 1 + p == p + p @test p - 1 == 1 - p == p - p diff --git a/test/phase_teleportation.jl b/test/phase_teleportation.jl index bf350e6..3269521 100644 --- a/test/phase_teleportation.jl +++ b/test/phase_teleportation.jl @@ -75,6 +75,8 @@ function gen_cir() end cir = gen_cir() +@test !isnothing(cir) @test tcount(cir) == 28 cir2 = phase_teleportation(cir) +@test !isnothing(plot(cir2)) @test tcount(cir2) == 8 diff --git a/test/plots.jl b/test/plots.jl new file mode 100644 index 0000000..069cd23 --- /dev/null +++ b/test/plots.jl @@ -0,0 +1,13 @@ +using Test, ZXCalculus, ZXCalculus.ZX +using ZXCalculus: ZX + + +# Othertests for ZXGraphs and ZXDigram are embededd into the zx_graph and zx_diagram testsets +zxd = ZXDiagram(3) +ZX.insert_spider!(zxd, 1, 2, SpiderType.H) +ZX.insert_spider!(zxd, 1, 2, SpiderType.X) +ZX.insert_spider!(zxd, 1, 2, SpiderType.Z) +zxg = ZXGraph(zxd) + +@test !isnothing(plot(zxd)) +@test !isnothing(plot(zxg)) diff --git a/test/rules.jl b/test/rules.jl index bcc6d1e..b951ec9 100644 --- a/test/rules.jl +++ b/test/rules.jl @@ -10,6 +10,7 @@ matches = match(Rule{:f}(), zxd) rewrite!(Rule{:f}(), zxd, matches) @test sort!(spiders(zxd)) == [1, 3] @test phase(zxd, 1) == phase(zxd, 3) == 3 // 4 +@test !isnothing(zxd) g = Multigraph(path_graph(5)) add_edge!(g, 1, 2) @@ -19,6 +20,7 @@ zxd = ZXDiagram(g, v_t, ps) matches = match(Rule{:i1}(), zxd) rewrite!(Rule{:i1}(), zxd, matches) @test nv(zxd) == 3 && ne(zxd, count_mul = true) == 3 && ne(zxd) == 2 +@test !isnothing(zxd) g = Multigraph([0 2 0; 2 0 1; 0 1 0]) ps = [i // 4 for i = 1:3] @@ -27,6 +29,7 @@ zxd = ZXDiagram(g, v_t, ps) matches = match(Rule{:h}(), zxd) rewrite!(Rule{:h}(), zxd, matches) @test nv(zxd) == 8 && ne(zxd) == 8 +@test !isnothing(zxd) matches = match(Rule{:i2}(), zxd) rewrite!(Rule{:i2}(), zxd, matches) @@ -52,6 +55,8 @@ matches = match(Rule{:pi}(), zxd) rewrite!(Rule{:pi}(), zxd, matches) @test nv(zxd) == 8 && ne(zxd) == 7 @test zxd.scalar == Scalar(0, 1 // 2) +# FIXME generate layout does not terminat +# @test !isnothing(zxd) g = Multigraph([0 2 0; 2 0 1; 0 1 0]) ps = [1, 1 // 2, 0] @@ -61,6 +66,7 @@ matches = match(Rule{:pi}(), zxd) rewrite!(Rule{:pi}(), zxd, matches) @test nv(zxd) == 4 && ne(zxd) == 3 && ne(zxd, count_mul = true) == 4 @test zxd.scalar == Scalar(0, 1 // 2) +@test !isnothing(zxd) g = Multigraph(5) add_edge!(g, 1, 2) @@ -74,6 +80,8 @@ matches = match(Rule{:c}(), zxd) rewrite!(Rule{:c}(), zxd, matches) @test nv(zxd) == 7 && ne(zxd) == 4 @test zxd.scalar == Scalar(-3, 0 // 1) +# FIXME generate layout does not terminate +# @test !isnothing(zxd) g = Multigraph(6) add_edge!(g, 1, 3) @@ -100,6 +108,7 @@ matches = match(Rule{:b}(), zxd) rewrite!(Rule{:b}(), zxd, matches) @test nv(zxd) == 8 && ne(zxd) == 8 @test zxd.scalar == Scalar(1, 0 // 1) +@test !isnothing(zxd) g = Multigraph(9) for e in [[2, 6], [3, 7], [4, 8], [5, 9]] @@ -127,6 +136,7 @@ replace!(Rule{:lc}(), zxg) phase(zxg, 3) == 7 // 4 && phase(zxg, 4) == 0 // 1 && phase(zxg, 5) == 1 // 4 +@test !isnothing(zxd) g = Multigraph(14) for e in [[3, 9], [4, 10], [5, 11], [6, 12], [7, 13], [8, 14]] @@ -178,6 +188,7 @@ end @test length(match(Rule{:p1}(), zxg)) == 1 replace!(Rule{:pab}(), zxg) @test nv(zxg) == 7 && ne(zxg) == 6 +@test !isnothing(zxg) g = Multigraph(14) for e in [[3, 9], [4, 10], [5, 11], [6, 12], [7, 13], [8, 14]] @@ -207,6 +218,7 @@ end match(Rule{:p2}(), zxg) replace!(Rule{:p2}(), zxg) @test zxg.phase_ids[15] == (2, -1) +@test !isnothing(zxg) g = Multigraph(15) for e in [[3, 9], [4, 10], [5, 11], [6, 12], [7, 13], [8, 14], [2, 15]] @@ -238,3 +250,4 @@ replace!(Rule{:p3}(), zxg) @test nv(zxg) == 16 && ne(zxg) == 28 @test ZXCalculus.ZX.is_hadamard(zxg, 2, 15) && ZXCalculus.ZX.is_hadamard(zxg, 1, 16) +@test !isnothing(zxg) diff --git a/test/runtests.jl b/test/runtests.jl index 13f992f..899ccaf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,15 @@ using ZXCalculus, Documenter, Test +using Vega +using DataFrames + + +@testset "plots.jl" begin + include("plots.jl") +end + +@testset "equality.jl" begin + include("equality.jl") +end @testset "abstract_zx_diagram.jl" begin include("abstract_zx_diagram.jl") @@ -24,9 +35,9 @@ end include("phase_teleportation.jl") end -# @testset "ir.jl" begin -# include("ir.jl") -# end +@testset "ir.jl" begin + include("ir.jl") +end @testset "scalar.jl" begin include("scalar.jl") diff --git a/test/zx_diagram.jl b/test/zx_diagram.jl index 370442f..4f84884 100644 --- a/test/zx_diagram.jl +++ b/test/zx_diagram.jl @@ -7,11 +7,13 @@ v_t = [SpiderType.X, SpiderType.Z, SpiderType.X] zxd = ZXDiagram(g, v_t, ps) zxd2 = ZXDiagram(g, Dict(zip(1:3, v_t)), Dict(zip(1:3, ps))) @test zxd.mg == zxd2.mg && zxd.st == zxd2.st && zxd.ps == zxd2.ps +@test !isnothing(zxd) zxd2 = copy(zxd) @test zxd.st == zxd2.st && zxd.ps == zxd2.ps @test ZX.spider_type(zxd, 1) == SpiderType.X @test nv(zxd) == 3 && ne(zxd) == 2 +@test !isnothing(zxd2) @test rem_edge!(zxd, 2, 3) @test outneighbors(zxd, 2) == inneighbors(zxd, 2) @@ -24,7 +26,11 @@ zxd3 = ZXDiagram(3) ZX.insert_spider!(zxd3, 1, 2, SpiderType.H) pushfirst_gate!(zxd3, Val{:SWAP}(), [1, 2]) push_gate!(zxd3, Val{:SWAP}(), [2, 3]) + +@test ZX.nout(zxd3) == 3 +@test ZX.nout(zxd3) == 3 @test ZX.qubit_loc(zxd3, 1) == ZX.qubit_loc(zxd3, 2) +@test !isnothing(zxd3) @testset "float to rational" begin @test ZX.continued_fraction(2.41, 10) === 241 // 100 @@ -42,6 +48,7 @@ push_gate!(zxd3, Val{:SWAP}(), [2, 3]) @test_throws MethodError push_gate!(zxd, Val(:Z), 3, sqrt(2); autoconvert = false) @test ZX.safe_convert(Rational{Int64}, 1.2) == 6 // 5 && ZX.safe_convert(Rational{Int64}, 1 // 2) == 1 // 2 + @test !isnothing(zxd) end zxd4 = ZXDiagram(2) @@ -52,4 +59,5 @@ pushfirst_gate!(zxd4, Val(:X), 1) pushfirst_gate!(zxd4, Val(:H), 1) pushfirst_gate!(zxd4, Val(:CNOT), 2, 1) pushfirst_gate!(zxd4, Val(:CZ), 1, 2) +@test !isnothing(zxd4) @test indegree(zxd4, 5) == outdegree(zxd4, 5) == degree(zxd4, 5) diff --git a/test/zx_graph.jl b/test/zx_graph.jl index a27f8eb..e909b30 100644 --- a/test/zx_graph.jl +++ b/test/zx_graph.jl @@ -7,10 +7,11 @@ add_edge!(g, 2, 4) add_edge!(g, 3, 4) add_edge!(g, 3, 5) add_edge!(g, 4, 6) -ps = [0//1 for i = 1:6] +ps = [0 // 1 for i = 1:6] v_t = [SpiderType.In, SpiderType.In, SpiderType.X, SpiderType.Z, SpiderType.Out, SpiderType.Out] zxd = ZXDiagram(g, v_t, ps) zxg1 = ZXGraph(zxd) +@test !isnothing(zxg1) @test outneighbors(zxg1, 1) == inneighbors(zxg1, 1) @test !ZX.is_hadamard(zxg1, 2, 4) && !ZX.is_hadamard(zxg1, 4, 6) @test add_edge!(zxg1, 1, 1) @@ -21,16 +22,20 @@ replace!(Rule{:b}(), zxd) zxg2 = ZXGraph(zxd) @test !ZX.is_hadamard(zxg2, 5, 8) && !ZX.is_hadamard(zxg2, 1, 7) -zxd = ZXDiagram(2) -push_gate!(zxd, Val(:H), 1) -push_gate!(zxd, Val(:CNOT), 2, 1) -zxg = ZXGraph(zxd) -zxg3 = ZXGraph(ZXDiagram(3)) -ZX.add_global_phase!(zxg3, ZXCalculus.Utils.Phase(1//4)) -ZX.add_power!(zxg3, 3) -@test ZX.scalar(zxg3) == Scalar(3, 1//4) -@test degree(zxg3, 1) == indegree(zxg3, 1) == outdegree(zxg3, 1) -@test ZX.qubit_loc(zxg3, 1) == ZX.qubit_loc(zxg3, 2) -@test ZX.column_loc(zxg3, 1) == 1//1 -@test ZX.column_loc(zxg3, 2) == 3//1 +@testset "push gates into Diagram then plot ZXGraph" begin + zxd = ZXDiagram(2) + push_gate!(zxd, Val(:H), 1) + push_gate!(zxd, Val(:CNOT), 2, 1) + zxg = ZXGraph(zxd) + @test !isnothing(zxg) + + zxg3 = ZXGraph(ZXDiagram(3)) + ZX.add_global_phase!(zxg3, ZXCalculus.Utils.Phase(1 // 4)) + ZX.add_power!(zxg3, 3) + @test ZX.scalar(zxg3) == Scalar(3, 1 // 4) + @test degree(zxg3, 1) == indegree(zxg3, 1) == outdegree(zxg3, 1) + @test ZX.qubit_loc(zxg3, 1) == ZX.qubit_loc(zxg3, 2) + @test ZX.column_loc(zxg3, 1) == 1 // 1 + @test ZX.column_loc(zxg3, 2) == 3 // 1 +end diff --git a/test/zxw_diagram.jl b/test/zxw_diagram.jl index 03807ef..c960a78 100644 --- a/test/zxw_diagram.jl +++ b/test/zxw_diagram.jl @@ -6,9 +6,9 @@ using ZXCalculus: ZXW @testset "ZXWSpiderType" begin spider_vec = - [Z(Parameter(Val(:PiUnit), 3)) Z(Parameter(Val(:Factor), exp(im * 1.5 * π))) X( + [Z(Parameter(Val(:PiUnit), 3)) Z(Parameter(Val(:Factor), exp(im * 1.5 * π))) ZXW.X( Parameter(Val(:PiUnit), 3), - ) X(Parameter(Val(:Factor), exp(im * 0.5 * π))) W H D Input(10) Output(2)] + ) ZXW.X(Parameter(Val(:Factor), exp(im * 0.5 * π))) W ZXW.H D Input(10) Output(2)] @test spider_vec[1].p == Parameter(Val(:PiUnit), 3) @test spider_vec[2].p == Parameter(Val(:Factor), exp(im * 1.5 * π))