令我郁闷的是,PNML Framework 几 乎是一套静态的库——这个其实可以从它的架构设计思想上就可以看出来:它的接口就是以一个假想的Petri Net Tool A为使用环境设计的,它在主页上说的必须实现的feature就包括import、load、export等,完全是针对某个Petri Net工具的一个转换器角色。在对源代码的暴力阅读(RTFC )和暴力逆向(eUML2 )时,我找不到类似add()这样用于动态创建模型对象的接口和ArcFactory、ArcFactoryImpl这样ecore风格的生产类。
相反,当我无奈的转向Petri Net Kernel (PNK) 时,却发现了简单方便的模型,它内核包含6个类,网的基本类是一个二元有向图。基类叫做extendable,没什么内容,连Petri Net的本性的Graph都是它的子类,Graph有Node和Edge。在Graph类以下是Net,再往下就跟PNML framework有些类似了,包括Node和Arc,Node又分两类:Place和Transition。
Net
Arc
Place
Transition
Extension
Specification
A petrinet is a bipartitioned, directed graph with nodes called places and transitions.
For the beginning I list the methods of these classes and try to explain their meaning. Then I will discuss their use by an example.
The Net class describes a petrinet. It has methods to access their arcs, places and transitions. Or you may ask a net for it's FiringRule object that describes when a transition is concessioned and how you does it fire. How do you may profite from these methods you will see in the Example Simulator chapter.
public final class Net extends Graph {
public Vector getArcs()
public Vector getPlaces()
public Vector getTransitions()
public FiringRule getFiringRule()
} // class Net
The Place class describes a place of a petrinet. You create a place using the class constructor. The place registers itself in the net which must be passed as a constructor's parameter. You can remove a place by calling it's delete() method. You may request the current marking and so on ...
public final class Place extends Node
public Place(Net net, String name, Object initiator)
public void delete(Object initiator)
public Marking getMarking()
public void setMarkingAsInitial()
} // class Place
The Transition class describes a transition of a petrinet. You create a transition using the class constructor. The transition registers itself in the net which must be passed as a constructor's parameter. You delete it using it's delete() method. You can also request the mode of a transition.
public final class Transition extends Node {
public Transition(Net net, String name, Object initiator)
public void delete(Object initiator)
public Mode getMode()
} // class Transition
The Arc class describes an arc of a petrinet. You create a new arc using the class constructor. The arc registers itself in the net passed as constructor parameter. You may ask an arc for it's initialnode, it's targetnode, it's inscription and so on ...
public class Arc extends Edge {
public Arc(Net net, Node source, Node target, Object initiator)
public Inscription getInscription()
public Place getPlace()
public Transition getTransition()
/// METHODS INHERITED FROM class Edge:
public Node getSource()
public Node getTarget()
} // class Arc
在PNK的QuickStart 上有关于这一套库的简介,没有太多废话;PNK的界面也是相当的简单,这对后人实在是一个好消息~
包之间的依赖关系:
de.huberlin.informatik.pnk.kernel
de.huberlin.informatik.pnk.kernel.base
de.huberlin.informatik.pnk.app
de.huberlin.informatik.pnk.app.base
de.huberlin.informatik.pnk.appControl
de.huberlin.informatik.pnk.appControl.base
de.huberlin.informatik.pnk.netElementExtensions
de.huberlin.informatik.pnk.netElementExtensions.base
de.huberlin.informatik.pnk.editor
de.huberlin.informatik.pnk.exceptions
例如,de.huberlin.informatik.pnk.kernel.base 提供了对kernel的基本操作接口,继承关系 如下:
依赖关系如下:
As you already notice the ApplicationControl in the de.huberlin.informatik.pnk.appControl package plays an very important role. This class manages all nets and applications of the Petrinet Kernel. The ApplicationControl parses some XML files for configuration. These are for example the specification of all nettypes in the netTypeSpecification directory or a list of valid applications to each nettype in toolSpecification .xml file. Furthermore it is responsible for loading and writing nets as PNML files . It also offers useful interfaces that lets different applications cooperate with each other. Using the main main() method of the ApplicationControl you launch the Petrinet Kernel on commandline.
java -classpath .:crimson.jar:jaxp.jar
de.huberlin.informatik.pnk.appControl.ApplicationControl
toolSpecifications/toolSpecification.xml
toolSpecification .xml定义了网的类型、对于每一类网有效支持的工具以及这类工具提供的对外协作的接口,示例如下:
< ?xml version="1.0" encoding="UTF-8"? >
< !DOCTYPE toolSpecification SYSTEM "toolSpecification.dtd" >
< toolSpecification >
< !-- Nettypes -- >
< nettype id="n1" typeSpecification="file:netTypeSpecifications/simpleHLNet.xml"/ >
< nettype id="n2" typeSpecification="file:netTypeSpecifications/dawnNet.xml"/ >
< nettype id="n3" typeSpecification="file:netTypeSpecifications/Echo.xml"/ >
< !-- Applications -- >
< application id="a1" mainClass="de.huberlin.informatik.pnk.editor.Editor" maxinstances="inf" >
< allowedNettypes >
< ntref ref="n1"/ >
< ntref ref="n2"/ >
< ntref ref="n3"/ >
< /allowedNettypes >
< /application >
< !-- Input / Output -- >
< format id="pnml" ioClass="de.huberlin.informatik.pnk.appControl.PnmlInOut" >
< allowedNettypes >
< ntref ref="n1"/ >
< ntref ref="n2"/ >
< /allowedNettypes >
< /format >
< format id="io" ioClass="de.huberlin.informatik.pnk.appControl.InOut" >
< /format >
< !-- default settings -- >
< standardNettype ref="n1"/ >
< standardApplication ref="a1"/ >
< standardFormat ref="pnml"/ >
< /toolSpecification >
可见它主要 包含三个部分:Nettypes 网的类型、 Applications 支持的工具 、Input / Output 工具协作的接口。
Now let's take a look at the Simulator application in the de.huberlin.informatik.pnk.app package. This example should show how easy it is to write an application.
略,见 QuickStart , Alexander Gruenewald
Petri Net Kernel 没与PNML Framework 相比,它没有采用先进的EMF建模技术,因此不便于与eclipse集成;但是它在向上层应用提供服务上较为完善,便于在应用程序中调用。另外,由于没有利用EMF框架,Petri Net Kernel 完全是自己实现的UI和上层管理,因此代码量大很多。
所以,从集成的角度看,还是应当吃透EMF基本知识,改良PNML Framework ,考虑如何在PNML Framework 上实现Petri Net Kernel 类似的功能。