Skip to content

Commit

Permalink
Fire start transition
Browse files Browse the repository at this point in the history
  • Loading branch information
tienvx committed Apr 28, 2022
1 parent 1eda551 commit 952ed75
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 72 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -29,7 +29,7 @@
"symfony/http-kernel": "^5.4",
"symfony/messenger": "^5.4",
"symfony/validator": "^5.4",
"tienvx/single-color-petrinet": "^1.3"
"tienvx/single-color-petrinet": "^1.5"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
Expand Down
26 changes: 11 additions & 15 deletions src/Generator/RandomGenerator.php
Expand Up @@ -3,14 +3,15 @@
namespace Tienvx\Bundle\MbtBundle\Generator;

use Petrinet\Model\MarkingInterface;
use Petrinet\Model\PetrinetInterface;
use Petrinet\Model\TransitionInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Service\GuardedTransitionServiceInterface;
use Tienvx\Bundle\MbtBundle\Model\Generator\State;
use Tienvx\Bundle\MbtBundle\Model\Generator\StateInterface;
use Tienvx\Bundle\MbtBundle\Model\TaskInterface;
use Tienvx\Bundle\MbtBundle\Service\Model\ModelHelperInterface;
use Tienvx\Bundle\MbtBundle\Service\Petrinet\MarkingHelperInterface;
use Tienvx\Bundle\MbtBundle\Service\Petrinet\PetrinetHelper;
use Tienvx\Bundle\MbtBundle\Service\Petrinet\PetrinetHelperInterface;
use Tienvx\Bundle\MbtBundle\ValueObject\Bug\Step;

Expand Down Expand Up @@ -44,36 +45,31 @@ public static function getName(): string
public function generate(TaskInterface $task): iterable
{
$petrinet = $this->petrinetHelper->build($task->getModelRevision());
$transition = null;
$transitionId = $this->modelHelper->getStartTransitionId($task->getModelRevision());
$places = $this->modelHelper->getStartPlaceIds($task->getModelRevision());
$marking = $this->markingHelper->getMarking($petrinet, $places);
$transition = $petrinet->getTransitionById(
$this->modelHelper->getStartTransitionId($task->getModelRevision())
);
$marking = $this->markingHelper->getMarking($petrinet, [PetrinetHelper::FAKE_START_PLACE_ID => 1]);
$state = new State(
[],
[$transitionId],
[],
count($task->getModelRevision()->getPlaces()),
count($task->getModelRevision()->getTransitions())
);

while ($this->canContinue($state)) {
if ($transition) {
$this->transitionService->fire($transition, $marking);
$places = $this->markingHelper->getPlaces($marking);
}
$this->update($state, $marking, $transitionId);
$this->transitionService->fire($transition, $marking);
$this->update($state, $marking, $transition->getId());

yield new Step(
$places,
$this->markingHelper->getPlaces($marking),
$marking->getColor(),
$transitionId
$transition->getId()
);

$transition = $this->nextTransition($petrinet, $marking);
if (!$transition) {
break;
}

$transitionId = $transition->getId();
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Service/AStar/PetrinetDomainLogic.php
Expand Up @@ -2,8 +2,8 @@

namespace Tienvx\Bundle\MbtBundle\Service\AStar;

use Petrinet\Model\PetrinetInterface;
use Petrinet\Model\TransitionInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Service\GuardedTransitionServiceInterface;
use Tienvx\Bundle\MbtBundle\Exception\RuntimeException;
use Tienvx\Bundle\MbtBundle\Model\Bug\Step;
Expand Down
2 changes: 1 addition & 1 deletion src/Service/AStar/PetrinetDomainLogicInterface.php
Expand Up @@ -3,7 +3,7 @@
namespace Tienvx\Bundle\MbtBundle\Service\AStar;

use JMGQ\AStar\DomainLogicInterface;
use Petrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Model\PetrinetInterface;

interface PetrinetDomainLogicInterface extends DomainLogicInterface
{
Expand Down
4 changes: 2 additions & 2 deletions src/Service/Petrinet/MarkingHelper.php
Expand Up @@ -4,11 +4,11 @@

use Petrinet\Builder\MarkingBuilder;
use Petrinet\Model\MarkingInterface;
use Petrinet\Model\PetrinetInterface;
use Petrinet\Model\PlaceMarkingInterface;
use SingleColorPetrinet\Model\ColorfulFactoryInterface;
use SingleColorPetrinet\Model\ColorfulMarkingInterface;
use SingleColorPetrinet\Model\ColorInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use Tienvx\Bundle\MbtBundle\Exception\UnexpectedValueException;

class MarkingHelper implements MarkingHelperInterface
Expand Down Expand Up @@ -45,7 +45,7 @@ public function getMarking(
): ColorfulMarkingInterface {
$markingBuilder = new MarkingBuilder($this->colorfulFactory);
foreach ($places as $place => $tokens) {
$markingBuilder->mark($petrinet->getPlaces()[$place], $tokens);
$markingBuilder->mark($petrinet->getPlaceById($place), $tokens);
}

$marking = $markingBuilder->getMarking();
Expand Down
2 changes: 1 addition & 1 deletion src/Service/Petrinet/MarkingHelperInterface.php
Expand Up @@ -3,9 +3,9 @@
namespace Tienvx\Bundle\MbtBundle\Service\Petrinet;

use Petrinet\Model\MarkingInterface;
use Petrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Model\ColorfulMarkingInterface;
use SingleColorPetrinet\Model\ColorInterface;
use SingleColorPetrinet\Model\PetrinetInterface;

interface MarkingHelperInterface
{
Expand Down
55 changes: 31 additions & 24 deletions src/Service/Petrinet/PetrinetHelper.php
Expand Up @@ -2,19 +2,21 @@

namespace Tienvx\Bundle\MbtBundle\Service\Petrinet;

use Petrinet\Model\PetrinetInterface;
use Petrinet\Model\PlaceInterface as PetrinetPlaceInterface;
use Petrinet\Model\TransitionInterface as PetrinetTransitionInterface;
use SingleColorPetrinet\Builder\SingleColorPetrinetBuilder;
use SingleColorPetrinet\Model\ColorfulFactoryInterface;
use SingleColorPetrinet\Model\ColorInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use Tienvx\Bundle\MbtBundle\Model\Model\Revision\PlaceInterface;
use Tienvx\Bundle\MbtBundle\Model\Model\Revision\TransitionInterface;
use Tienvx\Bundle\MbtBundle\Model\Model\RevisionInterface;
use Tienvx\Bundle\MbtBundle\Service\ExpressionLanguage;

class PetrinetHelper implements PetrinetHelperInterface
{
public const FAKE_START_PLACE_ID = -1;

protected ColorfulFactoryInterface $colorfulFactory;
protected ExpressionLanguage $expressionLanguage;

Expand All @@ -30,12 +32,16 @@ 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 && !$transition->isStart()) {
$this->connectPlacesToTransition(
array_intersect_key($places, array_flip($transition->getFromPlaces())),
$transitions[$index],
$builder
);
if ($transition instanceof TransitionInterface) {
if ($transition->isStart()) {
$builder->connect($places[self::FAKE_START_PLACE_ID], $transitions[$index], 1);
} else {
$this->connectPlacesToTransition(
array_intersect_key($places, array_flip($transition->getFromPlaces())),
$transitions[$index],
$builder
);
}
$this->connectTransitionToPlaces($transitions[$index], $transition->getToPlaces(), $places, $builder);
}
}
Expand All @@ -46,10 +52,10 @@ public function build(RevisionInterface $revision): PetrinetInterface
protected function getPlaces(RevisionInterface $revision, SingleColorPetrinetBuilder $builder): array
{
$places = [];
$places[self::FAKE_START_PLACE_ID] = $builder->place(self::FAKE_START_PLACE_ID);
foreach ($revision->getPlaces() as $index => $place) {
if ($place instanceof PlaceInterface) {
$places[$index] = $builder->place();
$places[$index]->setId($index);
$places[$index] = $builder->place($index);
}
}

Expand All @@ -60,21 +66,22 @@ protected function getTransitions(RevisionInterface $revision, SingleColorPetrin
{
$transitions = [];
foreach ($revision->getTransitions() as $index => $transition) {
if ($transition instanceof TransitionInterface && !$transition->isStart()) {
$guardCallback = $transition->getGuard()
? fn (ColorInterface $color): bool => (bool) $this->expressionLanguage->evaluate(
$transition->getGuard(),
$color->getValues()
)
: null;
$expressionCallback = $transition->getExpression()
? fn (ColorInterface $color): array => (array) $this->expressionLanguage->evaluate(
$transition->getExpression(),
$color->getValues()
)
: null;
$transitions[$index] = $builder->transition($guardCallback, $expressionCallback);
$transitions[$index]->setId($index);
if ($transition instanceof TransitionInterface) {
$transitions[$index] = $builder->transition(
$transition->getGuard()
? fn (ColorInterface $color): bool => (bool) $this->expressionLanguage->evaluate(
$transition->getGuard(),
$color->getValues()
)
: null,
$transition->getExpression()
? fn (ColorInterface $color): array => (array) $this->expressionLanguage->evaluate(
$transition->getExpression(),
$color->getValues()
)
: null,
$index
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Service/Petrinet/PetrinetHelperInterface.php
Expand Up @@ -2,7 +2,7 @@

namespace Tienvx\Bundle\MbtBundle\Service\Petrinet;

use Petrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use Tienvx\Bundle\MbtBundle\Model\Model\RevisionInterface;

interface PetrinetHelperInterface
Expand Down
4 changes: 2 additions & 2 deletions src/Service/Step/Runner/ReduceStepsRunner.php
Expand Up @@ -3,7 +3,7 @@
namespace Tienvx\Bundle\MbtBundle\Service\Step\Runner;

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Petrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Service\GuardedTransitionServiceInterface;
use Tienvx\Bundle\MbtBundle\Model\Bug\StepInterface;
use Tienvx\Bundle\MbtBundle\Model\DebugInterface;
Expand Down Expand Up @@ -48,7 +48,7 @@ protected function stop(?RemoteWebDriver $driver): void
protected function runStep(StepInterface $step, RevisionInterface $revision, RemoteWebDriver $driver): bool
{
$marking = $this->markingHelper->getMarking($this->petrinet, $step->getPlaces(), $step->getColor());
$transition = $this->petrinet->getTransitions()[$step->getTransition()];
$transition = $this->petrinet->getTransitionById($step->getTransition());
if ($this->transitionService->isEnabled($transition, $marking)) {
return parent::runStep($step, $revision, $driver);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Service/AStar/PetrinetDomainLogicTest.php
Expand Up @@ -3,12 +3,12 @@
namespace Tienvx\Bundle\MbtBundle\Tests\Service\AStar;

use Petrinet\Model\MarkingInterface;
use Petrinet\Model\PetrinetInterface;
use PHPUnit\Framework\TestCase;
use SingleColorPetrinet\Model\Color;
use SingleColorPetrinet\Model\ColorfulMarking;
use SingleColorPetrinet\Model\ColorInterface;
use SingleColorPetrinet\Model\GuardedTransition;
use SingleColorPetrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Service\GuardedTransitionServiceInterface;
use Tienvx\Bundle\MbtBundle\Exception\RuntimeException;
use Tienvx\Bundle\MbtBundle\Model\Bug\Step;
Expand Down
10 changes: 5 additions & 5 deletions tests/Service/Petrinet/MarkingHelperTest.php
Expand Up @@ -54,13 +54,13 @@ public function testGetMarking(): void
$builder = new SingleColorPetrinetBuilder($this->factory);

$petrinet = $builder
->connect($place1 = $builder->place(), $transition1 = $builder->transition())
->connect($transition1, $place2 = $builder->place())
->connect($place3 = $builder->place(), $transition2 = $builder->transition())
->connect($transition2, $place4 = $builder->place())
->connect($place1 = $builder->place(1), $transition1 = $builder->transition())
->connect($transition1, $place2 = $builder->place(2))
->connect($place3 = $builder->place(3), $transition2 = $builder->transition())
->connect($transition2, $place4 = $builder->place(4))
->getPetrinet();

$marking = $this->helper->getMarking($petrinet, [0 => 1, 2 => 3], new Color(['key' => 'value']));
$marking = $this->helper->getMarking($petrinet, [1 => 1, 3 => 3], new Color(['key' => 'value']));
$this->assertSame(['key' => 'value'], $marking->getColor()->getValues());
$this->assertCount(1, $marking->getPlaceMarking($place1)->getTokens());
$this->assertNull($marking->getPlaceMarking($place2));
Expand Down
36 changes: 27 additions & 9 deletions tests/Service/Petrinet/PetrinetHelperTest.php
Expand Up @@ -56,23 +56,32 @@ public function testBuild(): void

// Petrinet
$petrinet = $helper->build($revision);
$this->assertCount(3, $petrinet->getPlaces());
$this->assertCount(4, $petrinet->getPlaces());
$places = [
0 => [
'input' => [3],
'output' => [1],
'id' => -1,
'input' => [],
'output' => [0],
],
1 => [
'id' => 0,
'input' => [0, 3],
'output' => [1],
],
2 => [
'id' => 1,
'input' => [1, 2],
'output' => [3],
],
2 => [
3 => [
'id' => 2,
'input' => [1, 3],
'output' => [2],
],
];
foreach ($petrinet->getPlaces() as $index => $place) {
$this->assertInstanceOf(PetrinetPlace::class, $place);
$this->assertSame($places[$index]['id'], $place->getId());
$this->assertSame(
$places[$index]['input'],
array_map(fn (ArcInterface $arc) => $arc->getTransition()->getId(), $place->getInputArcs()->toArray()),
Expand All @@ -82,23 +91,32 @@ public function testBuild(): void
array_map(fn (ArcInterface $arc) => $arc->getTransition()->getId(), $place->getOutputArcs()->toArray()),
);
}
$this->assertCount(3, $petrinet->getTransitions());
$this->assertCount(4, $petrinet->getTransitions());
$transitions = [
0 => [
'id' => 0,
'input' => [-1],
'output' => [0],
],
1 => [
'id' => 1,
'input' => [0],
'output' => [1, 2],
],
1 => [
2 => [
'id' => 2,
'input' => [2],
'output' => [1],
],
2 => [
3 => [
'id' => 3,
'input' => [1],
'output' => [0, 2],
],
];
foreach ($petrinet->getTransitions() as $index => $transition) {
$this->assertInstanceOf(PetrinetTransition::class, $transition);
$this->assertSame($transitions[$index]['id'], $transition->getId());
$this->assertSame(
$transitions[$index]['input'],
array_map(fn (ArcInterface $arc) => $arc->getPlace()->getId(), $transition->getInputArcs()->toArray()),
Expand All @@ -107,14 +125,14 @@ public function testBuild(): void
$transitions[$index]['output'],
array_map(fn (ArcInterface $arc) => $arc->getPlace()->getId(), $transition->getOutputArcs()->toArray()),
);
if (0 === $index) {
if (1 === $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());
}
if (2 === $index) {
if (3 === $index) {
$this->assertIsCallable($expressionCallback = $transition->getExpression());
$this->assertSame(['count' => 2, 'status' => 'open'], $expressionCallback(new Color(['count' => 1])));
$this->assertSame(['count' => 1, 'status' => 'open'], $expressionCallback(new Color(['count' => 0])));
Expand Down
Expand Up @@ -3,7 +3,6 @@
namespace Tienvx\Bundle\MbtBundle\Tests\Service\Step\Builder;

use Generator;
use Petrinet\Model\PetrinetInterface;
use Petrinet\Model\PlaceInterface;
use Petrinet\Model\TransitionInterface;
use PHPUnit\Framework\MockObject\MockObject;
Expand All @@ -13,6 +12,7 @@
use SingleColorPetrinet\Model\ColorfulFactory;
use SingleColorPetrinet\Model\ColorfulFactoryInterface;
use SingleColorPetrinet\Model\ColorInterface;
use SingleColorPetrinet\Model\PetrinetInterface;
use SingleColorPetrinet\Service\GuardedTransitionService;
use SingleColorPetrinet\Service\GuardedTransitionServiceInterface;
use Tienvx\Bundle\MbtBundle\Entity\Bug;
Expand Down

0 comments on commit 952ed75

Please sign in to comment.