diff --git a/Cargo.lock b/Cargo.lock index 8019160e..ec99d7e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "anes" version = "0.1.6" @@ -25,9 +19,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "autocfg" @@ -37,9 +31,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bitvec" @@ -55,9 +49,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" [[package]] name = "cast" @@ -67,9 +61,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "ciborium" @@ -100,18 +94,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstyle", "clap_lex", @@ -119,9 +113,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "criterion" @@ -186,21 +180,21 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "fixedbitset" @@ -222,9 +216,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", @@ -234,9 +228,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -244,26 +238,24 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" dependencies = [ - "allocator-api2", - "equivalent", "foldhash", ] [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" [[package]] name = "indexmap" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown", @@ -271,13 +263,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -300,15 +292,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -316,15 +308,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.164" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" @@ -343,21 +335,20 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "petgraph" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c96dc3f2709da98e228764d8f4c01c39a101dcc441547e8036372ee0522eb108" +version = "0.8.2" +source = "git+https://github.com/keefehuang/petgraph#1cdbae4cecd2fb6591697eb8cba3d2c9a76c438e" dependencies = [ "fixedbitset", "hashbrown", @@ -404,18 +395,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -434,13 +425,12 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha", "rand_core", - "zerocopy", ] [[package]] @@ -511,11 +501,17 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -528,29 +524,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.102", ] [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -572,9 +568,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462" dependencies = [ "proc-macro2", "quote", @@ -599,15 +595,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "walkdir" @@ -630,34 +626,35 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.102", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -665,28 +662,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.102", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -698,16 +698,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", + "windows-sys", ] [[package]] @@ -803,20 +794,20 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.102", ] diff --git a/Cargo.toml b/Cargo.toml index 5f747414..48a3ae9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ path = "src/lib.rs" [dependencies] bitvec = "1.0.1" itertools = "0.13.0" -petgraph = { version = "0.8.0", features = ["stable_graph"]} +petgraph = { version = "0.8.2", features = ["stable_graph"], git = "https://github.com/keefehuang/petgraph" } typenum = "1.17.0" [dev-dependencies] diff --git a/benches/clifford_tableau.rs b/benches/clifford_tableau.rs index c29746ca..7dfa3f81 100644 --- a/benches/clifford_tableau.rs +++ b/benches/clifford_tableau.rs @@ -11,6 +11,8 @@ use syn::ir::Synthesizer; mod connectivity; +mod connectivity; + #[derive(Debug, Default)] pub struct MockCircuit { commands: Vec, diff --git a/src/architecture.rs b/src/architecture.rs index e046ffb4..aabb3d3b 100644 --- a/src/architecture.rs +++ b/src/architecture.rs @@ -7,6 +7,7 @@ type NodeWeight = (); #[derive(Debug, PartialEq)] pub enum LadderError { RootNotFound, + NodesNotFound(Vec), } pub trait Architecture { @@ -19,4 +20,5 @@ pub trait Architecture { nodes: &[GraphIndex], root: &GraphIndex, ) -> Result, LadderError>; + fn disconnect(&self, i: GraphIndex) -> Self; } diff --git a/src/architecture/connectivity.rs b/src/architecture/connectivity.rs index a7fa1a52..2efef0c3 100644 --- a/src/architecture/connectivity.rs +++ b/src/architecture/connectivity.rs @@ -1,20 +1,19 @@ use super::{Architecture, EdgeWeight, GraphIndex, LadderError, NodeWeight}; use petgraph::algo::floyd_warshall::floyd_warshall_path; -use petgraph::algo::steiner_tree::steiner_tree; -use petgraph::prelude::EdgeRef; -use petgraph::visit::{Bfs, Dfs, GraphBase, IntoNeighbors, VisitMap, Visitable, Walker}; +use petgraph::algo::steiner_tree::stable_steiner_tree; +use petgraph::prelude::{EdgeRef, StableUnGraph}; +use petgraph::visit::{Bfs, IntoEdgeReferences, VisitMap, Visitable}; use petgraph::{ algo::articulation_points::articulation_points, - graph::{NodeIndex, UnGraph}, + graph::NodeIndex, visit::{IntoNodeReferences, NodeIndexable, NodeRef}, }; -use std::borrow::Borrow; use std::collections::HashMap; use std::ops::Index; /// Get all the vertices in a graph that are non-cutting (won't make the graph disconnected) fn get_non_cutting_vertices( - graph: &UnGraph, + graph: &StableUnGraph, ) -> Vec { let art_points = articulation_points(&graph); (0..graph.node_count()) @@ -24,7 +23,7 @@ fn get_non_cutting_vertices( #[derive(Debug)] pub struct Connectivity { - graph: UnGraph, + graph: StableUnGraph, non_cutting: Vec, prev: Vec>>, distance: HashMap<(NodeIndex, NodeIndex), EdgeWeight>, @@ -32,8 +31,10 @@ pub struct Connectivity { impl Connectivity { pub fn new(num_qubits: usize) -> Self { + let graph = StableUnGraph::with_capacity(num_qubits, 0); + Connectivity { - graph: UnGraph::with_capacity(num_qubits, 0), + graph, non_cutting: Default::default(), prev: Default::default(), distance: HashMap::new(), @@ -72,19 +73,20 @@ impl Connectivity { } pub fn from_edges(edges: &[(GraphIndex, GraphIndex)]) -> Self { - let graph = UnGraph::from_edges(edges); + let graph = StableUnGraph::from_edges(edges); Connectivity::from_graph(graph) } pub fn from_weighted_edges(edges: &[(GraphIndex, GraphIndex, EdgeWeight)]) -> Self { - let graph = UnGraph::from_edges(edges); + let graph = StableUnGraph::from_edges(edges); Connectivity::from_graph(graph) } - pub fn from_graph(graph: UnGraph) -> Self { + pub fn from_graph(graph: StableUnGraph) -> Self { let non_cutting = get_non_cutting_vertices(&graph); let (distance, prev) = floyd_warshall_path(&graph, |e| *e.weight()).unwrap(); - let distance = distance.iter().map(|(k, v)| (*k, *v as usize)).collect(); + let distance = distance.iter().map(|(k, v)| (*k, *v)).collect(); + Connectivity { graph, non_cutting, @@ -96,7 +98,7 @@ impl Connectivity { pub fn nodes(&self) -> Vec { self.graph .node_references() - .map(|node| self.graph.to_index(node.id())) + .map(|(node, _)| node.id().index()) .collect() } @@ -119,7 +121,7 @@ impl Connectivity { let (distance, prev) = floyd_warshall_path(&self.graph, |e| *e.weight()).unwrap(); - let distance = distance.iter().map(|(k, v)| (*k, *v as usize)).collect(); + let distance = distance.iter().map(|(k, v)| (*k, *v)).collect(); self.non_cutting = non_cutting; self.distance = distance; @@ -131,10 +133,6 @@ impl Connectivity { self.update(); } - pub fn add_node(&mut self) { - self.graph.add_node(()); - } - pub fn add_edge(&mut self, i: GraphIndex, j: GraphIndex) { self.graph .add_edge(self.graph.from_index(i), self.graph.from_index(j), 1); @@ -206,22 +204,41 @@ impl Architecture for Connectivity { &self.non_cutting } + /// Obtain cx ladder that is architecture conforming that is rooted at `root` fn get_cx_ladder( &self, nodes: &[GraphIndex], root: &GraphIndex, ) -> Result, LadderError> { + let mut nodes = nodes.to_vec(); let terminals: Vec<_> = self .graph - .node_indices() - .filter(|node_index| nodes.contains(&node_index.index())) + .node_references() + .filter_map(|(node_index, _)| { + if nodes.contains(&node_index.index()) { + nodes.retain(|&x| x != node_index.index()); + Some(node_index) + } else { + None + } + }) .collect(); - let tree = steiner_tree(&self.graph, &terminals); + if !nodes.is_empty() { + return Err(LadderError::NodesNotFound(nodes)); + } + + let tree = stable_steiner_tree(&self.graph, &terminals); let root_node = tree - .node_indices() - .find(|item| item.index() == *root as usize) + .node_references() + .find_map(|(item, _)| { + if item.index() == *root { + Some(item) + } else { + None + } + }) .ok_or(LadderError::RootNotFound)?; let mut bfs = Bfs::new(&tree, root_node); @@ -233,12 +250,27 @@ impl Architecture for Connectivity { for neighbor in tree.neighbors(node) { if !visited.is_visited(&neighbor) { visited.visit(neighbor); - edge_list.push((node.index(), neighbor.index())); + edge_list.push((self.graph.to_index(node), self.graph.to_index(neighbor))); } } } Ok(edge_list) } + + fn disconnect(&self, i: GraphIndex) -> Connectivity { + let mut graph = self.graph.clone(); + graph.retain_nodes(|_, index| if index.index() == i { false } else { true }); + let non_cutting = get_non_cutting_vertices(&graph); + let (distance, prev) = floyd_warshall_path(&graph, |e| *e.weight()).unwrap(); + let distance = distance.iter().map(|(k, v)| (*k, *v)).collect(); + + Connectivity { + graph, + non_cutting, + prev, + distance, + } + } } #[cfg(test)] @@ -251,7 +283,7 @@ mod tests { (0, 1, 7), (0, 5, 6), (1, 2, 1), - (1, 5, 5), + (1, 5, 7), (2, 3, 1), (2, 4, 3), (3, 4, 1), @@ -276,7 +308,8 @@ mod tests { #[test] fn test_line_creation() { - let mut line_architecture = Connectivity::line(5); + let line_architecture = Connectivity::line(5); + assert_eq!( line_architecture.edges(), vec![(0, 1), (1, 2), (2, 3), (3, 4)] @@ -285,8 +318,8 @@ mod tests { #[test] fn test_grid_creation() { - let mut line_architecture = Connectivity::grid(3, 3); - let mut edges = line_architecture.edges(); + let grid_architecture = Connectivity::grid(3, 3); + let mut edges = grid_architecture.edges(); edges.sort(); assert_eq!( edges, @@ -308,25 +341,26 @@ mod tests { } #[test] - fn test_weight_is_considered() { - let new_architecture = Connectivity::from_weighted_edges(&setup_weighted()); + fn test_root_is_not_present() { + let new_architecture = Connectivity::from_edges(&setup_simple()); assert_eq!( new_architecture - .get_cx_ladder(&vec![1, 2, 3, 4], &2) - .unwrap() - .len(), - 3 + .get_cx_ladder(&[1, 2, 3, 4], &42) + .expect_err("Should return a Error that the root was not found"), + LadderError::RootNotFound ); } #[test] - fn test_root_is_not_present() { + fn test_cx_ladder_error() { let new_architecture = Connectivity::from_edges(&setup_simple()); assert_eq!( new_architecture - .get_cx_ladder(&vec![1, 2, 3, 4], &42) - .expect_err("Should return a Error that the root was not found"), - LadderError::RootNotFound + .get_cx_ladder(&[6, 1, 2, 3], &0) + .expect_err( + "Should return an error that the nodes are not part of the architecture" + ), + LadderError::NodesNotFound(vec![6]) ); } @@ -340,9 +374,7 @@ mod tests { fn test_cx_ladder_line_setup() { let new_architecture = Connectivity::from_edges(&setup_simple()); assert_eq!( - new_architecture - .get_cx_ladder(&vec![0, 1, 2, 3], &0) - .unwrap(), + new_architecture.get_cx_ladder(&[0, 1, 2, 3], &0).unwrap(), vec![(0, 1), (1, 2), (2, 3)] ); } @@ -352,32 +384,56 @@ mod tests { let new_architecture = Connectivity::from_edges(&setup_simple()); assert_eq!( new_architecture - .get_cx_ladder(&vec![0, 1, 2, 4, 5], &1) + .get_cx_ladder(&[0, 1, 2, 4, 5], &1) .unwrap() .len(), 4 ); } + #[test] + fn test_cx_ladder_weighted_extended_triangle() { + let new_architecture = Connectivity::from_weighted_edges(&setup_weighted()); + assert_eq!( + new_architecture + .get_cx_ladder(&[0, 1, 2, 4, 5], &1) + .unwrap(), + vec![(1, 2), (2, 3), (3, 5), (3, 4), (5, 0)] + ); + } + #[test] fn test_cx_ladder_small_triangle() { let new_architecture = Connectivity::from_edges(&setup_simple()); assert_eq!( new_architecture - .get_cx_ladder(&vec![2, 3, 4], &2) + .get_cx_ladder(&[2, 3, 4], &2) .unwrap() .len(), 2 ); assert_eq!( new_architecture - .get_cx_ladder(&vec![2, 3, 4], &4) + .get_cx_ladder(&[2, 3, 4], &4) .unwrap() .len(), 2 ); } + #[test] + fn test_cx_ladder_weighted_small_triangle() { + let new_architecture = Connectivity::from_weighted_edges(&setup_weighted()); + assert_eq!( + new_architecture.get_cx_ladder(&[2, 3, 4], &2).unwrap(), + vec![(2, 3), (3, 4)] + ); + assert_eq!( + new_architecture.get_cx_ladder(&[2, 3, 4], &4).unwrap(), + vec![(4, 3), (3, 2)] + ); + } + #[test] fn test_weighted_constructor() { let new_architecture = Connectivity::from_weighted_edges(&setup_weighted()); @@ -445,9 +501,224 @@ mod tests { assert_eq!(*line_architecture.non_cutting(), vec![0, 4]); } + #[test] + fn test_non_cutting_grid() { + let mut line_architecture = Connectivity::grid(3, 3); + assert_eq!( + *line_architecture.non_cutting(), + vec![0, 1, 2, 3, 4, 5, 6, 7, 8] + ); + } + #[test] fn test_non_cutting_complete() { - let mut line_architecture = Connectivity::complete(5); - assert_eq!(*line_architecture.non_cutting(), vec![0, 1, 2, 3, 4]); + let mut line_architecture = Connectivity::complete(3); + assert_eq!(*line_architecture.non_cutting(), vec![0, 1, 2]); + } + + #[test] + fn test_remove_node() { + let mut architecture = Connectivity::from_edges(&setup_simple()); + assert_eq!(architecture.nodes(), vec![0, 1, 2, 3, 4, 5]); + + assert_eq!( + architecture.edges(), + vec![ + (0, 1), + (0, 5), + (1, 2), + (1, 5), + (2, 3), + (2, 4), + (3, 4), + (3, 5), + (4, 5), + ] + ); + + architecture.remove_node(1); + + assert_eq!(architecture.nodes(), vec![0, 2, 3, 4, 5]); + + assert_eq!( + architecture.edges(), + vec![(0, 5), (2, 3), (2, 4), (3, 4), (3, 5), (4, 5)] + ); + } + + #[test] + fn test_remove_node_line() { + let mut architecture = Connectivity::line(5); + assert_eq!(architecture.nodes(), vec![0, 1, 2, 3, 4]); + + assert_eq!(architecture.edges(), vec![(0, 1), (1, 2), (2, 3), (3, 4)]); + + architecture.remove_node(1); + + assert_eq!(architecture.nodes(), vec![0, 2, 3, 4]); + + assert_eq!(architecture.edges(), vec![(2, 3), (3, 4)]); + } + + #[test] + fn test_remove_node_grid() { + let mut architecture = Connectivity::grid(3, 3); + assert_eq!(architecture.nodes(), vec![0, 1, 2, 3, 4, 5, 6, 7, 8]); + + assert_eq!( + architecture.edges(), + vec![ + (0, 3), + (0, 1), + (1, 4), + (1, 2), + (2, 5), + (3, 6), + (3, 4), + (4, 7), + (4, 5), + (5, 8), + (6, 7), + (7, 8) + ] + ); + + architecture.remove_node(1); + + assert_eq!(architecture.nodes(), vec![0, 2, 3, 4, 5, 6, 7, 8]); + + assert_eq!( + architecture.edges(), + vec![ + (0, 3), + (2, 5), + (3, 6), + (3, 4), + (4, 7), + (4, 5), + (5, 8), + (6, 7), + (7, 8), + ] + ); + } + + #[test] + fn test_disconnect() { + let architecture = Connectivity::from_edges(&setup_simple()); + let new_architecture = architecture.disconnect(1); + + assert_eq!(architecture.nodes(), vec![0, 1, 2, 3, 4, 5]); + + assert_eq!( + architecture.edges(), + vec![ + (0, 1), + (0, 5), + (1, 2), + (1, 5), + (2, 3), + (2, 4), + (3, 4), + (3, 5), + (4, 5), + ] + ); + + assert_eq!(new_architecture.nodes(), vec![0, 2, 3, 4, 5]); + + assert_eq!( + new_architecture.edges(), + vec![(0, 5), (2, 3), (2, 4), (3, 4), (3, 5), (4, 5)] + ); + } + + #[test] + fn test_disconnect_line() { + let architecture = Connectivity::line(5); + let new_architecture = architecture.disconnect(1); + + assert_eq!(architecture.nodes(), vec![0, 1, 2, 3, 4]); + + assert_eq!(architecture.edges(), vec![(0, 1), (1, 2), (2, 3), (3, 4)]); + + assert_eq!(new_architecture.nodes(), vec![0, 2, 3, 4]); + + assert_eq!(new_architecture.edges(), vec![(2, 3), (3, 4)]); + } + + #[test] + fn test_disconnect_grid() { + let architecture = Connectivity::grid(3, 3); + let new_architecture = architecture.disconnect(1); + + assert_eq!(architecture.nodes(), vec![0, 1, 2, 3, 4, 5, 6, 7, 8]); + + assert_eq!( + architecture.edges(), + vec![ + (0, 3), + (0, 1), + (1, 4), + (1, 2), + (2, 5), + (3, 6), + (3, 4), + (4, 7), + (4, 5), + (5, 8), + (6, 7), + (7, 8) + ] + ); + + assert_eq!(new_architecture.nodes(), vec![0, 2, 3, 4, 5, 6, 7, 8]); + + assert_eq!( + new_architecture.edges(), + vec![ + (0, 3), + (2, 5), + (3, 6), + (3, 4), + (4, 7), + (4, 5), + (5, 8), + (6, 7), + (7, 8) + ] + ); + } + + #[test] + fn test_disconnected_cx_ladder() { + let architecture = Connectivity::from_weighted_edges(&setup_weighted()); + let new_architecture = architecture.disconnect(3); + + assert_eq!(new_architecture.nodes(), vec![0, 1, 2, 4, 5]); + + assert_eq!( + new_architecture.edges(), + vec![(0, 1), (0, 5), (1, 2), (1, 5), (2, 4), (4, 5)] + ); + + assert_eq!( + new_architecture.get_cx_ladder(&[1, 2, 4, 5], &2).unwrap(), + vec![(2, 4), (2, 1), (1, 5)] + ); + + let new_architecture = new_architecture.disconnect(2); + + assert_eq!(new_architecture.nodes(), vec![0, 1, 4, 5]); + + assert_eq!( + new_architecture.edges(), + vec![(0, 1), (0, 5), (1, 5), (4, 5)] + ); + + assert_eq!( + new_architecture.get_cx_ladder(&[1, 4, 5], &1).unwrap(), + vec![(1, 5), (5, 4)] + ); } } diff --git a/src/ir/clifford_tableau.rs b/src/ir/clifford_tableau.rs index 0a2b6d75..177e3cef 100644 --- a/src/ir/clifford_tableau.rs +++ b/src/ir/clifford_tableau.rs @@ -1,12 +1,12 @@ -pub mod custom_callback; -mod helper; -pub mod naive; - +use super::{AdjointSynthesizer, Synthesizer}; use crate::data_structures::{CliffordTableau, HasAdjoint}; + pub use custom_callback::CallbackCliffordSynthesizer; pub use naive::NaiveCliffordSynthesizer; -use super::{AdjointSynthesizer, Synthesizer}; +mod custom_callback; +mod helper; +mod naive; #[derive(Default)] pub enum CliffordTableauSynthStrategy { diff --git a/src/ir/pauli_exponential.rs b/src/ir/pauli_exponential.rs index b9eaf164..ac3824e3 100644 --- a/src/ir/pauli_exponential.rs +++ b/src/ir/pauli_exponential.rs @@ -4,10 +4,10 @@ use crate::data_structures::{CliffordTableau, HasAdjoint, PauliPolynomial}; use crate::ir::{CliffordGates, Gates, Synthesizer}; +use crate::ir::clifford_tableau::CallbackCliffordSynthesizer; +use crate::ir::clifford_tableau::NaiveCliffordSynthesizer; use crate::ir::{ - clifford_tableau::{ - CallbackCliffordSynthesizer, CliffordTableauSynthStrategy, NaiveCliffordSynthesizer, - }, + clifford_tableau::CliffordTableauSynthStrategy, pauli_polynomial::{naive::NaivePauliPolynomialSynthesizer, PauliPolynomialSynthStrategy}, };