User Tools

Site Tools


devel:naming_of_model_components

Naming of model components

Names of the nodes in Workcraft are used to identify the mathematical and visual nodes in the model. Every node in the model must have some name and normally every name is unique within its namespace. The root node of the mathematical model provides a namespace at the highest level. Inside the model, there may be other nodes (such as pages) that create their own namespaces.

Reference managers

A model keeps track of node names by means of reference managers. A default reference manager for the mathematical model is manages namespaces and maps every namespace in a model to a name manager. A name manager generates new names within a given namespace. Every name is a C-style identifier, it follows the regular expression pattern: [_A-Za-z][_A-Za-z0-9]*. There may be exceptions from this rule, e.g STG model uses + and / to specify signal transitions and their instances.

The automatic naming in a name manager is ensured by mixing some prefix with a number. For instance, connections can be named con1, con2, etc. while nodes can be named node1, node2, etc. The rules for prefix can be specified when the reference manager is created.

Currently there is no namespace concept in the visual model (none of the visual group nodes creates a new namespace) and by default a simpler ID generator is used for names.

Some nodes introduce new namespaces – pages and groups are examples of such containers. For instance pages p1 and p2 may both have nodes named n1, because they are in different namespaces. Such objects can be referenced hierarchically while using / as the hierarchy separator (just like in the folder structure). For instance, p1/n1 and p2/n1 are absolute references to two different nodes in two different namespaces. The / at the beginning of reference is not necessary, the reference is assumed to be an absolute path.

A special naming rule is used to mark different instances when the name stays the same in STGs. Here / followed by a number is considered a part of a name, and not the beginning of a new hierarchy. For instance p1/t+/3 would read as p1 followed by t+/3, because there are several t+ transition instances, and they all refer to the different nodes in the model.

Flat Names

Some models need to be simplified (flattened) before they can be processed by other tools. For instance, an export into a .g file would not support hierarchical names. For this purpose names are transformed so that they look like C-style identifiers while replacing all / with the double underscore symbol __. For instance, a signal name p1/a would be converted to p1__a.

Note that the instance numbers are not prefixed with __. For instance, the transition p1/a+/3 would convert to p1__a+/3, which is a normal name for a .g file format.

Relevant classes

The model names are stored and managed by the ReferenceManager object both in visual and mathematical models. Mainly it checks whether a name is unique/correct within a given model, it can also automatically generate unique names for new nodes and connections added to the model. The default name manager in the visual models is DefaultNameManager. It works within a single namespace and produces simple numeric IDs as names. These numeric IDs are not seen by the user, they are used to identify nodes when the model is converted to XML representation and saved into a file.

The default RefrenceManager in the math model is HierarchicalUniqueNameReferenceManager, it is using the dedicated NameManager to check and assign new names. The NameManager only works with the names that are C-style identifiers, which cannot start with a number. For convenience, this manager creates new names based on a given prefix function Func<Node,String>. For instance, the new places in a Petri net would be named p1, p2, etc. and the new transitions would be t1, t2, etc.

The hierarchical reference manager is associated with multiple NameManagers, one NameManager for each NamespaceProvider (such as MathGroup or PageNode). It creates a new NameManager automatically when it is required. The reference manager can be used to name some component, the Model itself, however, is more commonly used for this task, it forwards these calls to the associate reference manager. The main methods of main interest are:

  • getNodeByReference(String):Node – return a node identified by a full path name, e.g., page1/node1.
  • getNodeReference(Node):String – return a full path reference to a given node.
  • getName(Node) – return the name of the node only, without the path leading to it, e.g. node1.
  • setName(Node, String):void – assign a new name to the node.

See also NamespaceHelper class that contains a number of useful static functions working with hierarchical name strings.

Code examples

The correspondence between the node types and the default prefixes can be passed to the HierarchicalUniqueNameReferenceManager as an instance of a functor class Func<Node, String>() whose public String eval(Node arg) implementation defines the mapping. The reference manager is introduced in the constructor of the model class, for example:

public class ExampleModel extends AbstractMathModel {
    ...
    public ExampleModel(Container root, References refs) {
        super(root, new HierarchicalUniqueNameReferenceManager(refs, new Func<Node, String>() {
            @Override
            public String eval(Node arg) {
                if (arg instanceof SpecialNode) return "special";
                if (arg instanceof Connection) return "con";
	        return "node";
            }
        }));
    }
    ...
}