Skip to content

Commit 4363502

Browse files
authored
🎨 Move validation function from qmap to NAComputation (cda-tum#660)
## Description This adds a function validating an NAComputation by checking the AOD constraints that was previously implemented inside the tests of QMAP. ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [x] The pull request only contains commits that are related to it. - [x] I have added appropriate tests and documentation. - [x] I have made sure that all CI jobs on GitHub pass. - [x] The pull request introduces no new warnings and follows the project's style guidelines.
2 parents 12754e4 + d04e582 commit 4363502

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

include/mqt-core/na/NAComputation.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,7 @@ class NAComputation {
8787
auto rend() noexcept { return operations.rend(); }
8888
[[nodiscard]] auto rend() const noexcept { return operations.rend(); }
8989
[[nodiscard]] auto crend() const noexcept { return operations.crend(); }
90+
91+
[[nodiscard]] auto validateAODConstraints() const -> bool;
9092
};
9193
} // namespace na

src/na/NAComputation.cpp

+80
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include "na/NAComputation.hpp"
22

3+
#include "na/operations/NALocalOperation.hpp"
4+
#include "na/operations/NAShuttlingOperation.hpp"
5+
6+
#include <cstddef>
37
#include <ios>
8+
#include <iostream>
49
#include <sstream>
510
#include <string>
611

@@ -22,4 +27,79 @@ auto NAComputation::toString() const -> std::string {
2227
}
2328
return ss.str();
2429
}
30+
auto NAComputation::validateAODConstraints() const -> bool {
31+
std::size_t counter = 1; // the first operation is `init at ...;`
32+
for (const auto& naOp : operations) {
33+
++counter;
34+
if (naOp->isShuttlingOperation()) {
35+
const auto& shuttlingOp =
36+
dynamic_cast<const NAShuttlingOperation&>(*naOp);
37+
if (shuttlingOp.getStart().size() != shuttlingOp.getEnd().size()) {
38+
return false;
39+
}
40+
for (std::size_t i = 0; i < shuttlingOp.getStart().size(); ++i) {
41+
for (std::size_t j = i + 1; j < shuttlingOp.getStart().size(); ++j) {
42+
const auto& s1 = shuttlingOp.getStart()[i];
43+
const auto& s2 = shuttlingOp.getStart()[j];
44+
const auto& e1 = shuttlingOp.getEnd()[i];
45+
const auto& e2 = shuttlingOp.getEnd()[j];
46+
if (*s1 == *s2) {
47+
std::cout << "Error in op number " << counter
48+
<< " (two start points identical)\n";
49+
return false;
50+
}
51+
if (*e1 == *e2) {
52+
std::cout << "Error in op number " << counter
53+
<< " (two end points identical)\n";
54+
return false;
55+
}
56+
if (s1->x == s2->x && e1->x != e2->x) {
57+
std::cout << "Error in op number " << counter
58+
<< " (columns not preserved)\n";
59+
return false;
60+
}
61+
if (s1->y == s2->y && e1->y != e2->y) {
62+
std::cout << "Error in op number " << counter
63+
<< " (rows not preserved)\n";
64+
return false;
65+
}
66+
if (s1->x < s2->x && e1->x >= e2->x) {
67+
std::cout << "Error in op number " << counter
68+
<< " (column order not preserved)\n";
69+
return false;
70+
}
71+
if (s1->y < s2->y && e1->y >= e2->y) {
72+
std::cout << "Error in op number " << counter
73+
<< " (row order not preserved)\n";
74+
return false;
75+
}
76+
if (s1->x > s2->x && e1->x <= e2->x) {
77+
std::cout << "Error in op number " << counter
78+
<< " (column order not preserved)\n";
79+
return false;
80+
}
81+
if (s1->y > s2->y && e1->y <= e2->y) {
82+
std::cout << "Error in op number " << counter
83+
<< " (row order not preserved)\n";
84+
return false;
85+
}
86+
}
87+
}
88+
} else if (naOp->isLocalOperation()) {
89+
const auto& localOp = dynamic_cast<const NALocalOperation&>(*naOp);
90+
for (std::size_t i = 0; i < localOp.getPositions().size(); ++i) {
91+
for (std::size_t j = i + 1; j < localOp.getPositions().size(); ++j) {
92+
const auto& a = localOp.getPositions()[i];
93+
const auto& b = localOp.getPositions()[j];
94+
if (*a == *b) {
95+
std::cout << "Error in op number " << counter
96+
<< " (identical positions)\n";
97+
return false;
98+
}
99+
}
100+
}
101+
}
102+
}
103+
return true;
104+
}
25105
} // namespace na

test/na/test_nacomputation.cpp

+76
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,80 @@ TEST(NAComputation, EmptyPrint) {
5353
ss << qc;
5454
EXPECT_EQ(ss.str(), "init at;\n");
5555
}
56+
57+
TEST(NAComputation, ValidateAODConstraints) {
58+
auto qc = NAComputation();
59+
qc.emplaceInitialPosition(std::make_shared<Point>(0, 0));
60+
qc.emplaceInitialPosition(std::make_shared<Point>(1, 0));
61+
qc.emplaceInitialPosition(std::make_shared<Point>(0, 2));
62+
qc.emplaceInitialPosition(std::make_shared<Point>(1, 2));
63+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
64+
LOAD,
65+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(1, 0)},
66+
std::vector{std::make_shared<Point>(0, 1),
67+
std::make_shared<Point>(1, 1)}));
68+
EXPECT_TRUE(qc.validateAODConstraints());
69+
qc.clear(false);
70+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
71+
LOAD,
72+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(0, 0)},
73+
std::vector{std::make_shared<Point>(0, 1),
74+
std::make_shared<Point>(1, 0)}));
75+
EXPECT_FALSE(qc.validateAODConstraints());
76+
qc.clear(false);
77+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
78+
LOAD,
79+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(1, 0)},
80+
std::vector{std::make_shared<Point>(0, 1),
81+
std::make_shared<Point>(0, 1)}));
82+
EXPECT_FALSE(qc.validateAODConstraints());
83+
qc.clear(false);
84+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
85+
LOAD,
86+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(1, 0)},
87+
std::vector{std::make_shared<Point>(0, 1),
88+
std::make_shared<Point>(1, 0)}));
89+
EXPECT_FALSE(qc.validateAODConstraints());
90+
qc.clear(false);
91+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
92+
LOAD,
93+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(1, 0)},
94+
std::vector{std::make_shared<Point>(1, 1),
95+
std::make_shared<Point>(0, 1)}));
96+
EXPECT_FALSE(qc.validateAODConstraints());
97+
qc.clear(false);
98+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
99+
LOAD,
100+
std::vector{std::make_shared<Point>(1, 0), std::make_shared<Point>(0, 0)},
101+
std::vector{std::make_shared<Point>(0, 1),
102+
std::make_shared<Point>(1, 1)}));
103+
EXPECT_FALSE(qc.validateAODConstraints());
104+
qc.clear(false);
105+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
106+
LOAD,
107+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(0, 2)},
108+
std::vector{std::make_shared<Point>(1, 0),
109+
std::make_shared<Point>(0, 1)}));
110+
EXPECT_FALSE(qc.validateAODConstraints());
111+
qc.clear(false);
112+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
113+
LOAD,
114+
std::vector{std::make_shared<Point>(0, 0), std::make_shared<Point>(1, 2)},
115+
std::vector{std::make_shared<Point>(0, 2),
116+
std::make_shared<Point>(1, 0)}));
117+
EXPECT_FALSE(qc.validateAODConstraints());
118+
qc.clear(false);
119+
qc.emplaceBack(std::make_unique<NAShuttlingOperation>(
120+
LOAD,
121+
std::vector{std::make_shared<Point>(1, 2), std::make_shared<Point>(0, 0)},
122+
std::vector{std::make_shared<Point>(1, 0),
123+
std::make_shared<Point>(0, 2)}));
124+
EXPECT_FALSE(qc.validateAODConstraints());
125+
qc.clear(false);
126+
qc.emplaceBack(std::make_unique<NALocalOperation>(
127+
FullOpType{qc::RZ, 0}, std::vector{qc::PI_2},
128+
std::vector{std::make_shared<Point>(0, 0),
129+
std::make_shared<Point>(0, 0)}));
130+
EXPECT_FALSE(qc.validateAODConstraints());
131+
}
56132
} // namespace na

0 commit comments

Comments
 (0)