diff --git a/src/gspn/gspn.cpp b/src/gspn/gspn.cpp index 589f4b7..99e0a0b 100644 --- a/src/gspn/gspn.cpp +++ b/src/gspn/gspn.cpp @@ -54,6 +54,7 @@ void define_gspn(py::module& m) { .def("add_timed_transition", py::overload_cast, std::string const&>(&GSPNBuilder::addTimedTransition), "Adds an timed transition to the GSPN", "priority"_a, "rate"_a, "numServers"_a, "name"_a = "") .def("set_transition_layout_info", &GSPNBuilder::setTransitionLayoutInfo, "set transition layout information", "transitionId"_a, "layoutInfo"_a) + // todo write tests .def("add_input_arc", py::overload_cast(&GSPNBuilder::addInputArc), "from"_a , "to"_a, "multiplicity"_a) .def("add_input_arc", py::overload_cast(&GSPNBuilder::addInputArc), "from"_a, "to"_a, "multiplicity"_a) .def("add_inhibition_arc", py::overload_cast(&GSPNBuilder::addInhibitionArc), "from"_a, "to"_a, "multiplicity"_a) @@ -67,9 +68,8 @@ void define_gspn(py::module& m) { // GspnParser class py::class_>(m, "GSPNParser") - .def(py::init<>()) - .def("parse", [](GSPNParser& p, std::string const& filename, std::string const& constantDefinitions) -> GSPN& { - return *(p.parse(filename,constantDefinitions)); }, "filename"_a, "constantDefinitions"_a = "") + .def(py::init<>()) + .def("parse", [](GSPNParser& p, std::string const& filename, std::string const& constantDefinitions) -> GSPN& {return *(p.parse(filename,constantDefinitions)); }, "filename"_a, "constantDefinitions"_a = "") ; // GSPN class @@ -81,27 +81,22 @@ void define_gspn(py::module& m) { .def("get_name", &GSPN::getName, "Get name of GSPN") .def("set_name", &GSPN::setName, "Set name of GSPN") - // todo write tests: + .def("get_number_of_places", &GSPN::getNumberOfPlaces, "Get the number of places in this GSPN") .def("get_number_of_immediate_transitions", &GSPN::getNumberOfImmediateTransitions, "Get the number of immediate transitions in this GSPN") .def("get_number_of_timed_transitions", &GSPN::getNumberOfTimedTransitions, "Get the number of timed transitions in this GSPN") - // todo write tests: + .def("get_place", [](GSPN const& g, uint64_t id) -> const Place& {return *(g.getPlace(id)); }, "id"_a) + .def("get_place", [](GSPN const& g, std::string const& name) -> const Place& {return *(g.getPlace(name)); }, "name"_a) + .def("get_timed_transition", [](GSPN const& g, std::string const& name) -> const TimedTransition& {return *(g.getTimedTransition(name)); }, "name"_a) + .def("get_immediate_transition", [](GSPN const& g, std::string const& name) -> const ImmediateTransition& {return *(g.getImmediateTransition(name)); }, "name"_a) .def("get_partitions", &GSPN::getPartitions, "Get the partitions of this GSPN") .def("get_places", &GSPN::getPlaces, "Get the places of this GSPN") .def("get_timed_transitions", &GSPN::getTimedTransitions, "Get the timed transitions of this GSPN") .def("get_immediate_transitions", &GSPN::getImmediateTransitions, "Get the immediate transitions of this GSPN") .def("get_initial_marking", &GSPN::getInitialMarking, "Computes the initial marking of this GSPN") - // todo tests (special case: getTimedTransition/... returns nullptr - // dereferencing a null pointer is undefined behavior, getTimedTransition returns nullptr (if transition naem does not exist -> test) - // test if get_place by id and name correct (overloaded) - .def("get_place", [](GSPN const& g, uint64_t id) -> const Place& {return *(g.getPlace(id)); }, "id"_a) - .def("get_place", [](GSPN const& g, std::string const& name) -> const Place& {return *(g.getPlace(name)); }, "name"_a) - .def("get_timed_transition", [](GSPN const& g, std::string const& name) -> const TimedTransition& {return *(g.getTimedTransition(name)); }, "name"_a) - .def("get_immediate_transition", [](GSPN const& g, std::string const& name) -> const ImmediateTransition& {return *(g.getImmediateTransition(name)); }, "name"_a) - - // todo write tests: + //todo tests: .def_static("timed_transition_id_to_transition_id", &GSPN::timedTransitionIdToTransitionId) .def_static("immediate_transition_id_to_transition_id", &GSPN::immediateTransitionIdToTransitionId) .def_static("transition_id_to_timed_transition_id", &GSPN::transitionIdToTimedTransitionId) @@ -137,8 +132,11 @@ void define_gspn(py::module& m) { // Transition class py::class_>(m, "Transition", "Transition in a GSPN") .def(py::init<>()) - .def("get_name", &Transition::getName, "Get name of this transition") + .def("get_id", &Transition::getID, "Get id of this transition") .def("set_name", &Transition::setName, "name"_a, "Set name of this transition") + .def("get_name", &Transition::getName, "Get name of this transition") + .def("set_priority", &Transition::getID, "Get priority of this transition") + .def("get_priority", &Transition::getPriority, "Get priority of this transition") // todo add missing ; @@ -166,10 +164,10 @@ void define_gspn(py::module& m) { // TransitionPartition class py::class_(m, "TransitionPartition") - .def(py::init<>()) - .def_readwrite("priority", &TransitionPartition::priority) - .def_readwrite("transitions", &TransitionPartition::transitions) - .def("nr_transitions", &TransitionPartition::nrTransitions, "Get number of transitions") + .def(py::init<>()) + .def_readwrite("priority", &TransitionPartition::priority) + .def_readwrite("transitions", &TransitionPartition::transitions) + .def("nr_transitions", &TransitionPartition::nrTransitions, "Get number of transitions") ; } diff --git a/tests/gspn/test_gspn.py b/tests/gspn/test_gspn.py index cfe9094..7da5ecd 100644 --- a/tests/gspn/test_gspn.py +++ b/tests/gspn/test_gspn.py @@ -30,7 +30,7 @@ class TestGSPNBuilder: assert p_id == place.get_id() assert place.has_restricted_capacity() == False - # todo this does not work (boost::optional ?): + # todo this does not work (boost::optional problem?): place.set_capacity(cap = 5) # assert place.has_restricted_capacity() == True # assert place.get_capacity() == 5 @@ -64,26 +64,23 @@ class TestGSPNBuilder: assert ti_weight == ti.get_weight() assert ti.no_weight_attached() == False - #def test_gspn(self): - # todo - #immediateTransitions = - #gspn = stormpy.gspn.GSPN("gspn", places, immediateTransitions, timedTransitions, orderedPartitions, actualExprManager, constantsSubstitution) def test_build_gspn(self): - gspn_name = "gspn_test" builder = stormpy.gspn.GSPNBuilder() + builder.set_name(gspn_name) + # todo place tests, set_place_layout_info (boost) - #p_id_0 = builder.add_place() - # p_id_0 = builder.add_place(capacity = 1, initialTokens = 0, name = "place_test") + # p_0 = builder.add_place() + # p_1 = builder.add_place(capacity = 2, initialTokens = 0, name = "place_test") # p_layout = stormpy.gspn.LayoutInfo(1, 2) - # builder.set_place_layout_info(p_id_0, t_layout) + # builder.set_place_layout_info(p_0, t_layout) - ti_0 = builder.add_immediate_transition() - ti_1 = builder.add_immediate_transition(priority=0, weight=0.5, name="ti_1") + ti_0 = builder.add_immediate_transition(priority=1, weight=0.5, name="ti_0") + ti_1 = builder.add_immediate_transition() - tt_0 = builder.add_timed_transition(priority=0, rate=0.5, name="tt_0") + tt_0 = builder.add_timed_transition(priority=2, rate=0.4, name="tt_0") # todo problems with sumServers (boost) # tt_1 = builder.add_timed_transition(priority=0, rate=0.5, numServers=2, name="tt_1") @@ -96,38 +93,76 @@ class TestGSPNBuilder: builder.set_transition_layout_info(ti_0, t_layout) gspn = builder.build_gspn() + assert gspn.get_name() == gspn_name + assert gspn.get_number_of_immediate_transitions() == 2 + # assert gspn.get_number_of_timed_transitions() == 2 + # assert gspn.get_number_of_places() == 2 + cp_ti_0 = gspn.get_immediate_transition("ti_0") + assert cp_ti_0.get_id() == ti_0 + assert cp_ti_0.get_weight() == 0.5 + assert cp_ti_0.get_priority() == 1 + cp_tt_0 = gspn.get_timed_transition("tt_0") + assert cp_tt_0.get_id() == tt_0 + assert cp_tt_0.get_rate() == 0.4 + assert cp_tt_0.get_priority() == 2 + # cp_p_0 = gspn.get_immediate_transition("p_0") + # assert cp_p_0.get_id() == p_0 + # assert cp_p_0.get_capacity() == 2 gspn_new_name = "new_name" gspn.set_name(gspn_new_name) assert gspn.get_name() == gspn_new_name def test_export_to_pnpro(self, tmpdir): - builder = stormpy.gspn.GSPNBuilder() builder.set_name("gspn_test") ti_0 = builder.add_immediate_transition(priority=0, weight=0.5, name="ti_0") gspn = builder.build_gspn() - # todo add trans and places (place layout after import?) + # todo add some trans and places (place layout after import?) + # add arcs export_file = os.path.join(str(tmpdir), "gspn.pnpro") + # export gspn to pnpro gspn.export_gspn_pnpro_file(export_file) + # import gspn gspn_parser = stormpy.gspn.GSPNParser() gspn_import = gspn_parser.parse(export_file) + assert gspn_import.get_name() == gspn.get_name() assert gspn_import.get_number_of_timed_transitions() == gspn.get_number_of_timed_transitions() assert gspn_import.get_number_of_immediate_transitions() == gspn.get_number_of_immediate_transitions() assert gspn_import.get_number_of_places() == gspn.get_number_of_places() - # tets transition name - # ti_0_import = gspn_import. + cp_ti_0 = gspn_import.get_immediate_transition("ti_0") + assert cp_ti_0.get_id() == ti_0 + + + def test_export_to_pnml(self, tmpdir): + builder = stormpy.gspn.GSPNBuilder() + builder.set_name("gspn_test") + ti_0 = builder.add_immediate_transition(priority=0, weight=0.5, name="ti_0") + gspn = builder.build_gspn() + # todo add some trans and places (place layout after import?) + # add arcs (cp from above) + + export_file = os.path.join(str(tmpdir), "gspn.pnml") + + # export gspn to pnml + gspn.export_gspn_pnml_file(export_file) + + # import gspn + gspn_parser = stormpy.gspn.GSPNParser() + gspn_import = gspn_parser.parse(export_file) - # assert gspn_from_file.nr ==... - #asser name of ti + assert gspn_import.get_name() == gspn.get_name() + assert gspn_import.get_number_of_timed_transitions() == gspn.get_number_of_timed_transitions() + assert gspn_import.get_number_of_immediate_transitions() == gspn.get_number_of_immediate_transitions() + assert gspn_import.get_number_of_places() == gspn.get_number_of_places() + cp_ti_0 = gspn_import.get_immediate_transition("ti_0") + assert cp_ti_0.get_id() == ti_0 - # todo test to_pnml (cp test to pnpro) - #def test_export_to_pnml(self, tmpdir):