Skip to content

Commit

Permalink
Merge 99c2167 into e991fca
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed Apr 17, 2022
2 parents e991fca + 99c2167 commit d970fb9
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 40 deletions.
5 changes: 5 additions & 0 deletions src/Model/Model/Revision/Transition.php
Expand Up @@ -96,4 +96,9 @@ public function toArray(): array
'commands' => array_map(fn (CommandInterface $command) => $command->toArray(), $this->commands),
];
}

public function isStart(): bool
{
return empty($this->fromPlaces);
}
}
2 changes: 2 additions & 0 deletions src/Model/Model/Revision/TransitionInterface.php
Expand Up @@ -31,4 +31,6 @@ public function setToPlaces(array $toPlaces): void;
public function addToPlace(int $toPlace): void;

public function toArray(): array;

public function isStart(): bool;
}
4 changes: 2 additions & 2 deletions src/Service/Model/ModelHelper.php
Expand Up @@ -14,7 +14,7 @@ class ModelHelper implements ModelHelperInterface
public function getStartTransitionId(RevisionInterface $revision): int
{
foreach ($revision->getTransitions() as $index => $transition) {
if ($transition instanceof TransitionInterface && 0 === count($transition->getFromPlaces())) {
if ($transition instanceof TransitionInterface && $transition->isStart()) {
return $index;
}
}
Expand All @@ -28,7 +28,7 @@ public function getStartTransitionId(RevisionInterface $revision): int
public function getStartPlaceIds(RevisionInterface $revision): array
{
foreach ($revision->getTransitions() as $transition) {
if ($transition instanceof TransitionInterface && 0 === count($transition->getFromPlaces())) {
if ($transition instanceof TransitionInterface && $transition->isStart()) {
return array_fill_keys($transition->getToPlaces(), 1);
}
}
Expand Down
9 changes: 2 additions & 7 deletions src/Service/Petrinet/PetrinetHelper.php
Expand Up @@ -30,7 +30,7 @@ public function build(RevisionInterface $revision): PetrinetInterface
$places = $this->getPlaces($revision, $builder);
$transitions = $this->getTransitions($revision, $builder);
foreach ($revision->getTransitions() as $index => $transition) {
if ($transition instanceof TransitionInterface && $this->isValidTransition($transition)) {
if ($transition instanceof TransitionInterface && !$transition->isStart()) {
$this->connectPlacesToTransition(
array_intersect_key($places, array_flip($transition->getFromPlaces())),
$transitions[$index],
Expand Down Expand Up @@ -60,7 +60,7 @@ protected function getTransitions(RevisionInterface $revision, SingleColorPetrin
{
$transitions = [];
foreach ($revision->getTransitions() as $index => $transition) {
if ($transition instanceof TransitionInterface && $this->isValidTransition($transition)) {
if ($transition instanceof TransitionInterface && !$transition->isStart()) {
$guardCallback = $transition->getGuard()
? fn (ColorInterface $color): bool => (bool) $this->expressionLanguage->evaluate(
$transition->getGuard(),
Expand Down Expand Up @@ -97,9 +97,4 @@ protected function connectTransitionToPlaces(
$builder->connect($transition, $places[$toPlace], 1);
}
}

protected function isValidTransition(TransitionInterface $transition): bool
{
return !empty($transition->getFromPlaces());
}
}
8 changes: 8 additions & 0 deletions tests/Model/Model/Revision/TransitionTest.php
Expand Up @@ -49,6 +49,13 @@ protected function setUpCommands(): void
$this->command2->setValue(null);
}

public function testStartTransition(): void
{
$this->assertFalse($this->transition->isStart());
$this->transition->setFromPlaces([]);
$this->assertTrue($this->transition->isStart());
}

public function testSerialize(): void
{
$className = get_class($this->transition);
Expand All @@ -70,6 +77,7 @@ public function testUnerialize(): void
$this->assertSame(StoreCommandRunner::STORE, $transition->getCommands()[0]->getCommand());
$this->assertSame('55', $transition->getCommands()[0]->getTarget());
$this->assertSame('number', $transition->getCommands()[0]->getValue());
$this->assertFalse($transition->isStart());
}

protected function createTransition(): TransitionInterface
Expand Down
108 changes: 77 additions & 31 deletions tests/Service/Petrinet/PetrinetHelperTest.php
Expand Up @@ -2,11 +2,12 @@

namespace Tienvx\Bundle\MbtBundle\Tests\Service\Petrinet;

use Petrinet\Model\PlaceInterface;
use Petrinet\Model\ArcInterface;
use PHPUnit\Framework\TestCase;
use SingleColorPetrinet\Model\Color;
use SingleColorPetrinet\Model\ColorfulFactory;
use SingleColorPetrinet\Model\GuardedTransitionInterface;
use SingleColorPetrinet\Model\GuardedTransition as PetrinetTransition;
use SingleColorPetrinet\Model\Place as PetrinetPlace;
use Tienvx\Bundle\MbtBundle\Entity\Model\Revision;
use Tienvx\Bundle\MbtBundle\Service\ExpressionLanguage;
use Tienvx\Bundle\MbtBundle\Service\Petrinet\PetrinetHelper;
Expand All @@ -28,45 +29,90 @@ public function testBuild(): void
$factory = new ColorfulFactory();
$expressionLanguage = new ExpressionLanguage();
$helper = new PetrinetHelper($factory, $expressionLanguage);
$places = [

// Model revision
$revision = new Revision();
$revision->setPlaces([
$place0 = new Place(),
$place1 = new Place(),
$place2 = new Place(),
$place3 = new Place(),
];
$revision = new Revision();
$revision->setPlaces($places);
$transitions = [
]);
$revision->setTransitions([
$transition0 = new Transition(),
$transition1 = new Transition(),
$transition2 = new Transition(),
];
$transition3 = new Transition(),
]);
$transition0->setFromPlaces([]);
$transition0->setToPlaces([0]);
$transition1->setGuard('count > 0');
$transition1->setFromPlaces([0, 1]);
$transition1->setToPlaces([2]);
$transition1->setFromPlaces([0]);
$transition1->setToPlaces([1, 2]);
$transition2->setFromPlaces([2]);
$transition2->setToPlaces([1]);
$revision->setTransitions($transitions);
$transition3->setFromPlaces([1]);
$transition3->setToPlaces([0, 2]);

// Petrinet
$petrinet = $helper->build($revision);
$this->assertCount(3, $petrinet->getPlaces());
foreach ($petrinet->getPlaces() as $place) {
$this->assertInstanceOf(PlaceInterface::class, $place);
$places = [
0 => [
'input' => [3],
'output' => [1],
],
1 => [
'input' => [1, 2],
'output' => [3],
],
2 => [
'input' => [1, 3],
'output' => [2],
],
];
foreach ($petrinet->getPlaces() as $index => $place) {
$this->assertInstanceOf(PetrinetPlace::class, $place);
$this->assertSame(
$places[$index]['input'],
array_map(fn (ArcInterface $arc) => $arc->getTransition()->getId(), $place->getInputArcs()->toArray()),
);
$this->assertSame(
$places[$index]['output'],
array_map(fn (ArcInterface $arc) => $arc->getTransition()->getId(), $place->getOutputArcs()->toArray()),
);
}
$this->assertCount(0, $petrinet->getPlaces()[0]->getInputArcs());
$this->assertCount(1, $petrinet->getPlaces()[0]->getOutputArcs());
$this->assertCount(1, $petrinet->getPlaces()[1]->getInputArcs());
$this->assertCount(1, $petrinet->getPlaces()[1]->getOutputArcs());
$this->assertCount(1, $petrinet->getPlaces()[2]->getInputArcs());
$this->assertCount(1, $petrinet->getPlaces()[2]->getOutputArcs());
$this->assertCount(2, $petrinet->getTransitions());
foreach ($petrinet->getTransitions() as $place) {
$this->assertInstanceOf(GuardedTransitionInterface::class, $place);
$this->assertCount(3, $petrinet->getTransitions());
$transitions = [
0 => [
'input' => [0],
'output' => [1, 2],
],
1 => [
'input' => [2],
'output' => [1],
],
2 => [
'input' => [1],
'output' => [0, 2],
],
];
foreach ($petrinet->getTransitions() as $index => $transition) {
$this->assertInstanceOf(PetrinetTransition::class, $transition);
$this->assertSame(
$transitions[$index]['input'],
array_map(fn (ArcInterface $arc) => $arc->getPlace()->getId(), $transition->getInputArcs()->toArray()),
);
$this->assertSame(
$transitions[$index]['output'],
array_map(fn (ArcInterface $arc) => $arc->getPlace()->getId(), $transition->getOutputArcs()->toArray()),
);
if (0 === $index) {
$this->assertIsCallable($guardCallback = $transition->getGuard());
$this->assertTrue($guardCallback(new Color(['count' => 1])));
$this->assertFalse($guardCallback(new Color(['count' => 0])));
} else {
$this->assertNull($transition->getGuard());
}
}
$this->assertIsCallable($guardCallback = $petrinet->getTransitions()[0]->getGuard());
$this->assertTrue($guardCallback(new Color(['count' => 1])));
$this->assertFalse($guardCallback(new Color(['count' => 0])));
$this->assertNull($petrinet->getTransitions()[1]->getGuard());
$this->assertCount(2, $petrinet->getTransitions()[0]->getInputArcs());
$this->assertCount(1, $petrinet->getTransitions()[0]->getOutputArcs());
$this->assertCount(1, $petrinet->getTransitions()[1]->getInputArcs());
$this->assertCount(1, $petrinet->getTransitions()[1]->getOutputArcs());
}
}

0 comments on commit d970fb9

Please sign in to comment.