From 4528c5fe6b429877c68a00ad447a90510ac88643 Mon Sep 17 00:00:00 2001 From: Quentin Quadrat Date: Fri, 26 Apr 2024 15:17:33 +0200 Subject: [PATCH] Fix confusion with order origin/destination nodes in arcs --- data/examples/Howard2.json | 20 +- data/examples/SemiHoward.teg | 8 +- data/examples/SemiNetherlands.teg | 24 +- doc/pics/Circuit01.png | Bin 15738 -> 0 bytes doc/pics/EventGraph01.png | Bin 15651 -> 0 bytes src/Net/Algorithms.cpp | 5 +- tests/EventGraphTests.cpp | 53 +++- tests/HowardTests.cpp | 220 ++++++++++++--- tests/PetriNetTests.cpp | 446 ++++++++++++++++-------------- 9 files changed, 490 insertions(+), 286 deletions(-) delete mode 100644 doc/pics/Circuit01.png delete mode 100644 doc/pics/EventGraph01.png diff --git a/data/examples/Howard2.json b/data/examples/Howard2.json index 8f7da23..a931647 100644 --- a/data/examples/Howard2.json +++ b/data/examples/Howard2.json @@ -18,16 +18,16 @@ { "id": 3, "caption": "T3", "x": 734, "y": 406, "angle": 0 } ], "arcs": [ - { "from": "P0", "to": "T0" }, - { "from": "T0", "to": "P1", "duration": 5 }, - { "from": "P1", "to": "T1" }, - { "from": "T1", "to": "P2", "duration": 3 }, - { "from": "P2", "to": "T2" }, - { "from": "T2", "to": "P0", "duration": 5 }, - { "from": "T0", "to": "P3", "duration": 1 }, - { "from": "P3", "to": "T3" }, - { "from": "T3", "to": "P4", "duration": 1 }, - { "from": "P4", "to": "T2" } + { "from": "P3", "to": "T0" }, + { "from": "P1", "to": "T0" }, + { "from": "T0", "to": "P0", "duration": 5 }, + { "from": "P0", "to": "T2" }, + { "from": "T2", "to": "P2", "duration": 3 }, + { "from": "P2", "to": "T1" }, + { "from": "T1", "to": "P1", "duration": 5 }, + { "from": "T2", "to": "P4", "duration": 1 }, + { "from": "P4", "to": "T3" }, + { "from": "T3", "to": "P3", "duration": 1 } ] } ] diff --git a/data/examples/SemiHoward.teg b/data/examples/SemiHoward.teg index bf52486..c220ccc 100644 --- a/data/examples/SemiHoward.teg +++ b/data/examples/SemiHoward.teg @@ -1,7 +1,7 @@ TimedEventGraph 3 5 -1 0: 0 1 -0 1: 1 0 -0 2: 0 0 -1 2: 1 0 +0 1: 0 1 +1 0: 1 0 +2 0: 0 0 +2 1: 1 0 2 2: 2 1 \ No newline at end of file diff --git a/data/examples/SemiNetherlands.teg b/data/examples/SemiNetherlands.teg index 2ca4eb9..a294214 100644 --- a/data/examples/SemiNetherlands.teg +++ b/data/examples/SemiNetherlands.teg @@ -1,14 +1,14 @@ TimedEventGraph 8 12 -1 0: 61 2 -3 1: 81 1 -0 2: 58 1 -5 2: 0 0 -2 3: 86 2 -4 3: 69 2 -3 4: 69 1 -6 4: 36 1 -4 5: 35 1 -1 6: 0 0 -7 6: 58 1 -5 7: 61 1 + 0 1: 61 2 + 1 3: 81 1 + 2 0: 58 1 + 2 5: 0 0 + 3 2: 86 2 + 3 4: 69 2 + 4 3: 69 1 + 4 6: 36 1 + 5 4: 35 1 + 6 1: 0 0 + 6 7: 58 1 + 7 5: 61 1 \ No newline at end of file diff --git a/doc/pics/Circuit01.png b/doc/pics/Circuit01.png deleted file mode 100644 index c692b943d0a5209e9d6783b17681a348d47781a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15738 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 diff --git a/src/Net/Algorithms.cpp b/src/Net/Algorithms.cpp index acfc88b..97dfb93 100644 --- a/src/Net/Algorithms.cpp +++ b/src/Net/Algorithms.cpp @@ -450,8 +450,8 @@ CriticalCycleResult findCriticalCycle(Net const& net) Transition& from = *reinterpret_cast(&(p.arcsIn[0]->from)); Transition& to = *reinterpret_cast(&(p.arcsOut[0]->to)); - IJ.push_back(int(to.id)); // Transposed is needed IJ.push_back(int(from.id)); + IJ.push_back(int(to.id)); T.push_back(p.arcsIn[0]->duration); N.push_back(double(p.tokens)); } @@ -501,7 +501,7 @@ CriticalCycleResult findCriticalCycle(Net const& net) Node* t1 = &p.arcsOut[0]->to; assert(t0->type == Node::Type::Transition); assert(t1->type == Node::Type::Transition); - if ((t0->id == from) && (t1->id == to)) + if ((t1->id == from) && (t0->id == to)) { result.arcs.push_back(p.arcsIn[0]); result.arcs.push_back(p.arcsOut[0]); @@ -524,6 +524,7 @@ CriticalCycleResult findCriticalCycle(Net const& net) } result.success = true; + //std::cout << result.message.str().c_str() << "\n"; return result; } diff --git a/tests/EventGraphTests.cpp b/tests/EventGraphTests.cpp index 7394379..c9171fa 100644 --- a/tests/EventGraphTests.cpp +++ b/tests/EventGraphTests.cpp @@ -83,41 +83,72 @@ TEST(TestEventGraph, TestToSysLinNoInputNoOutput) ASSERT_EQ(toSysLin(net, D, A, B, C), true); // // j - // i | . . . . . | | . . . . 5 | - // | 5 . . . . | | . . . . . | - // D = | . 3 . 1 . |, A = | . . . . . | - // | 1 . . . . | | . . . . . | - // | . . . . . | | . . 0 . . | + // i | . 5 . 1 . | | . . . . . | + // | . . 3 . . | | . . . . . | + // D = | . . . . . |, A = | . . . . 5 | + // | . . 1 . . | | . . . . . | + // | . . . . . | | 0 . . . . | // ASSERT_EQ(D.i.size(), 4u); ASSERT_EQ(D.j.size(), 4u); ASSERT_EQ(D.d.size(), 4u); ASSERT_EQ(D.N, 5u); ASSERT_EQ(D.M, 5u); - ASSERT_THAT(D.i, UnorderedElementsAre(2u, 3u, 4u, 3u)); - ASSERT_THAT(D.j, UnorderedElementsAre(1u, 2u, 1u, 4u)); - ASSERT_THAT(D.d, UnorderedElementsAre(5.0, 3.0, 1.0, 1.0)); + ASSERT_THAT(D.i, ElementsAre(1u, 2u, 1u, 4u)); + ASSERT_THAT(D.j, ElementsAre(4u, 3u, 2u, 3u)); + ASSERT_THAT(D.d, ElementsAre(1.0, 3.0, 5.0, 1.0)); + SparseMatrix::display_for_julia = true; + SparseMatrix::display_as_dense = false; + std::stringstream ssD; ssD << D; + ASSERT_STREQ(ssD.str().c_str(), "[1, 2, 1, 4], [4, 3, 2, 3], MP([1, 3, 5, 1]), 5, 5"); + SparseMatrix::display_as_dense = true; + ssD.str(""); ssD << D; + ASSERT_STREQ(ssD.str().c_str(), ". 5 . 1 . \n. . 3 . . \n. . . . . \n. . 1 . . \n. . . . . \n"); ASSERT_EQ(A.i.size(), 2u); ASSERT_EQ(A.j.size(), 2u); ASSERT_EQ(A.d.size(), 2u); ASSERT_EQ(A.N, 5u); ASSERT_EQ(A.M, 5u); - ASSERT_THAT(A.i, UnorderedElementsAre(5u, 1u)); - ASSERT_THAT(A.j, UnorderedElementsAre(3u, 5u)); - ASSERT_THAT(A.d, UnorderedElementsAre(0.0, 5.0)); + ASSERT_THAT(A.i, ElementsAre(5u, 3u)); + ASSERT_THAT(A.j, ElementsAre(1u, 5u)); + ASSERT_THAT(A.d, ElementsAre(0.0, 5.0)); + SparseMatrix::display_for_julia = true; + SparseMatrix::display_as_dense = false; + std::stringstream ssA; ssA << A; + ASSERT_STREQ(ssA.str().c_str(), "[5, 3], [1, 5], MP([0, 5]), 5, 5"); + SparseMatrix::display_as_dense = true; + ssA.str(""); ssA << A; + // FIXME trailing white space not proper + // FIXME 0 not displayed + // ASSERT_STREQ(ssA.str().c_str(), ". . . . . \n. . . . . \n. . . . 5 \n. . . . . \n0 . . . . \n"); + ASSERT_STREQ(ssA.str().c_str(), ". . . . . \n. . . . . \n. . . . 5 \n. . . . . \n. . . . . \n"); ASSERT_EQ(B.i.size(), 0u); ASSERT_EQ(B.j.size(), 0u); ASSERT_EQ(B.d.size(), 0u); ASSERT_EQ(B.N, 0u); ASSERT_EQ(B.M, 5u); + SparseMatrix::display_for_julia = true; + SparseMatrix::display_as_dense = false; + std::stringstream ssB; ssB << B; + ASSERT_STREQ(ssB.str().c_str(), "[], [], MP([]), 5, 0"); + SparseMatrix::display_as_dense = true; + ssB.str(""); ssB << B; + ASSERT_STREQ(ssB.str().c_str(), "\n\n\n\n\n"); // FIXME not proper ASSERT_EQ(C.i.size(), 0u); ASSERT_EQ(C.j.size(), 0u); ASSERT_EQ(C.d.size(), 0u); ASSERT_EQ(C.N, 5u); ASSERT_EQ(C.M, 0u); + SparseMatrix::display_for_julia = true; + SparseMatrix::display_as_dense = false; + std::stringstream ssC; ssC << C; + ASSERT_STREQ(ssC.str().c_str(), "[], [], MP([]), 0, 5"); + SparseMatrix::display_as_dense = true; + ssC.str(""); ssC << C; + ASSERT_STREQ(ssC.str().c_str(), ""); } //------------------------------------------------------------------------------ diff --git a/tests/HowardTests.cpp b/tests/HowardTests.cpp index 85d8de2..2fdfbf5 100644 --- a/tests/HowardTests.cpp +++ b/tests/HowardTests.cpp @@ -68,9 +68,9 @@ TEST(TestHoward, TestSemiSimple) ASSERT_EQ(pi.size(), nnodes); ASSERT_EQ(ncomponents, 2); - ASSERT_DOUBLE_EQ(chi[0], 1.0); ASSERT_DOUBLE_EQ(v[0], 0.0); ASSERT_EQ(pi[0], 1); - ASSERT_DOUBLE_EQ(chi[1], 1.0); ASSERT_DOUBLE_EQ(v[1], 1.0); ASSERT_EQ(pi[1], 0); - ASSERT_DOUBLE_EQ(chi[2], 2.0); ASSERT_DOUBLE_EQ(v[2], 2.0); ASSERT_EQ(pi[2], 2); + ASSERT_DOUBLE_EQ(chi[0], 1.0); ASSERT_DOUBLE_EQ(v[0], 0.0); ASSERT_DOUBLE_EQ(pi[0], 1); + ASSERT_DOUBLE_EQ(chi[1], 1.0); ASSERT_DOUBLE_EQ(v[1], 1.0); ASSERT_DOUBLE_EQ(pi[1], 0); + ASSERT_DOUBLE_EQ(chi[2], 2.0); ASSERT_DOUBLE_EQ(v[2], 2.0); ASSERT_DOUBLE_EQ(pi[2], 2); } //------------------------------------------------------------------------------ @@ -114,14 +114,14 @@ TEST(TestHoward, TestSemiNetherlands) ASSERT_EQ(pi.size(), nnodes); ASSERT_EQ(ncomponents, 1); - ASSERT_DOUBLE_EQ(chi[0], 47.666666666666664); ASSERT_DOUBLE_EQ(v[0], 47.6666666666667); ASSERT_EQ(pi[0], 1); - ASSERT_DOUBLE_EQ(chi[1], 47.666666666666664); ASSERT_DOUBLE_EQ(v[1], 82.0); ASSERT_EQ(pi[1], 3); - ASSERT_DOUBLE_EQ(chi[2], 47.666666666666664); ASSERT_DOUBLE_EQ(v[2], 58.000000000000036); ASSERT_EQ(pi[2], 0); - ASSERT_DOUBLE_EQ(chi[3], 47.666666666666664); ASSERT_DOUBLE_EQ(v[3], 48.666666666666693); ASSERT_EQ(pi[3], 2); - ASSERT_DOUBLE_EQ(chi[4], 47.666666666666664); ASSERT_DOUBLE_EQ(v[4], 70.333333333333371); ASSERT_EQ(pi[4], 6); - ASSERT_DOUBLE_EQ(chi[5], 47.666666666666664); ASSERT_DOUBLE_EQ(v[5], 57.666666666666707); ASSERT_EQ(pi[5], 4); - ASSERT_DOUBLE_EQ(chi[6], 47.666666666666664); ASSERT_DOUBLE_EQ(v[6], 82.000000000000036); ASSERT_EQ(pi[6], 1); - ASSERT_DOUBLE_EQ(chi[7], 47.666666666666664); ASSERT_DOUBLE_EQ(v[7], 71.0); ASSERT_EQ(pi[7], 5); + ASSERT_NEAR(chi[0], 47.6667, 0.001); ASSERT_NEAR(v[0], 47.6667, 0.001); ASSERT_EQ(pi[0], 1); + ASSERT_NEAR(chi[1], 47.6667, 0.001); ASSERT_NEAR(v[1], 82.0, 0.001); ASSERT_EQ(pi[1], 3); + ASSERT_NEAR(chi[2], 47.6667, 0.001); ASSERT_NEAR(v[2], 58.0, 0.001); ASSERT_EQ(pi[2], 0); + ASSERT_NEAR(chi[3], 47.6667, 0.001); ASSERT_NEAR(v[3], 48.6667, 0.001); ASSERT_EQ(pi[3], 2); + ASSERT_NEAR(chi[4], 47.6667, 0.001); ASSERT_NEAR(v[4], 70.3333, 0.001); ASSERT_EQ(pi[4], 6); + ASSERT_NEAR(chi[5], 47.6667, 0.001); ASSERT_NEAR(v[5], 57.6667, 0.001); ASSERT_EQ(pi[5], 4); + ASSERT_NEAR(chi[6], 47.6667, 0.001); ASSERT_NEAR(v[6], 82.0, 0.001); ASSERT_EQ(pi[6], 1); + ASSERT_NEAR(chi[7], 47.6667, 0.001); ASSERT_NEAR(v[7], 71.0, 0.001); ASSERT_EQ(pi[7], 5); } //------------------------------------------------------------------------------ @@ -132,6 +132,7 @@ TEST(TestHoward, TestPetriNetSemiSimple) // Check dummy result is set to "invalid". CriticalCycleResult res; ASSERT_EQ(res.success, false); + ASSERT_EQ(res.cycles, 0u); ASSERT_EQ(res.eigenvector.size(), 0u); ASSERT_EQ(res.durations.size(), 0u); ASSERT_EQ(res.arcs.size(), 0u); @@ -143,6 +144,7 @@ TEST(TestHoward, TestPetriNetSemiSimple) ASSERT_EQ(net.isEmpty(), false); res = findCriticalCycle(net); ASSERT_EQ(res.success, false); + ASSERT_EQ(res.cycles, 0u); ASSERT_EQ(res.eigenvector.size(), 0u); ASSERT_EQ(res.durations.size(), 0u); ASSERT_NE(res.arcs.size(), 0u); @@ -154,6 +156,7 @@ TEST(TestHoward, TestPetriNetSemiSimple) ASSERT_EQ(net.isEmpty(), false); res = findCriticalCycle(net); ASSERT_EQ(res.success, false); + ASSERT_EQ(res.cycles, 0u); ASSERT_EQ(res.eigenvector.size(), 0u); ASSERT_EQ(res.durations.size(), 0u); ASSERT_EQ(res.arcs.size(), 0u); @@ -165,36 +168,189 @@ TEST(TestHoward, TestPetriNetSemiSimple) ASSERT_EQ(net.isEmpty(), false); res = findCriticalCycle(net); ASSERT_EQ(res.success, true); + ASSERT_EQ(res.cycles, 1u); ASSERT_EQ(res.eigenvector.size(), 4u); - ASSERT_EQ(res.eigenvector[0], 0.0f); - ASSERT_EQ(res.eigenvector[1], 5.0f); - ASSERT_EQ(res.eigenvector[2], 8.0f); - ASSERT_EQ(res.eigenvector[3], 1.0f); + ASSERT_EQ(res.eigenvector[0], 0.0); + ASSERT_EQ(res.eigenvector[1], 5.0); + ASSERT_EQ(res.eigenvector[2], 8.0); + ASSERT_EQ(res.eigenvector[3], 1.0); ASSERT_EQ(res.durations.size(), 4u); - ASSERT_EQ(res.durations[0], 6.5f); - ASSERT_EQ(res.durations[1], 6.5f); - ASSERT_EQ(res.durations[2], 6.5f); - ASSERT_EQ(res.durations[3], 6.5f); - //ASSERT_EQ(res.optimal_policy.size(), 4u); - //ASSERT_EQ(res.optimal_policy[0], 2u); - //ASSERT_EQ(res.optimal_policy[1], 0u); + ASSERT_EQ(res.durations[0], 6.5); + ASSERT_EQ(res.durations[1], 6.5); + ASSERT_EQ(res.durations[2], 6.5); + ASSERT_EQ(res.durations[3], 6.5); ASSERT_EQ(res.arcs.size(), 8u); - ASSERT_STREQ(res.arcs[0]->from.key.c_str(), "T2"); + ASSERT_STREQ(res.arcs[0]->from.key.c_str(), "T0"); ASSERT_STREQ(res.arcs[0]->to.key.c_str(), "P0"); ASSERT_STREQ(res.arcs[1]->from.key.c_str(), "P0"); - ASSERT_STREQ(res.arcs[1]->to.key.c_str(), "T0"); - ASSERT_STREQ(res.arcs[2]->from.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[1]->to.key.c_str(), "T2"); + ASSERT_STREQ(res.arcs[2]->from.key.c_str(), "T1"); ASSERT_STREQ(res.arcs[2]->to.key.c_str(), "P1"); ASSERT_STREQ(res.arcs[3]->from.key.c_str(), "P1"); - ASSERT_STREQ(res.arcs[3]->to.key.c_str(), "T1"); - ASSERT_STREQ(res.arcs[4]->from.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[3]->to.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[4]->from.key.c_str(), "T2"); ASSERT_STREQ(res.arcs[4]->to.key.c_str(), "P2"); ASSERT_STREQ(res.arcs[5]->from.key.c_str(), "P2"); - ASSERT_STREQ(res.arcs[5]->to.key.c_str(), "T2"); - ASSERT_STREQ(res.arcs[6]->from.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[5]->to.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[6]->from.key.c_str(), "T3"); ASSERT_STREQ(res.arcs[6]->to.key.c_str(), "P3"); ASSERT_STREQ(res.arcs[7]->from.key.c_str(), "P3"); - ASSERT_STREQ(res.arcs[7]->to.key.c_str(), "T3"); - ASSERT_STREQ(res.message.str().substr(0u, 51u).c_str(), - "Found 1 connected components of the optimal policy:"); + ASSERT_STREQ(res.arcs[7]->to.key.c_str(), "T0"); + + std::stringstream expected; + expected << "Found 1 connected components of the optimal policy:\n" + << " T2 -> T0\n" + << " T0 -> T1\n" + << " T1 -> T2\n" + << " T0 -> T3\n" + << "Cycle durations [unit of time]:\n" + << " T0: 6.5\n" + << " T1: 6.5\n" + << " T2: 6.5\n" + << " T3: 6.5\n" + << "Eigenvector:\n" + << " 0\n" + << " 5\n" + << " 8\n" + << " 1\n"; + ASSERT_STREQ(res.message.str().c_str(), expected.str().c_str()); +} + +//------------------------------------------------------------------------------ +TEST(TestHoward, TestSemiHowardExample) +{ + Net net(TypeOfNet::TimedPetriNet); + + ASSERT_STREQ(loadFromFile(net, "../data/examples/SemiHoward.teg").c_str(), ""); + CriticalCycleResult res = findCriticalCycle(net); + ASSERT_EQ(res.success, true); + ASSERT_EQ(res.cycles, 2u); + ASSERT_EQ(res.eigenvector.size(), 3u); + ASSERT_EQ(res.eigenvector[0], 0.0); + ASSERT_EQ(res.eigenvector[1], 1.0); + ASSERT_EQ(res.eigenvector[2], 2.0); + ASSERT_EQ(res.durations.size(), 3u); + ASSERT_EQ(res.durations[0], 1.0); + ASSERT_EQ(res.durations[1], 1.0); + ASSERT_EQ(res.durations[2], 2.0); + ASSERT_EQ(res.arcs.size(), 6u); + ASSERT_STREQ(res.arcs[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[0]->to.key.c_str(), "P0"); + ASSERT_STREQ(res.arcs[1]->from.key.c_str(), "P0"); + ASSERT_STREQ(res.arcs[1]->to.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[2]->from.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[2]->to.key.c_str(), "P1"); + ASSERT_STREQ(res.arcs[3]->from.key.c_str(), "P1"); + ASSERT_STREQ(res.arcs[3]->to.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[4]->from.key.c_str(), "T2"); + ASSERT_STREQ(res.arcs[4]->to.key.c_str(), "P4"); + ASSERT_STREQ(res.arcs[5]->from.key.c_str(), "P4"); + ASSERT_STREQ(res.arcs[5]->to.key.c_str(), "T2"); + + std::stringstream expected; + expected << "Found 2 connected components of the optimal policy:\n" + << " T1 -> T0\n" + << " T0 -> T1\n" + << " T2 -> T2\n" + << "Cycle durations [unit of time]:\n" + << " T0: 1\n" + << " T1: 1\n" + << " T2: 2\n" + << "Eigenvector:\n" + << " 0\n" + << " 1\n" + << " 2\n"; + ASSERT_STREQ(res.message.str().c_str(), expected.str().c_str()); } + +//------------------------------------------------------------------------------ +TEST(TestHoward, TestSemiNetherlandsExample) +{ + Net net(TypeOfNet::TimedPetriNet); + + ASSERT_STREQ(loadFromFile(net, "../data/examples/SemiNetherlands.teg").c_str(), ""); + CriticalCycleResult res = findCriticalCycle(net); + ASSERT_EQ(res.success, true); + ASSERT_EQ(res.cycles, 1u); + ASSERT_EQ(res.eigenvector.size(), 8u); + ASSERT_NEAR(res.eigenvector[0], 47.6667, 0.001); + ASSERT_NEAR(res.eigenvector[1], 82.0, 0.001); + ASSERT_NEAR(res.eigenvector[2], 58.0, 0.001); + ASSERT_NEAR(res.eigenvector[3], 48.6667, 0.001); + ASSERT_NEAR(res.eigenvector[4], 70.3333, 0.001); + ASSERT_NEAR(res.eigenvector[5], 57.6667, 0.001); + ASSERT_NEAR(res.eigenvector[6], 82.0, 0.001); + ASSERT_NEAR(res.eigenvector[7], 71.0, 0.001); + ASSERT_EQ(res.durations.size(), 8u); + ASSERT_NEAR(res.durations[0], 47.6667, 0.001); + ASSERT_NEAR(res.durations[1], 47.6667, 0.001); + ASSERT_NEAR(res.durations[2], 47.6667, 0.001); + ASSERT_NEAR(res.durations[3], 47.6667, 0.001); + ASSERT_NEAR(res.durations[4], 47.6667, 0.001); + ASSERT_NEAR(res.durations[5], 47.6667, 0.001); + ASSERT_NEAR(res.durations[6], 47.6667, 0.001); + ASSERT_NEAR(res.durations[7], 47.6667, 0.001); + ASSERT_EQ(res.arcs.size(), 16u); + ASSERT_STREQ(res.arcs[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[0]->to.key.c_str(), "P0"); + ASSERT_STREQ(res.arcs[1]->from.key.c_str(), "P0"); + ASSERT_STREQ(res.arcs[1]->to.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[2]->from.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[2]->to.key.c_str(), "P1"); + ASSERT_STREQ(res.arcs[3]->from.key.c_str(), "P1"); + ASSERT_STREQ(res.arcs[3]->to.key.c_str(), "T3"); + ASSERT_STREQ(res.arcs[4]->from.key.c_str(), "T2"); + ASSERT_STREQ(res.arcs[4]->to.key.c_str(), "P2"); + ASSERT_STREQ(res.arcs[5]->from.key.c_str(), "P2"); + ASSERT_STREQ(res.arcs[5]->to.key.c_str(), "T0"); + ASSERT_STREQ(res.arcs[6]->from.key.c_str(), "T3"); + ASSERT_STREQ(res.arcs[6]->to.key.c_str(), "P4"); + ASSERT_STREQ(res.arcs[7]->from.key.c_str(), "P4"); + ASSERT_STREQ(res.arcs[7]->to.key.c_str(), "T2"); + ASSERT_STREQ(res.arcs[8]->from.key.c_str(), "T4"); + ASSERT_STREQ(res.arcs[8]->to.key.c_str(), "P7"); + ASSERT_STREQ(res.arcs[9]->from.key.c_str(), "P7"); + ASSERT_STREQ(res.arcs[9]->to.key.c_str(), "T6"); + ASSERT_STREQ(res.arcs[10]->from.key.c_str(), "T5"); + ASSERT_STREQ(res.arcs[10]->to.key.c_str(), "P8"); + ASSERT_STREQ(res.arcs[11]->from.key.c_str(), "P8"); + ASSERT_STREQ(res.arcs[11]->to.key.c_str(), "T4"); + ASSERT_STREQ(res.arcs[12]->from.key.c_str(), "T6"); + ASSERT_STREQ(res.arcs[12]->to.key.c_str(), "P9"); + ASSERT_STREQ(res.arcs[13]->from.key.c_str(), "P9"); + ASSERT_STREQ(res.arcs[13]->to.key.c_str(), "T1"); + ASSERT_STREQ(res.arcs[14]->from.key.c_str(), "T7"); + ASSERT_STREQ(res.arcs[14]->to.key.c_str(), "P11"); + ASSERT_STREQ(res.arcs[15]->from.key.c_str(), "P11"); + ASSERT_STREQ(res.arcs[15]->to.key.c_str(), "T5"); + + std::stringstream expected; + expected << "Found 1 connected components of the optimal policy:\n" + << " T1 -> T0\n" + << " T3 -> T1\n" + << " T0 -> T2\n" + << " T2 -> T3\n" + << " T6 -> T4\n" + << " T4 -> T5\n" + << " T1 -> T6\n" + << " T5 -> T7\n" + << "Cycle durations [unit of time]:\n" + << " T0: 47.6667\n" + << " T1: 47.6667\n" + << " T2: 47.6667\n" + << " T3: 47.6667\n" + << " T4: 47.6667\n" + << " T5: 47.6667\n" + << " T6: 47.6667\n" + << " T7: 47.6667\n" + << "Eigenvector:\n" + << " 47.6667\n" + << " 82\n" + << " 58\n" + << " 48.6667\n" + << " 70.3333\n" + << " 57.6667\n" + << " 82\n" + << " 71\n"; + ASSERT_STREQ(res.message.str().c_str(), expected.str().c_str()); +} \ No newline at end of file diff --git a/tests/PetriNetTests.cpp b/tests/PetriNetTests.cpp index b604bf7..b5c9996 100644 --- a/tests/PetriNetTests.cpp +++ b/tests/PetriNetTests.cpp @@ -747,10 +747,10 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_places[0].tokens, 2u); ASSERT_EQ(net.m_places[0].arcsIn.size(), 1u); ASSERT_EQ(net.m_places[0].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_places[0].arcsIn[0]->from.key.c_str(), "T2"); + ASSERT_STREQ(net.m_places[0].arcsIn[0]->from.key.c_str(), "T0"); ASSERT_STREQ(net.m_places[0].arcsIn[0]->to.key.c_str(), "P0"); ASSERT_STREQ(net.m_places[0].arcsOut[0]->from.key.c_str(), "P0"); - ASSERT_STREQ(net.m_places[0].arcsOut[0]->to.key.c_str(), "T0"); + ASSERT_STREQ(net.m_places[0].arcsOut[0]->to.key.c_str(), "T2"); ASSERT_EQ(net.m_places[1].id, 1u); ASSERT_STREQ(net.m_places[1].key.c_str(), "P1"); @@ -759,10 +759,10 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_places[1].tokens, 0u); ASSERT_EQ(net.m_places[1].arcsIn.size(), 1u); ASSERT_EQ(net.m_places[1].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_places[1].arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(net.m_places[1].arcsIn[0]->from.key.c_str(), "T1"); ASSERT_STREQ(net.m_places[1].arcsIn[0]->to.key.c_str(), "P1"); ASSERT_STREQ(net.m_places[1].arcsOut[0]->from.key.c_str(), "P1"); - ASSERT_STREQ(net.m_places[1].arcsOut[0]->to.key.c_str(), "T1"); + ASSERT_STREQ(net.m_places[1].arcsOut[0]->to.key.c_str(), "T0"); ASSERT_EQ(net.m_places[2].id, 2u); ASSERT_STREQ(net.m_places[2].key.c_str(), "P2"); @@ -771,10 +771,10 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_places[2].tokens, 0u); ASSERT_EQ(net.m_places[2].arcsIn.size(), 1u); ASSERT_EQ(net.m_places[2].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_places[2].arcsIn[0]->from.key.c_str(), "T1"); + ASSERT_STREQ(net.m_places[2].arcsIn[0]->from.key.c_str(), "T2"); ASSERT_STREQ(net.m_places[2].arcsIn[0]->to.key.c_str(), "P2"); ASSERT_STREQ(net.m_places[2].arcsOut[0]->from.key.c_str(), "P2"); - ASSERT_STREQ(net.m_places[2].arcsOut[0]->to.key.c_str(), "T2"); + ASSERT_STREQ(net.m_places[2].arcsOut[0]->to.key.c_str(), "T1"); ASSERT_EQ(net.m_places[3].id, 3u); ASSERT_STREQ(net.m_places[3].key.c_str(), "P3"); @@ -783,10 +783,10 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_places[3].tokens, 0u); ASSERT_EQ(net.m_places[3].arcsIn.size(), 1u); ASSERT_EQ(net.m_places[3].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_places[3].arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(net.m_places[3].arcsIn[0]->from.key.c_str(), "T3"); ASSERT_STREQ(net.m_places[3].arcsIn[0]->to.key.c_str(), "P3"); ASSERT_STREQ(net.m_places[3].arcsOut[0]->from.key.c_str(), "P3"); - ASSERT_STREQ(net.m_places[3].arcsOut[0]->to.key.c_str(), "T3"); + ASSERT_STREQ(net.m_places[3].arcsOut[0]->to.key.c_str(), "T0"); ASSERT_EQ(net.m_places[4].id, 4u); ASSERT_STREQ(net.m_places[4].key.c_str(), "P4"); @@ -795,24 +795,24 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_places[4].tokens, 0u); ASSERT_EQ(net.m_places[4].arcsIn.size(), 1u); ASSERT_EQ(net.m_places[4].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_places[4].arcsIn[0]->from.key.c_str(), "T3"); + ASSERT_STREQ(net.m_places[4].arcsIn[0]->from.key.c_str(), "T2"); ASSERT_STREQ(net.m_places[4].arcsIn[0]->to.key.c_str(), "P4"); ASSERT_STREQ(net.m_places[4].arcsOut[0]->from.key.c_str(), "P4"); - ASSERT_STREQ(net.m_places[4].arcsOut[0]->to.key.c_str(), "T2"); + ASSERT_STREQ(net.m_places[4].arcsOut[0]->to.key.c_str(), "T3"); // Check transitions ASSERT_EQ(net.m_transitions[0].id, 0u); ASSERT_STREQ(net.m_transitions[0].key.c_str(), "T0"); ASSERT_STREQ(net.m_transitions[0].caption.c_str(), "T0"); ASSERT_EQ(net.m_transitions[0].type, Node::Transition); - ASSERT_EQ(net.m_transitions[0].arcsIn.size(), 1u); - ASSERT_EQ(net.m_transitions[0].arcsOut.size(), 2u); - ASSERT_STREQ(net.m_transitions[0].arcsIn[0]->from.key.c_str(), "P0"); - ASSERT_STREQ(net.m_transitions[0].arcsIn[0]->to.key.c_str(), "T0"); + ASSERT_EQ(net.m_transitions[0].arcsIn.size(), 2u); + ASSERT_EQ(net.m_transitions[0].arcsOut.size(), 1u); ASSERT_STREQ(net.m_transitions[0].arcsOut[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(net.m_transitions[0].arcsOut[0]->to.key.c_str(), "P1"); - ASSERT_STREQ(net.m_transitions[0].arcsOut[1]->from.key.c_str(), "T0"); - ASSERT_STREQ(net.m_transitions[0].arcsOut[1]->to.key.c_str(), "P3"); + ASSERT_STREQ(net.m_transitions[0].arcsOut[0]->to.key.c_str(), "P0"); + ASSERT_STREQ(net.m_transitions[0].arcsIn[0]->from.key.c_str(), "P3"); + ASSERT_STREQ(net.m_transitions[0].arcsIn[0]->to.key.c_str(), "T0"); + ASSERT_STREQ(net.m_transitions[0].arcsIn[1]->from.key.c_str(), "P1"); + ASSERT_STREQ(net.m_transitions[0].arcsIn[1]->to.key.c_str(), "T0"); ASSERT_EQ(net.m_transitions[1].id, 1u); ASSERT_STREQ(net.m_transitions[1].key.c_str(), "T1"); @@ -820,23 +820,23 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_transitions[1].type, Node::Transition); ASSERT_EQ(net.m_transitions[1].arcsIn.size(), 1u); ASSERT_EQ(net.m_transitions[1].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_transitions[1].arcsIn[0]->from.key.c_str(), "P1"); + ASSERT_STREQ(net.m_transitions[1].arcsIn[0]->from.key.c_str(), "P2"); ASSERT_STREQ(net.m_transitions[1].arcsIn[0]->to.key.c_str(), "T1"); ASSERT_STREQ(net.m_transitions[1].arcsOut[0]->from.key.c_str(), "T1"); - ASSERT_STREQ(net.m_transitions[1].arcsOut[0]->to.key.c_str(), "P2"); + ASSERT_STREQ(net.m_transitions[1].arcsOut[0]->to.key.c_str(), "P1"); ASSERT_EQ(net.m_transitions[2].id, 2u); ASSERT_STREQ(net.m_transitions[2].key.c_str(), "T2"); ASSERT_STREQ(net.m_transitions[2].caption.c_str(), "T2"); ASSERT_EQ(net.m_transitions[2].type, Node::Transition); - ASSERT_EQ(net.m_transitions[2].arcsIn.size(), 2u); - ASSERT_EQ(net.m_transitions[2].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_transitions[2].arcsIn[0]->from.key.c_str(), "P2"); - ASSERT_STREQ(net.m_transitions[2].arcsIn[0]->to.key.c_str(), "T2"); - ASSERT_STREQ(net.m_transitions[2].arcsIn[1]->from.key.c_str(), "P4"); - ASSERT_STREQ(net.m_transitions[2].arcsIn[1]->to.key.c_str(), "T2"); + ASSERT_EQ(net.m_transitions[2].arcsIn.size(), 1u); + ASSERT_EQ(net.m_transitions[2].arcsOut.size(), 2u); ASSERT_STREQ(net.m_transitions[2].arcsOut[0]->from.key.c_str(), "T2"); - ASSERT_STREQ(net.m_transitions[2].arcsOut[0]->to.key.c_str(), "P0"); + ASSERT_STREQ(net.m_transitions[2].arcsOut[0]->to.key.c_str(), "P2"); + ASSERT_STREQ(net.m_transitions[2].arcsOut[1]->from.key.c_str(), "T2"); + ASSERT_STREQ(net.m_transitions[2].arcsOut[1]->to.key.c_str(), "P4"); + ASSERT_STREQ(net.m_transitions[2].arcsIn[0]->from.key.c_str(), "P0"); + ASSERT_STREQ(net.m_transitions[2].arcsIn[0]->to.key.c_str(), "T2"); ASSERT_EQ(net.m_transitions[3].id, 3u); ASSERT_STREQ(net.m_transitions[3].key.c_str(), "T3"); @@ -844,91 +844,91 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_transitions[3].type, Node::Transition); ASSERT_EQ(net.m_transitions[3].arcsIn.size(), 1u); ASSERT_EQ(net.m_transitions[3].arcsOut.size(), 1u); - ASSERT_STREQ(net.m_transitions[3].arcsIn[0]->from.key.c_str(), "P3"); + ASSERT_STREQ(net.m_transitions[3].arcsIn[0]->from.key.c_str(), "P4"); ASSERT_STREQ(net.m_transitions[3].arcsIn[0]->to.key.c_str(), "T3"); ASSERT_STREQ(net.m_transitions[3].arcsOut[0]->from.key.c_str(), "T3"); - ASSERT_STREQ(net.m_transitions[3].arcsOut[0]->to.key.c_str(), "P4"); + ASSERT_STREQ(net.m_transitions[3].arcsOut[0]->to.key.c_str(), "P3"); // Check arcs - ASSERT_EQ(net.m_arcs[0].from.id, 0u); + ASSERT_EQ(net.m_arcs[0].from.id, 3u); ASSERT_EQ(net.m_arcs[0].from.type, Node::Place); - ASSERT_STREQ(net.m_arcs[0].from.key.c_str(), "P0"); + ASSERT_STREQ(net.m_arcs[0].from.key.c_str(), "P3"); ASSERT_EQ(net.m_arcs[0].to.id, 0u); ASSERT_EQ(net.m_arcs[0].to.type, Node::Transition); ASSERT_STREQ(net.m_arcs[0].to.key.c_str(), "T0"); ASSERT_EQ(isnan(net.m_arcs[0].duration), true); // FIXME forcer json a NAN ? - ASSERT_EQ(net.m_arcs[1].from.id, 0u); - ASSERT_EQ(net.m_arcs[1].from.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[1].from.key.c_str(), "T0"); - ASSERT_EQ(net.m_arcs[1].to.id, 1u); - ASSERT_EQ(net.m_arcs[1].to.type, Node::Place); - ASSERT_STREQ(net.m_arcs[1].to.key.c_str(), "P1"); - ASSERT_EQ(net.m_arcs[1].duration, 5u); - - ASSERT_EQ(net.m_arcs[2].from.id, 1u); - ASSERT_EQ(net.m_arcs[2].from.type, Node::Place); - ASSERT_STREQ(net.m_arcs[2].from.key.c_str(), "P1"); - ASSERT_EQ(net.m_arcs[2].to.id, 1u); - ASSERT_EQ(net.m_arcs[2].to.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[2].to.key.c_str(), "T1"); - ASSERT_EQ(isnan(net.m_arcs[2].duration), true); - - ASSERT_EQ(net.m_arcs[3].from.id, 1u); - ASSERT_EQ(net.m_arcs[3].from.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[3].from.key.c_str(), "T1"); + ASSERT_EQ(net.m_arcs[1].from.id, 1u); + ASSERT_EQ(net.m_arcs[1].from.type, Node::Place); + ASSERT_STREQ(net.m_arcs[1].from.key.c_str(), "P1"); + ASSERT_EQ(net.m_arcs[1].to.id, 0u); + ASSERT_EQ(net.m_arcs[1].to.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[1].to.key.c_str(), "T0"); + ASSERT_EQ(isnan(net.m_arcs[1].duration), true); + + ASSERT_EQ(net.m_arcs[2].from.id, 0u); + ASSERT_EQ(net.m_arcs[2].from.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[2].from.key.c_str(), "T0"); + ASSERT_EQ(net.m_arcs[2].to.id, 0u); + ASSERT_EQ(net.m_arcs[2].to.type, Node::Place); + ASSERT_STREQ(net.m_arcs[2].to.key.c_str(), "P0"); + ASSERT_EQ(net.m_arcs[2].duration, 5u); + + ASSERT_EQ(net.m_arcs[3].from.id, 0u); + ASSERT_EQ(net.m_arcs[3].from.type, Node::Place); + ASSERT_STREQ(net.m_arcs[3].from.key.c_str(), "P0"); ASSERT_EQ(net.m_arcs[3].to.id, 2u); - ASSERT_EQ(net.m_arcs[3].to.type, Node::Place); - ASSERT_STREQ(net.m_arcs[3].to.key.c_str(), "P2"); - ASSERT_EQ(net.m_arcs[3].duration, 3u); + ASSERT_EQ(net.m_arcs[3].to.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[3].to.key.c_str(), "T2"); + ASSERT_EQ(isnan(net.m_arcs[3].duration), true); ASSERT_EQ(net.m_arcs[4].from.id, 2u); - ASSERT_EQ(net.m_arcs[4].from.type, Node::Place); - ASSERT_STREQ(net.m_arcs[4].from.key.c_str(), "P2"); + ASSERT_EQ(net.m_arcs[4].from.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[4].from.key.c_str(), "T2"); ASSERT_EQ(net.m_arcs[4].to.id, 2u); - ASSERT_EQ(net.m_arcs[4].to.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[4].to.key.c_str(), "T2"); - ASSERT_EQ(isnan(net.m_arcs[4].duration), true); // FIXME forcer json a NAN ? + ASSERT_EQ(net.m_arcs[4].to.type, Node::Place); + ASSERT_STREQ(net.m_arcs[4].to.key.c_str(), "P2"); + ASSERT_EQ(net.m_arcs[4].duration, 3u); ASSERT_EQ(net.m_arcs[5].from.id, 2u); - ASSERT_EQ(net.m_arcs[5].from.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[5].from.key.c_str(), "T2"); - ASSERT_EQ(net.m_arcs[5].to.id, 0u); - ASSERT_EQ(net.m_arcs[5].to.type, Node::Place); - ASSERT_STREQ(net.m_arcs[5].to.key.c_str(), "P0"); - ASSERT_EQ(net.m_arcs[5].duration, 5u); - - ASSERT_EQ(net.m_arcs[6].from.id, 0u); + ASSERT_EQ(net.m_arcs[5].from.type, Node::Place); + ASSERT_STREQ(net.m_arcs[5].from.key.c_str(), "P2"); + ASSERT_EQ(net.m_arcs[5].to.id, 1u); + ASSERT_EQ(net.m_arcs[5].to.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[5].to.key.c_str(), "T1"); + ASSERT_EQ(isnan(net.m_arcs[5].duration), true); + + ASSERT_EQ(net.m_arcs[6].from.id, 1u); ASSERT_EQ(net.m_arcs[6].from.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[6].from.key.c_str(), "T0"); - ASSERT_EQ(net.m_arcs[6].to.id, 3u); + ASSERT_STREQ(net.m_arcs[6].from.key.c_str(), "T1"); + ASSERT_EQ(net.m_arcs[6].to.id, 1u); ASSERT_EQ(net.m_arcs[6].to.type, Node::Place); - ASSERT_STREQ(net.m_arcs[6].to.key.c_str(), "P3"); - ASSERT_EQ(net.m_arcs[6].duration, 1u); - - ASSERT_EQ(net.m_arcs[7].from.id, 3u); - ASSERT_EQ(net.m_arcs[7].from.type, Node::Place); - ASSERT_STREQ(net.m_arcs[7].from.key.c_str(), "P3"); - ASSERT_EQ(net.m_arcs[7].to.id, 3u); - ASSERT_EQ(net.m_arcs[7].to.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[7].to.key.c_str(), "T3"); - ASSERT_EQ(isnan(net.m_arcs[7].duration), true); // FIXME forcer json a NAN ? - - ASSERT_EQ(net.m_arcs[8].from.id, 3u); - ASSERT_EQ(net.m_arcs[8].from.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[8].from.key.c_str(), "T3"); - ASSERT_EQ(net.m_arcs[8].to.id, 4u); - ASSERT_EQ(net.m_arcs[8].to.type, Node::Place); - ASSERT_STREQ(net.m_arcs[8].to.key.c_str(), "P4"); - ASSERT_EQ(net.m_arcs[8].duration, 1u); - - ASSERT_EQ(net.m_arcs[9].from.id, 4u); - ASSERT_EQ(net.m_arcs[9].from.type, Node::Place); - ASSERT_STREQ(net.m_arcs[9].from.key.c_str(), "P4"); - ASSERT_EQ(net.m_arcs[9].to.id, 2u); - ASSERT_EQ(net.m_arcs[9].to.type, Node::Transition); - ASSERT_STREQ(net.m_arcs[9].to.key.c_str(), "T2"); - ASSERT_EQ(isnan(net.m_arcs[9].duration), true); // FIXME forcer json a NAN ? + ASSERT_STREQ(net.m_arcs[6].to.key.c_str(), "P1"); + ASSERT_EQ(net.m_arcs[6].duration, 5u); + + ASSERT_EQ(net.m_arcs[7].from.id, 2u); + ASSERT_EQ(net.m_arcs[7].from.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[7].from.key.c_str(), "T2"); + ASSERT_EQ(net.m_arcs[7].to.id, 4u); + ASSERT_EQ(net.m_arcs[7].to.type, Node::Place); + ASSERT_STREQ(net.m_arcs[7].to.key.c_str(), "P4"); + ASSERT_EQ(net.m_arcs[7].duration, 1u); + + ASSERT_EQ(net.m_arcs[8].from.id, 4u); + ASSERT_EQ(net.m_arcs[8].from.type, Node::Place); + ASSERT_STREQ(net.m_arcs[8].from.key.c_str(), "P4"); + ASSERT_EQ(net.m_arcs[8].to.id, 3u); + ASSERT_EQ(net.m_arcs[8].to.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[8].to.key.c_str(), "T3"); + ASSERT_EQ(isnan(net.m_arcs[8].duration), true); + + ASSERT_EQ(net.m_arcs[9].from.id, 3u); + ASSERT_EQ(net.m_arcs[9].from.type, Node::Transition); + ASSERT_STREQ(net.m_arcs[9].from.key.c_str(), "T3"); + ASSERT_EQ(net.m_arcs[9].to.id, 3u); + ASSERT_EQ(net.m_arcs[9].to.type, Node::Place); + ASSERT_STREQ(net.m_arcs[9].to.key.c_str(), "P3"); + ASSERT_EQ(net.m_arcs[9].duration, 1u); // Can we access to nodes ? ASSERT_EQ(net.isEmpty(), false); @@ -961,60 +961,70 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) // Can we access to arcs ? Arc* arc; - arc = net.findArc(*net.findNode("T0"), *net.findNode("P1")); + arc = net.findArc(*net.findNode("P3"), *net.findNode("T0")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "T0"); - ASSERT_STREQ(arc->to.key.c_str(), "P1"); - - arc = net.findArc(*net.findNode("T0"), *net.findNode("P3")); - ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "T0"); - ASSERT_STREQ(arc->to.key.c_str(), "P3"); + ASSERT_STREQ(arc->from.key.c_str(), "P3"); + ASSERT_STREQ(arc->to.key.c_str(), "T0"); + ASSERT_EQ(isnan(arc->duration), true); - arc = net.findArc(*net.findNode("T1"), *net.findNode("P2")); + arc = net.findArc(*net.findNode("P1"), *net.findNode("T0")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "T1"); - ASSERT_STREQ(arc->to.key.c_str(), "P2"); + ASSERT_STREQ(arc->from.key.c_str(), "P1"); + ASSERT_STREQ(arc->to.key.c_str(), "T0"); + ASSERT_EQ(isnan(arc->duration), true); - arc = net.findArc(*net.findNode("T2"), *net.findNode("P0")); + arc = net.findArc(*net.findNode("T0"), *net.findNode("P0")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "T2"); + ASSERT_STREQ(arc->from.key.c_str(), "T0"); ASSERT_STREQ(arc->to.key.c_str(), "P0"); + ASSERT_EQ(arc->duration, 5u); - arc = net.findArc(*net.findNode("T3"), *net.findNode("P4")); + arc = net.findArc(*net.findNode("P0"), *net.findNode("T2")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "T3"); - ASSERT_STREQ(arc->to.key.c_str(), "P4"); + ASSERT_STREQ(arc->from.key.c_str(), "P0"); + ASSERT_STREQ(arc->to.key.c_str(), "T2"); + ASSERT_EQ(isnan(arc->duration), true); - arc = net.findArc(*net.findNode("P0"), *net.findNode("T0")); + arc = net.findArc(*net.findNode("T2"), *net.findNode("P2")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "P0"); - ASSERT_STREQ(arc->to.key.c_str(), "T0"); + ASSERT_STREQ(arc->from.key.c_str(), "T2"); + ASSERT_STREQ(arc->to.key.c_str(), "P2"); + ASSERT_EQ(arc->duration, 3u); - arc = net.findArc(*net.findNode("P1"), *net.findNode("T1")); + arc = net.findArc(*net.findNode("P2"), *net.findNode("T1")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "P1"); + ASSERT_STREQ(arc->from.key.c_str(), "P2"); ASSERT_STREQ(arc->to.key.c_str(), "T1"); + ASSERT_EQ(isnan(arc->duration), true); - arc = net.findArc(*net.findNode("P2"), *net.findNode("T2")); + arc = net.findArc(*net.findNode("T1"), *net.findNode("P1")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "P2"); - ASSERT_STREQ(arc->to.key.c_str(), "T2"); + ASSERT_STREQ(arc->from.key.c_str(), "T1"); + ASSERT_STREQ(arc->to.key.c_str(), "P1"); + ASSERT_EQ(arc->duration, 5u); - arc = net.findArc(*net.findNode("P3"), *net.findNode("T3")); + arc = net.findArc(*net.findNode("T2"), *net.findNode("P4")); ASSERT_NE(arc, nullptr); - ASSERT_STREQ(arc->from.key.c_str(), "P3"); - ASSERT_STREQ(arc->to.key.c_str(), "T3"); + ASSERT_STREQ(arc->from.key.c_str(), "T2"); + ASSERT_STREQ(arc->to.key.c_str(), "P4"); + ASSERT_EQ(arc->duration, 1u); - arc = net.findArc(*net.findNode("P4"), *net.findNode("T2")); + arc = net.findArc(*net.findNode("P4"), *net.findNode("T3")); ASSERT_NE(arc, nullptr); ASSERT_STREQ(arc->from.key.c_str(), "P4"); - ASSERT_STREQ(arc->to.key.c_str(), "T2"); + ASSERT_STREQ(arc->to.key.c_str(), "T3"); + ASSERT_EQ(isnan(arc->duration), true); + + arc = net.findArc(*net.findNode("T3"), *net.findNode("P3")); + ASSERT_NE(arc, nullptr); + ASSERT_STREQ(arc->from.key.c_str(), "T3"); + ASSERT_STREQ(arc->to.key.c_str(), "P3"); + ASSERT_EQ(arc->duration, 1u); // At least one token - ASSERT_EQ(net.m_transitions[0].isValidated(), true); + ASSERT_EQ(net.m_transitions[0].isValidated(), false); ASSERT_EQ(net.m_transitions[1].isValidated(), false); - ASSERT_EQ(net.m_transitions[2].isValidated(), false); + ASSERT_EQ(net.m_transitions[2].isValidated(), true); ASSERT_EQ(net.m_transitions[3].isValidated(), false); #if 0 // FIXMEEEEEEEEEE A FINALISER @@ -1352,7 +1362,7 @@ TEST(TestPetriNet, TestRemoveNode) ASSERT_EQ(net.m_transitions.size(), 4u); ASSERT_EQ(net.m_arcs.size(), 10u); - // Delete Transition 0 + // *** Delete Transition 0. Check that T3 is now T0 net.removeNode(*net.findNode("T0")); ASSERT_EQ(net.m_next_place_id, 5u); ASSERT_EQ(net.m_next_transition_id, 3u); @@ -1360,7 +1370,7 @@ TEST(TestPetriNet, TestRemoveNode) ASSERT_EQ(net.m_transitions.size(), 3u); ASSERT_EQ(net.m_arcs.size(), 7u); - // Check Places + // Check Places are all here ASSERT_NE(net.findPlace(0u), nullptr); ASSERT_NE(net.findPlace(1u), nullptr); ASSERT_NE(net.findPlace(2u), nullptr); @@ -1368,20 +1378,24 @@ TEST(TestPetriNet, TestRemoveNode) ASSERT_NE(net.findPlace(4u), nullptr); ASSERT_EQ(net.findPlace(5u), nullptr); - // Check Transitions + // Check Transitions. Check T3 is no longer present while T0 has been removed ASSERT_NE(net.findTransition(0u), nullptr); ASSERT_NE(net.findTransition(1u), nullptr); ASSERT_NE(net.findTransition(2u), nullptr); ASSERT_EQ(net.findTransition(3u), nullptr); - // Check arcs - ASSERT_NE(net.findArc(*net.findTransition(2u), *net.findPlace(0u)), nullptr); - ASSERT_NE(net.findArc(*net.findTransition(1u), *net.findPlace(2u)), nullptr); - ASSERT_NE(net.findArc(*net.findTransition(0u), *net.findPlace(4u)), nullptr); - ASSERT_NE(net.findArc(*net.findPlace(1u), *net.findTransition(1u)), nullptr); - ASSERT_NE(net.findArc(*net.findPlace(2u), *net.findTransition(2u)), nullptr); - ASSERT_NE(net.findArc(*net.findPlace(3u), *net.findTransition(0u)), nullptr); - ASSERT_NE(net.findArc(*net.findPlace(4u), *net.findTransition(2u)), nullptr); + // Check arcs from/to previous T0 no longer exist. + // Check arcs from/to previous T3 (now T0) exist. + ASSERT_EQ(net.findArc(*net.findPlace(3u), *net.findTransition(0u)), nullptr); + ASSERT_EQ(net.findArc(*net.findPlace(1u), *net.findTransition(0u)), nullptr); + ASSERT_EQ(net.findArc(*net.findTransition(0u), *net.findPlace(0u)), nullptr); + ASSERT_NE(net.findArc(*net.findPlace(0u), *net.findTransition(2u)), nullptr); + ASSERT_NE(net.findArc(*net.findTransition(2u), *net.findPlace(2u)), nullptr); + ASSERT_NE(net.findArc(*net.findPlace(2u), *net.findTransition(1u)), nullptr); + ASSERT_NE(net.findArc(*net.findTransition(1u), *net.findPlace(1u)), nullptr); + ASSERT_NE(net.findArc(*net.findTransition(2u), *net.findPlace(4u)), nullptr); + ASSERT_NE(net.findArc(*net.findPlace(4u), *net.findTransition(0u)), nullptr); + ASSERT_NE(net.findArc(*net.findTransition(0u), *net.findPlace(3u)), nullptr); // In/out arcs Transition // T0 (previously T3) @@ -1390,10 +1404,10 @@ TEST(TestPetriNet, TestRemoveNode) auto const& arcsOut = net.findTransition(0u)->arcsOut; ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P3"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P4"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T0"); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P4"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P3"); ASSERT_EQ(arcsOut[0]->duration, 1.0f); } // T1 @@ -1402,25 +1416,26 @@ TEST(TestPetriNet, TestRemoveNode) auto const& arcsOut = net.findTransition(1u)->arcsOut; ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P1"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P2"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T1"); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T1"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P2"); - ASSERT_EQ(arcsOut[0]->duration, 3.0f); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P1"); + ASSERT_EQ(arcsOut[0]->duration, 5.0f); } // T2 { auto const& arcsIn = net.findTransition(2u)->arcsIn; auto const& arcsOut = net.findTransition(2u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 2u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P2"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T2"); - ASSERT_STREQ(arcsIn[1]->from.key.c_str(), "P4"); - ASSERT_STREQ(arcsIn[1]->to.key.c_str(), "T2"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 2u); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T2"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P0"); - ASSERT_EQ(arcsOut[0]->duration, 5.0f); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P4"); + ASSERT_EQ(arcsOut[0]->duration, 1.0f); + ASSERT_STREQ(arcsOut[1]->from.key.c_str(), "T2"); + ASSERT_STREQ(arcsOut[1]->to.key.c_str(), "P2"); + ASSERT_EQ(arcsOut[1]->duration, 3.0f); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P0"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T2"); } // In/out arcs Place @@ -1428,19 +1443,19 @@ TEST(TestPetriNet, TestRemoveNode) { auto const& arcsIn = net.findPlace(0u)->arcsIn; auto const& arcsOut = net.findPlace(0u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 1u); - ASSERT_EQ(arcsOut.size(), 0u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T2"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P0"); + ASSERT_EQ(arcsIn.size(), 0u); + ASSERT_EQ(arcsOut.size(), 1u); + ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P0"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T2"); } // P1 { auto const& arcsIn = net.findPlace(1u)->arcsIn; auto const& arcsOut = net.findPlace(1u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 0u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P1"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T1"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 0u); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T1"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P1"); } // P2 { @@ -1449,18 +1464,18 @@ TEST(TestPetriNet, TestRemoveNode) ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P2"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T2"); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T1"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T1"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T2"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P2"); } // P3 { auto const& arcsIn = net.findPlace(3u)->arcsIn; auto const& arcsOut = net.findPlace(3u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 0u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P3"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 0u); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P3"); } // P4 { @@ -1469,12 +1484,12 @@ TEST(TestPetriNet, TestRemoveNode) ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P4"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T2"); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T2"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P4"); } - // Delete Transition 2 + // *** Delete Transition 2 net.removeNode(*net.findNode("T2")); ASSERT_EQ(net.m_next_place_id, 5u); ASSERT_EQ(net.m_next_transition_id, 2u); @@ -1488,10 +1503,10 @@ TEST(TestPetriNet, TestRemoveNode) auto const& arcsOut = net.findTransition(0u)->arcsOut; ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P3"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P4"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T0"); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P4"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P3"); ASSERT_EQ(arcsOut[0]->duration, 1.0f); } // T1 @@ -1500,11 +1515,11 @@ TEST(TestPetriNet, TestRemoveNode) auto const& arcsOut = net.findTransition(1u)->arcsOut; ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P1"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P2"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T1"); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T1"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P2"); - ASSERT_EQ(arcsOut[0]->duration, 3.0f); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P1"); + ASSERT_EQ(arcsOut[0]->duration, 5.0f); } // P0 { @@ -1517,40 +1532,40 @@ TEST(TestPetriNet, TestRemoveNode) { auto const& arcsIn = net.findPlace(1u)->arcsIn; auto const& arcsOut = net.findPlace(1u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 0u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P1"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T1"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 0u); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T1"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P1"); } // P2 { auto const& arcsIn = net.findPlace(2u)->arcsIn; auto const& arcsOut = net.findPlace(2u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 1u); - ASSERT_EQ(arcsOut.size(), 0u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T1"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P2"); + ASSERT_EQ(arcsIn.size(), 0u); + ASSERT_EQ(arcsOut.size(), 1u); + ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P2"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T1"); } // P3 { auto const& arcsIn = net.findPlace(3u)->arcsIn; auto const& arcsOut = net.findPlace(3u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 0u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P3"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 0u); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P3"); } // P4 { auto const& arcsIn = net.findPlace(4u)->arcsIn; auto const& arcsOut = net.findPlace(4u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 1u); - ASSERT_EQ(arcsOut.size(), 0u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P4"); + ASSERT_EQ(arcsIn.size(), 0u); + ASSERT_EQ(arcsOut.size(), 1u); + ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P4"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); } - // Delete Place 0: Place 4 becomes Place 0 + // *** Delete Place 0: Place 4 becomes Place 0 net.removeNode(*net.findNode("P0")); ASSERT_EQ(net.m_next_place_id, 4u); ASSERT_EQ(net.m_next_transition_id, 2u); @@ -1562,10 +1577,10 @@ TEST(TestPetriNet, TestRemoveNode) { auto const& arcsIn = net.findPlace(0u)->arcsIn; auto const& arcsOut = net.findPlace(0u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 1u); - ASSERT_EQ(arcsOut.size(), 0u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P0"); + ASSERT_EQ(arcsIn.size(), 0u); + ASSERT_EQ(arcsOut.size(), 1u); + ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P0"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); } // T0 { @@ -1573,36 +1588,36 @@ TEST(TestPetriNet, TestRemoveNode) auto const& arcsOut = net.findTransition(0u)->arcsOut; ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P3"); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P0"); ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T0"); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P0"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P3"); ASSERT_EQ(arcsOut[0]->duration, 1.0f); } - // Delete Place 0: Place 3 becomes Place 0 + // *** Delete Place 0: Place 3 becomes Place 0 net.removeNode(*net.findNode("P0")); // P0 { auto const& arcsIn = net.findPlace(0u)->arcsIn; auto const& arcsOut = net.findPlace(0u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 0u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P0"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 0u); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P0"); } // T0 { auto const& arcsIn = net.findTransition(0u)->arcsIn; auto const& arcsOut = net.findTransition(0u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 1u); - ASSERT_EQ(arcsOut.size(), 0u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P0"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T0"); + ASSERT_EQ(arcsIn.size(), 0u); + ASSERT_EQ(arcsOut.size(), 1u); + ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P0"); } - // Delete Transition 0: Transition 1 becomes Place 0 + // *** Delete Transition 0: Transition 1 becomes Transition 0 net.removeNode(*net.findNode("T0")); // P0 @@ -1616,20 +1631,20 @@ TEST(TestPetriNet, TestRemoveNode) { auto const& arcsIn = net.findPlace(1u)->arcsIn; auto const& arcsOut = net.findPlace(1u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 0u); - ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P1"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); + ASSERT_EQ(arcsIn.size(), 1u); + ASSERT_EQ(arcsOut.size(), 0u); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P1"); + ASSERT_EQ(arcsIn[0]->duration, 5.0f); } // P2 { auto const& arcsIn = net.findPlace(2u)->arcsIn; auto const& arcsOut = net.findPlace(2u)->arcsOut; - ASSERT_EQ(arcsIn.size(), 1u); - ASSERT_EQ(arcsOut.size(), 0u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "P2"); - ASSERT_EQ(arcsIn[0]->duration, 3.0f); + ASSERT_EQ(arcsIn.size(), 0u); + ASSERT_EQ(arcsOut.size(), 1u); + ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "P2"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "T0"); } // T0 { @@ -1637,10 +1652,11 @@ TEST(TestPetriNet, TestRemoveNode) auto const& arcsOut = net.findTransition(0u)->arcsOut; ASSERT_EQ(arcsIn.size(), 1u); ASSERT_EQ(arcsOut.size(), 1u); - ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P1"); - ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T0"); ASSERT_STREQ(arcsOut[0]->from.key.c_str(), "T0"); - ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P2"); + ASSERT_STREQ(arcsOut[0]->to.key.c_str(), "P1"); + ASSERT_EQ(arcsOut[0]->duration, 5.0f); + ASSERT_STREQ(arcsIn[0]->from.key.c_str(), "P2"); + ASSERT_STREQ(arcsIn[0]->to.key.c_str(), "T0"); } net.removeNode(*net.findNode("T0"));