Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/execute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ bool AUTOQ::Automata<Symbol>::execute(const char *filename, std::vector<int> qub
if (it == kRegexEnd)
THROW_AUTOQ_ERROR("Expected measure assignment (var = measure ...[n]) in \"" + line + "\".");
std::string result = it->str(1);
int pos = 1 + atoi(it->str(2).c_str());
int pos = 1 + qubit_permutation[atoi(it->str(2).c_str())]; // the automaton level of the qubit, as for gates
var_is_measure_what_qubit[result] = pos;
// TODO: Actually, we should split the automaton here into two separate copies which
// are produced from the measurement outcome of 0 and 1, respectively. However, we do
Expand Down
22 changes: 22 additions & 0 deletions unit_tests/explicit_tree_aut_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,28 @@ BOOST_AUTO_TEST_CASE(for_loop_summarization_complex_amplitudes){
}
}

// `r = measure q[k];` must guard on the same automaton level that gates use for
// q[k], also when the .hsl files reorder the qubits (#26).
BOOST_AUTO_TEST_CASE(measurement_guard_uses_qubit_permutation){
std::string folder = test_dir_from_file(__FILE__, "testcase/MeasurePermutation/");
// {|sts>} and {|s0s>} put the two `s` qubits next to each other, so q[1] and q[2] swap levels.
const std::vector<std::pair<std::string, bool>> cases = {
{"if_reset.qasm", true},
{"if_wrong_qubit.qasm", false},
{"while_reset.qasm", true},
};
for (const auto& [circuit, expected] : cases) {
auto [autVec, qp] = AUTOQ::Parsing::TimbukParser<AUTOQ::Symbol::Concrete>::ReadTwoAutomata(folder + "pre.hsl", folder + "post.hsl", folder + circuit);
BOOST_REQUIRE_MESSAGE((qp == std::vector<int>{0, 2, 1}), circuit + ": the qubits are not reordered");
auto aut = autVec.at(0);
auto spec = autVec.at(1);
autVec.erase(autVec.begin(), autVec.begin() + 2);
bool verify = aut.execute(folder + circuit, qp, autVec);
verify &= (aut <<= spec);
BOOST_CHECK_MESSAGE(verify == expected, circuit + ": expected " + (expected ? "[OK]" : "[failed]"));
}
}


static void grover_oracle(AUTOQ::ConcreteAutomata& aut, unsigned ans, int n) {
for (int i=1; i<=n; i++) {
Expand Down
8 changes: 8 additions & 0 deletions unit_tests/testcase/MeasurePermutation/if_reset.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
OPENQASM 3;
include "stdgates.inc";
qubit[3] q;
bit r;
r = measure q[1];
if (r) {
x q[1];
}
8 changes: 8 additions & 0 deletions unit_tests/testcase/MeasurePermutation/if_wrong_qubit.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
OPENQASM 3;
include "stdgates.inc";
qubit[3] q;
bit r;
r = measure q[2];
if (r) {
x q[1];
}
2 changes: 2 additions & 0 deletions unit_tests/testcase/MeasurePermutation/inv.hsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Extended Dirac
{|sts> : |s|=1, |t|=1}
2 changes: 2 additions & 0 deletions unit_tests/testcase/MeasurePermutation/post.hsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Extended Dirac
{|s0s> : |s|=1}
2 changes: 2 additions & 0 deletions unit_tests/testcase/MeasurePermutation/pre.hsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Extended Dirac
{|sts> : |s|=1, |t|=1}
9 changes: 9 additions & 0 deletions unit_tests/testcase/MeasurePermutation/while_reset.qasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
OPENQASM 3;
include "stdgates.inc";
qubit[3] q;
bit r;
r = measure q[1];
while (r) { // inv.hsl
x q[1];
r = measure q[1];
}
Loading