Scalable Simulation Framework
Domain Modeling Language (DML)
Reference Manual

DML grammar
DML schema format
      _schema  tuple syntax verification
      _find  inline attribute substitution
      _extends  inline inheritance semantics

DML Grammar in BNF Format
DML          ::=  (space* Attribute space*)+
Attribute    ::=  Key space+ Value
Key          ::=  Name | ReservedName
Name         ::=  ^[^_][a-zA-Z0-9_-]*
ReservedName ::=  ^_[a-zA-Z0-9_-]*
Value        ::=  String | \[ DML \]
String       ::=  [^(space)\]\[]+ | "[^"]+"
space        ::=  [ \t\n]

The escape character is the backslash "\".

Reserved keys: _schema, _find, _extends.

Simplified English translation

  • A DML expression is a list of whitespace-separated Key and Value pairs.
  • A Key is an alphanumerical string. A Key reserved for special use begins with an underscore "_".
  • A Value can be a String or a DML expression enclosed in square brackets.
  • A Value String is an arbitrary ASCII string enclosed in quotes "...". The enclosing quotes may be omitted if a Value String does not include whitespace nor the square brackets. Note that a Value String may be a regular expression (special characters need to be escaped with backslash "\").
Regular expressions in a nutshell
DML Schema Format

A schema specifies a concrete DML attribute tree by specifying key names, attribute value types, and the allowed number of attribute instances. Conveniently, DML schemas can be written using the DML syntax, where an attribute's value type and number of instances are represented by a formatting expression embedded in the DML Value of String type.

A value type is expressed in a microlanguage whose syntax is:

valuetype ::=  %format
format    ::=  [SFI] count |
               S count: regexp |
               T count: keypath
count     ::=  empty | integer(!)? |
               integer<integer | <integer
integer   ::=  [1-9][0-9]*

Notes:

A keypath uniquely identifies an attribute in a schema tree (either internal or leaf) by a sequence of dot-separated keynames along the path from the root to the attribute. This is analogous to filesystem pathnames on Unix machines.

%[SFI]count (String, Float, Integer) specify leaf attribute value type and number of instances.

%Scount:regexp uses regular expression matching to restrict strings that may be values of a leaf attribute. Warning: This feature is currently not supported.

%Tcount:keypath specifies a substitution of value by the content of another schema. This allows to specify the count of non-leaf attributes.

count

  • if omitted, specifies that any number of instances is permitted (including none);
  • a positive integer n specifies the minimum required number of instances is n;
  • <n specifies that the maximum allowed number of instances is n;
  • m<n specifies that the number of instances must be in the range m,m+1,...n;
  • a trailing ! after an integer count specifies that the count must be exact.

Examples:
%S     -- string leaf attribute that may have any number of instances;
%I1    -- integer leaf attribute that must have at least one instance;
%F2!  -- float leaf attribute that must have exactly two instances;
%S<3     -- string leaf attribute that may have 0, 1, 2, or 3 instances;
%F2<5 -- float leaf attribute that must have 2, 3, 4, or 5 instances;
%T1:.key1.key2    -- an internal attribute that must have at least one instance;
%S<2:[1-9][0-9]*[ \t]+[GMkK]B -- string leaf attribute that may have at most two instances, and whose values must match the regular expression, e.g., "125 kB" or "2001 MB".

Reserved attribute names

_schema keypath

When present in an internal attribute, the keypath points to another dml tuple that contains the schema for that internal attribute. Used by Schema Checker for validation.

_find keypath

When present in an internal attribute, is replaced by the last attribute specified in the keypath (has-a relation).

_extends keypath

When present in an internal attribute, makes this attribute inherit all attributes contained in the attribute pointed to by keypath (is-a relation).

See how these directives are used in the examples below.

Attribute ordering in a tuple

The order of different-name attributes is insignificant, but the order of same-name attributes is significant and tools should preserve it. So, for example, when you write:

   graph [
     ProtocolSession [name server use test.masterServer port 10]
     ProtocolSession [name socket use SSF.OS.Socket.socketMaster]
     ProtocolSession [name tcp use SSF.OS.TCP.tcpSessionMaster] 
     ProtocolSession [name ip use SSF.OS.IP]
   ]

the order of ProtocolSession attributes in a host configuration database can be used to determine the order of protocol initialization during the model instantiation phase, as initialization of a higher protocol may depend on the completion of a lower protocol initialization. In SSFNet, when the simulation starts, the protocols are initialized in the reverse order of their appearance in the graph attribute, thus assuring that ip is initialized first, followed by tcp, socket, and server, in this order.

DML Schema Checker

The DML package includes a schema checker that validates the syntactic correctness of an attribute whenever the attribute specifies a _schema subattribute.

Example: DML schema file

dictionary [
  schemas [
    tty [
      name %S:tty[0-9]+
      speed %S:[0-9]+[kKmM][bB][sS]
    ]
    machinespecs [
      powerconsumption  %S1!:[0-9]+[ \t]+[mMkK][wW]
      mtbf              %S:[0-9]+[ \t]+days
      replacementcost   %S:$[0-9,]* 
    ]
    portmaster [
      serialnum %I1!
      hostname %S1!
      tty %T:.dictionary.schemas.tty
      machinespecs %T1!:.dictionary.schemas.machinespecs
    ]
  ]
]

Example: DML database fragment in a model configuration file:

dictionary [
  equipment [
    cabletron [
      portmaster [
        machinespecs [
          _schema ".dictionary.schemas.machinespecs"
          powerconsumption 1600w
          mtbf "20 days"
          replacementcost "$500,000"
        ]
      ]
    ]
  ]
]

In the above example, the Schema Checker will consult the schema .dictionary.schemas.machinespecs to evaluate the syntactic correctness of this particular instance of the attribute machinespecs when it is loaded during model instantiation.

Note that the toplevel attribute dictionary specifies no schema (i.e., a deliberate polymorphism) so this will not cause an error when loaded against the previous schema file, which also contains a toplevel attribute dictionary with entirely different subtree.

Inline attribute substitution

Attribute _find keypath is used for in-line substitution of the attribute referred to in keypath.

There may be arbitrarily many instances of _find in an attribute.

Note that the _find key imports the last attribute specified in the keypath.

Example: DML database fragment that uses both previous dictionaries:

portmaster [
  _schema ".dictionary.schemas.portmaster"
  serialnum 12345
  hostname "far.near.net"
  tty [ name tty01 speed 40kBs]
  tty [ name tty02 speed 800Mbs]
  tty [ name tty03 speed 4kBs]
  _find ".dictionary.equipment.cabletron.portmaster.machinespecs"
]

Therefore, upon the expansion of the value of _find, the last example is equivalent to

portmaster [
  _schema ".dictionary.schemas.portmaster"
  serialnum 12345
  hostname "far.near.net"
  tty [ name tty01 speed 40kBs]
  tty [ name tty02 speed 800Mbs]
  tty [ name tty03 speed 4kBs]
  machinespecs [
    _schema ".dictionary.schemas.machinespecs"
    powerconsumption 1600w
    mtbf "20 days"
    replacementcost "$500,000"
  ]
]

A word of warning: if any of the keys in the keypath used as the value of  _find had multiple instances, _find would expand to the enumeration of values of all instances of the terminal attribute, which would be an error in this example, because machinespecs must have exactly one instance.

DML Inheritance Semantics

The attribute _extends keypath implements multiple inheritance with strict ordering. It is easiest to explain by examples.

The DML code may use _extends multiple times per attribute, and keys in the extended attribute may overlap with keys in the extending attribute. Order of same-name attributes is the same as that defined by _find, i.e., the imported attributes appear as if they had been defined directly at the position of _extends.

For example, given:

  x [
    y foo
    _extends .z
    y splat 
  ]
  
  z [
    y bar
    y baz
  ]

the attribute x is equivalent to (note the ordering):

  x [
    y foo
    y bar
    y baz
    y splat 
  ]

And the Java DML query find(".x.y") will return the enumeration {foo,bar,baz,splat}.

One can also write multiple-inheritance configurations, like this example:

  truck [
    wheels 4 
    cylinders 8
    serial_number 1234
  ]

  artillery [
    caliber 70mm 
    cycletime 30s 
    range 10km
    serial_number 5678
  ]

  tank [
    _extends .truck
    _extends .artillery
    price $40M
  ]

where now the attribute tank is equivalent to:

  tank [
    wheels 4 
    cylinders 8
    serial_number 1234
    caliber 70mm 
    cycletime 30s 
    range 10km
    serial_number 5678
    price $40M
  ]

And the DML query (in Java) find(".tank.serial_number") will return the enumeration {1234,5678}.

Note: the implementation of _extends is pretty much like implementing OO inheritance, and the same potential problems have to be checked for as errors, in particular circular inheritance, which may not be detected by the DML schema checker.


Last updated October 14, 1999.