CIMTool can validate CIM/XML and Incremental CIM/XML documents against profiles. It does this by applying a built in set of validation rules to the schema and the CIM/XML input.

The built in rules cover all schema-based validation some electrical topology validation and some CIM/XML-specific rules. This ought to be sufficient validation for many purposes.

However, some constraints can't be captured in the profile definition but could be written as special case rule. This applies to some of the CPSM constraints currently recorded in prose. Project-specific constraints might also require special rules.

CIMTool provides the ability to add custom rules via the New Rules wizard. This wizard adds a set of rules to the project in the form of a text file. The rule language is an extension of the Jena rule language which uses a fairly common rule syntax.

General Form of a Rule

As an example, the following rule tests whether a connectivity node is referenced by at least two terminals:

[ -> 
  [ problem("Isolated node" topol:ConnectivityNode 
	"expect two or more terminals. Subject" ?n "has less.") 
		<- (?n rdf:type topol:ConnectivityNode) 
			countLessThan(2 * topol:Terminal.ConnectivityNode ?n)]]

The initial [-> and closing ] are part of the syntax for schema-dependent rules. For a simple rule they can be ignored. The validation rule is enclosed in the inner brackets [...]. Its form is:

	problem(...)  <- clause1 clause2 ...

Rule Head

The head of the rule is on the left of the <- and is a problem(...) clause. More generally, a sequence of clauses is allowed.

The head clauses are evaluated if the rule fires.

The problem(...) clause takes a sequence of terms and generates a diagnostic message. The terms may be strings like "Isolated node", resources like topol:ConnectivityNode, or variables like ?n.

These are concatenated, separated by spaces, to make the diagnostic message. The first resource, or variable that evaluates as a resource, becomes the key under which this message will be grouped in the diagnostic display.

Note that the prefix topol is predefined and stands for the namespace in which topology classes such as ConnectivityNode are defined.

Rule Body

The clauses to the right of the <- form the body of the rule. These clauses match statements in the input. The rule is fired for each distinct combination of statements that match the body.

The first body clause in the example is a statement pattern.

	 (?n rdf:type topol:ConnectivityNode) 

This matches every statement that asserts a resource, ?n, has type ConnectivityNode. In other words, it matches each connectivity node in the input.

Variables

A term like ?... denotes a variable. The first appearance of a variable in statement pattern is treated as a wildcard. It matches any resource.

Statement patterns bind each variable to its value for each match. In the example, the variable ?n is bound to a connectivity node resource for each match.

The variable is then used in other clauses, in the body or the head, where it stands for the bound value. For example, the connectivity node ?n appears in the diagnostic message.

Predicates

The second body clause is a predefined predicate, countLessThan(...). It counts the number of statements matching a pattern and tests whether this count is less than a given limit. The limit is the first argument. The following three arguments form the statement pattern.

Predicates don't bind variables to values, but they can contain wildards, *, and can use bound variables such as ?n.

The countLessThan(2 * topol:Terminal.ConnectivityNode ?n) clause matches if there are less than 2 resources with a Terminal.ConnectivityNode of ?n. As this is the last clause, a match fires the rule and causes a diagnostic message to be generated.