Skip to content

Commit

Permalink
Import from / Export to timed event graph format
Browse files Browse the repository at this point in the history
  • Loading branch information
Lecrapouille committed Apr 25, 2024
1 parent 30583a2 commit 99ea173
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ LINKER_FLAGS += -ldl -lpthread
###################################################
# Make the list of compiled files for the library
#
IMPORT_FORMATS += ImportJSON.o ImportPNML.o
IMPORT_FORMATS += ImportJSON.o ImportPNML.o ImportTimedEventGraph.o ExportTimedEventGraph.o
EXPORT_FORMATS += ExportJSON.o ExportPNML.o ExportSymfony.o ExportPnEditor.o
EXPORT_FORMATS += ExportPetriLaTeX.o ExportJulia.o ExportGraphviz.o ExportDrawIO.o
EXPORT_FORMATS += ExportGrafcetCpp.o
Expand Down
7 changes: 7 additions & 0 deletions data/examples/SemiHoward.teg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TimedEventGraph 3 5

1 0: 0 1
0 1: 1 0
0 2: 0 0
1 2: 1 0
2 2: 2 1
14 changes: 14 additions & 0 deletions data/examples/SemiNetherlands.teg
Original file line number Diff line number Diff line change
@@ -0,0 +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
21 changes: 18 additions & 3 deletions doc/export.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Exporting the net
# Exporting and importing the net to other file format

## Export to LaTeX

Expand Down Expand Up @@ -33,7 +33,7 @@ Can export to input files for [Draw.io](https://app.diagrams.net).

Can export to input files for [Symfony workflow](https://symfony.com/doc/current/components/workflow.html).

## Export to pn-editor
## Export/Import to pn-editor

Can export to input files for [pn-editor](https://gitlab.com/porky11/pn-editor).

Expand All @@ -45,4 +45,19 @@ You have to git clone and install it manually.

If your net is a GRAFCET (GRAphe Fonctionnel de Commande Etapes-Transitions in French,
aka Sequential Function Chart (SFC) in English) you can generate the C++ code.
More details [here](grafcet.md).
More details [here](grafcet.md).

## Export to Timed Graph Event

Store timed event graph in a compact format. The file format is based this initial [project](http://www.cmap.polytechnique.fr/~gaubert/HOWARD2.html). We are using the
`.teg` extension.

The first line indicates if we are using "TimedEventGraph", the number of transitions and the number of arcs (which is equals to places / 2). Other lines define each arcs transition to transition, the number of tokens in the place relying the two transitions and the duration. All values are unsigned integer execept for duration which are float.

Timed event graph file format:

```
TimedEventGraph <number of arcs> <number of arcs>
<initial transition id> <destination transition id>: <duration> <number of tokens>.
```
7 changes: 4 additions & 3 deletions src/Editor/DearImGui/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ void Editor::PetriView::Canvas::pop()
}

//--------------------------------------------------------------------------
void Editor::PetriView::Canvas::reshape()
ImVec2 Editor::PetriView::Canvas::reshape()
{
// ImDrawList API uses screen coordinates!
corners[0] = ImGui::GetCursorScreenPos();
Expand All @@ -1179,12 +1179,13 @@ void Editor::PetriView::Canvas::reshape()

// Lock scrolled origin
origin = corners[0] + scrolling;
return size;
}

//--------------------------------------------------------------------------
void Editor::PetriView::reshape()
ImVec2 Editor::PetriView::reshape()
{
m_canvas.reshape();
return m_canvas.reshape();
}

//--------------------------------------------------------------------------
Expand Down
8 changes: 5 additions & 3 deletions src/Editor/DearImGui/Editor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Editor: public PetriNetEditor, public Application
void messagebox();
void inspector();
void view();
inline ImVec2 viewSize() const { return m_view.size(); }

private: // Show results from Petri algorithms

Expand Down Expand Up @@ -138,16 +139,17 @@ class Editor: public PetriNetEditor, public Application
// ********************************************************************
struct GridLayout
{
float step = 64.0f;
float step = 50.0f;
bool show = true;
bool menu = true;
} grid;

PetriView(Editor& editor);
void reshape();
ImVec2 reshape();
void onHandleInput();
void drawPetriNet(Net& net, Simulation& simulation);
inline ImVec2 const& origin() const { return m_canvas.origin; };
inline ImVec2 const& size() const { return m_canvas.size; };

private:

Expand Down Expand Up @@ -176,7 +178,7 @@ class Editor: public PetriNetEditor, public Application
ImDrawList* draw_list;

ImVec2 getMousePosition();
void reshape();
ImVec2 reshape();
void push();
void pop();
} m_canvas;
Expand Down
63 changes: 63 additions & 0 deletions src/Net/Exports/ExportTimedEventGraph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//=============================================================================
// TimedPetriNetEditor: A timed Petri net editor.
// Copyright 2021 -- 2023 Quentin Quadrat <lecrapouille@gmail.com>
//
// This file is part of TimedPetriNetEditor.
//
// TimedPetriNetEditor is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
//=============================================================================

#include "Net/Exports/Exports.hpp"
#include "TimedPetriNetEditor/PetriNet.hpp"
#include "TimedPetriNetEditor/Algorithms.hpp"
#include <fstream>
#include <cstring>

namespace tpne {

//------------------------------------------------------------------------------
std::string exportToTimedEventGraph(Net const& net, std::string const& filename)
{
std::stringstream error;

if (!isEventGraph(net))
{
error << "Failed to export the Petri net to '" << filename
<< "'. Reason was 'the net is not an event graph'"
<< std::endl;
return error.str();
}

std::ofstream file(filename);
if (!file)
{
error << "Failed to export the Petri net to '" << filename
<< "'. Reason was " << strerror(errno) << std::endl;
return error.str();
}

file << "TimedEventGraph " << net.transitions().size() << " "
<< net.places().size() << std::endl << std::endl;

for (auto const& p: net.places())
{
file << p.arcsIn[0]->from.id << " " << p.arcsOut[0]->to.id
<< ": " << p.arcsIn[0]->duration << " " << p.tokens
<< std::endl;
}

return {};
}

} // namespace tpne
1 change: 1 addition & 0 deletions src/Net/Exports/Exports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ std::vector<Exporter> const& exporters()
{ "PN-Editor", ".pns,.pnl,.pnk,.pnkp", exportToPNEditor },
{ "Petri-LaTeX", ".tex", exportToPetriLaTeX },
{ "Petri Net Markup Language", ".pnml", exportToPNML },
{ "Timed Event Graph", ".teg", exportToTimedEventGraph },
//{ "Codesys", ".codesys.xml", exportToCodesys },
//{ "Grafcet-LaTeX", ".tex", exportToGrafcetLaTeX },
};
Expand Down
2 changes: 2 additions & 0 deletions src/Net/Exports/Exports.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Net;

//! \brief JSON is the main format used for saving Petri by this editor.
std::string exportToJSON(Net const& net, std::string const& filename);
//! \brief Import http://www.cmap.polytechnique.fr/~gaubert/HOWARD2.html
std::string exportToTimedEventGraph(Net const& net, std::string const& filename);
//! \brief
std::string exportToSymfony(Net const& net, std::string const& filename);
//! \brief Import https://gitlab.com/porky11/pn-editor
Expand Down
112 changes: 112 additions & 0 deletions src/Net/Imports/ImportTimedEventGraph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//=============================================================================
// TimedPetriNetEditor: A timed Petri net editor.
// Copyright 2021 -- 2023 Quentin Quadrat <lecrapouille@gmail.com>
//
// This file is part of TimedPetriNetEditor.
//
// TimedPetriNetEditor is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
//=============================================================================

#include "Imports.hpp"
#include "TimedPetriNetEditor/PetriNet.hpp"
#include "Utils/Utils.hpp"

#include <fstream>
#include <cstring>

namespace tpne {

//------------------------------------------------------------------------------
std::string importFromTimedEventGraph(Net& net, std::string const& filename)
{
std::stringstream error;
size_t initial_transition, final_transition, tokens;
float duration;
// windows screen.
// FIXME: get the exact dimension Editor::viewSize()
// FIXME: initial frame iteration: the screen size is not at its final size
const size_t w = 700u; const size_t h = 700u;
const size_t margin = 50u; const size_t nodes_by_line = 4u;

net.reset(TypeOfNet::TimedPetriNet);//TimedEventGraph);

// Check if file exists
std::ifstream file(filename);
if (!file)
{
error << "Failed opening '" << filename << "'. Reason was '"
<< strerror(errno) << "'" << std::endl;
return error.str();
}

// Extract number of transitions and number of lines
size_t transitions, lines, rows;
char separator;
std::string type;

if (!(file >> type >> transitions >> lines))
{
error << "Malformed header. Needed 'TimedEventGraph number_transitions number_lines'"
<< std::endl;
return error.str();
}
if (type != "TimedEventGraph")
{
error << "Malformed token. Expected to extract token 'TimedEventGraph'"
<< std::endl;
return error.str();
}

// Since the file does not give position, we place them as square
size_t dx = (w - 2u * margin) / (nodes_by_line - 1u);
size_t dy = (h - 2u * margin) / (nodes_by_line - 1u);
size_t x = margin, y = margin;
for (size_t id = 0u; id < transitions; ++id)
{
net.addTransition(id, Transition::to_str(id), x, y, 0);
x += dx;
if (x > w - margin) { x = margin; y += dy; }
}

// Create arcs between created transitions. Places are automatically created
// when the arc is created.
for (size_t i = 0u; i < lines; ++i)
{
if (!(file >> final_transition >> initial_transition >> separator >> duration >> tokens))
{
error << "Malformed line. Expected 4 values: 'initial_transition"
<< " final_transition: duration tokens'" << std::endl;
return error.str();
}
if ((initial_transition >= transitions) || (final_transition >= transitions))
{
error << "Malformed line. Invalid transition ID" << std::endl;
return error.str();
}
if (separator != ':')
{
error << "Malformed line. Missing ':' separator" << std::endl;
return error.str();
}

Transition* t0 = net.findTransition(initial_transition);
Transition* t1 = net.findTransition(final_transition);
assert((t0 != nullptr) && (t1 != nullptr));
net.addArc(*t0, *t1, tokens, duration);
}

return {};
}

} // namespace tpne
3 changes: 3 additions & 0 deletions src/Net/Imports/Imports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@

#include "Net/Imports/Imports.hpp"
#include <sstream>
#include <iostream>
namespace tpne {

std::vector<Importer> const& importers()
{
static const std::vector<Importer> s_importers = {
{ "JSON", ".json", importFromJSON },
{ "Petri Net Markup Language", ".pnml", importFromPNML },
// FIXME add a filter to eliminate it in the case the net is not event graph
{ "Timed Event Graph", ".teg", importFromTimedEventGraph }
};

return s_importers;
Expand Down
2 changes: 2 additions & 0 deletions src/Net/Imports/Imports.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Net;

//! \brief JSON is the main format used for saving Petri by this editor.
std::string importFromJSON(Net& net, std::string const& filename);
//! \brief Import http://www.cmap.polytechnique.fr/~gaubert/HOWARD2.html
std::string importFromTimedEventGraph(Net& net, std::string const& filename);
//! \brief Import https://gitlab.com/porky11/pn-editor
std::string importFromPNML(Net& net, std::string const& filename);

Expand Down
Loading

0 comments on commit 99ea173

Please sign in to comment.