HeaRTDroid is a rule-based inference engine both for Android mobile devices, and desktop solutions

User Tools

Site Tools


HMR Language

HeKaTe Meta Representation (HMR) is an algebraic notation, created to be human-readable language for XTT2 model representation. File written in HMR language is in fact a legal Prolog code, therefore it can be interpreted directly by ISO-compliant Prolog environments (for example SWI-Prolog). In case of usage outside the Prolog environment, HMR syntax is formally specified using Parsing expression grammar (PEG) — parser for the desired executing technology can be directly derived from grammar by means of a parser generator.

HMR file can be written by hand or it can be generated from different representations by HQEd XTT2 editor.


This section will present the semi-formal definition of HMR along with link to the full grammar used in actual parser generation process (using Mouse parser generator). Firstly, there will be defined primitive types used in HMR. Subsequent subsections will concern more and more complex elements of a HMR model.

As for the notation, double-quotes are put around the literals, brackets ( and ) are used to group tokens, and question sign ? is used in some places to mark that the preceding token is optional.


  • Comment: HMR supports multi line (/* COMMENT */) and single line comments (% COMMENT)
  • Number: HMR supports both Floats (with dot as separator) and Integers
  • String: every string used in HMR file. Defined the same way as an atom in Prolog, which can be expressed with following grammar rules:
| String grammar rules
// two variants
String = 
    QuotedString / 
// everything in single quotes; does not support escape characters
QuotedString = "'" ^["'"]* "'"; 
// starts with lowercase letter, then letter or digit or underscore
NormalString = [a-z] ([a-z]/[A-Z]/[0-9]/"_")*;
  • Foreign Identifier: identifies action or callback implemented in foreign language (for example in Java). Syntax is similar to Java class name rules (except lack of support for '$' character). It also supports dots in order to designate the Java package structure. It can be defined by following grammar rules:
| Foreign Identifier grammar rules
ForeignIdentifier =
    NormalString /
    "'" ([a-z]/[A-Z]/"_") ([a-z]/[A-Z]/"_"/[0-9]/'.')* "'";  
  • Symbol: string treated as value of an attribute, it can be associated with numeric weight:
| Weighted Symbol grammar rules
Symbol =
    String "/" UnsignedInteger /
  • Range: represents a range between two values (Numbers or Strings, whenever there is defined order over elements). It has fairly straightforward syntax:
| Range grammar rules
// both values should be of the same type (Number or String)
Range = Value "to" Value; 
  • Set: represents a collection of Values (Number, String, Range).
| List grammar rules
// both values should be of the same type (Number / String / Range)
// you can mix Range elements with simple Values, when Range represents values
// of the same type (Number and range of Numbers) 
List = "[" Value ("," Value)* "]"
  • Boolean: represents logical value (in two-valued logic).
| Boolean grammar rules
Boolean = "yes" / "no";
  • Time index: a non-positive number designating a specified moment in the history of the program execution. It can be written with time unit ('ms', 's', 'min', 'h'), or without it e.g.
| Time index grammar rules
TimeIndex = '0' TimeUnit? | '-' Integer TimeUnit?
TimeUnit = 'ms' | 's' | 'min' | 'h' 
  • Time period: represents some past period of time. There are two ways to define a period. First uses colon as a separator. This way user can define also a step of quantization (what should be time difference between following samples) e.g. -5s : 1s : 0 will contain 6 samples measured at moments: -5s, -4s, -3s, -2s, -1s, 0.
| Time period grammar rules
TimePeriod = TimeIndex (Colon TimeIndex)? Colon TimeIndex  

The other way uses the old range notation and doesn't allow defining step value:

| Time Period grammar rules
TimePeriod = TimeIndex "to" TimeIndex.

In both definitions of period, user can't mix TimeIndexes with and without time units, e.g. -5 : 1s : 0 is not allowed, for details, please refer to the original grammar file.


Types in HMR language are used to define kind, structure and domain for further attributes definitions. Type grammar rules could look as follows:

| Type grammar rules
Type = "xtype" "[" "name" ":" String ","
                   "base" ":" ("numeric" / "symbolic") ","
	           "domain" ":" List ","
	           "desc" ":" String ","
                   "ordered" ":" Boolean "]" "."
  • namemandatory — a field that contains type's name.
  • base mandatory — a field describing base of the type. It can be either numeric, or symbolic.
  • domainmandatory — a field that contains a list of all acceptable values for this type. For ordered symbolic domains, it is possible to use. For instance in the example below, every day has it's own number assigned, that allows referring to the values using this number instead of symbolic name. If a symbolic domain is marked as ordered, and there are no weights assigned explicitly to the domain's values, default numbering is assumed that starts from 1 and ends on n, where n is the number of elements in the domain. This behavior is very similar to C enum construct.
  • ordered - optional — a field indicating whether domain is ordered or not. Every numeric type has ordered domain by default. It's required to create Range with values of this type.
  • descoptional — a field containing longer description of the type.

The order of fields does not matter, so type definition may look as follows:

Type example
xtype [ domain: [mon/1,tue/3,wed/5,thu/7,fri/9,sat/10,sun/20],
	ordered: yes, 
	desc: 'Days of the week', 
        name: day].


Attributes in HMR language denotes instances of defined types. Every attribute in the HMR language must have a type assigned. Only one type can be assigned to one attribute. Type definitions looks as follows:

| Attribute grammar rules
Attribute = "xattr" "[" "name" ":" String ","
   	                "class" ":" ("simple" / "general") ","
 		        "type" ":" String ","
		        "comm" ":" ("in" / "out" / "inter" / "comm") ","
		        "callback" ":" ForeignIdentifier ","
		        "abbrev" ":" String ","
		        "desc" ":" String "]" "."
  • namemandatory — a field contains attribute's name
  • classmandatory – a field that denotes weather the attribute is simple (represents simple values) or general (represents set values).
  • typemandatory – a field that contains a name of a type defined as xtype. This field denotes the attribute's type.
  • commoptional — a field that describes attribute's relation to the world. If the attribute is in it means that a value of it is supposed to be given by the user; if the attribute is out it means that the value of it should be presented to the user; if attribute is inter it means that its value is set by the system as a result of inference process, but it's not relevant to the user; if the attribute is comm, it means that it's both in and out.
  • callbackoptional — a field that contains an information about which callback is supposed to be fired for the attribute.
  • abbrevoptional — a field that contains short name of the attribute.
  • descoptional — a field that contains longer description of the attribute.

As with Type definition, order of fields does not matter. Attribute definition may look as follows:

Attribute example
xattr [name: day,
       abbrev: d,
       class: simple,
       type: days,
       comm: in,
       callback: ask_console.


Schemas represents XTT tables in HMR language. However, they cannot be considered as entities filled with rows containing rules. Schema is only a representation of relation between attributes that rules falling into this schema realizes. Definitions of schema looks as follows:

| Scheme grammar rules
Schema = "xschm" SchemaName "/" SchemaDesc ":" AttributesIn "==>" AttributesOut "."
SchemaName = String;
SchemaDesc = String;
  • SchemaNamemandatory — a field containing obligatory schema name,
  • SchemaDescoptional — a field containing an optional schema description,
  • atts_inmandatory — list of attribute names (or abbreviations); attributes in this list are required to be known by the rules that falls in this schema.
  • atts_outmandatory — list of attribute names (or abbreviations); attributes in this list are going to change their value as a result of the rule falling within this schema.

An example of schema definitions may look as follows:

Schema example
xschm current_season/"Scheme calculating current season": 
      [month, day] ==> [season].


Rules in HMR language are defined as follows:

| Rule grammar rules
Rule = "xrule" RuleName ":" Conditions "==>" Decisions "**>" Actions ":" Links "." "#" CertaintyFactor
RuleName = SchemeName "/" String;
  • RuleNamemandatory — a field composed from owning Schema's name and string identifying this particular rule.
  • Conditionsmandatory — list of conditions; every condition can only used Attributes declared in Schema's conditional part. Every condition has a form:
| Condition grammar rules
Condition = AttributeExpression ALSV_OPERATOR Value TemporalParameter?
  • AttributeExpression may be on of following:
| Rule grammar rules
AttributeExpression = AttributeName 
AttributeExpression = "valat" "(" AttributeName "," TimeIndex ")"
AttributeExpression = StatisticalOperator "(" AttributeName "," TimePeriod ")"

In the first case we use the attribute's name to check it's current value. In the second case we use “valat” operator to get historical value of the attribute at the specified moment of time. In the last case we use a statistical operator to get a statistical characteristics of the attribute. All availavle statistical operators are described below.

Statistical Operator Type of attribute Description
max numerical returns the biggest attribute's value from the period
min numerical returns the smallest attribute's value from the period
mean numerical returns the average attribute's value from the period
mode both types returns the most common atrribute's value from the period
med numerical returns the median of the attribute's values from the period
stddev numerical returns the standard deviation of the attribute's values from the period
trend numerical Returns slope of the trend line fitted to attribute's values using the least–squares fit
var both types In case of numeric attribute, returns variance of the attribute's values from specified period of time. In case of symbolic type, variance is replaced with entropy.
  • ALSV_OPERATOR is one of the unary operators. Following table contains every allowed combination. “any” and “null” are considered as special values allowed only in “neq” and “eq” contexts.
Operator Argument's type Description
subset List is the Attribute's value subset of Argument?
supset List is the Attribute's value super set of Argument?
sim List has the Attribute's value nonempty intersection with Argument?
notsim List has the Attribute's value empty intersection with List?
in List is the Attribute's value an element of Argument?
notin List doesn't Attribute's element belong to Argument?
eq Value is Attribute's value equal to Value?
eq any is Attribute set to anything?
eq null isn't Attribute set to anything?
neq Value is Attribute's value different from Value?
neq any isn't Attribute set to anything?
neq null is Attribute set to anything?
lt Ordered is Attribute's value less than Value?
lte Ordered is Attribute's value less or equal Value?
gt Ordered is Attribute's value greater than Value?
gte Ordered is Attribute's value greater or equal Value?
  • Additionally, in recent versions there were introduced optional Temporal Parameters, which check if a specified condition was satisfied in a period of time.
| Condition grammar rules
TemporalParameter = "{" "min"/"exact"/"max" Number "%" "in" TimePeriod "}"
  • Decisions - contains a list of Decisions, that have to fired when the all conditions are satisfied. Each Decisions has to assign value to Attribute already listed in owning Schema. It can be expressed as:
| Decisional grammar rules
Decision = AttributeName "set" DecisionalExpression;
  • DecisionalExpression has a form of algebraic expression using a set of left-associative binary operators and unary operators. There exist three types of allowed operands:
    1. Value (Symbol, Number, List, “null”)
    2. AttributeExpression
      • :!: Symbols and Attribute names share the same namespace; name clash is solved in favour of Attribute
    3. another Expression with higher precedence (can be obtained using brackets as in common algebra).
    • unary operators have precedence higher than binary operators and are written using functional notation. Following table contains all unary operators:
Operator Description
abs(Number) returns absolute value of Argument
cos(Number) returns cosinus of Argument
sin(Number) returns sinus of Argument
tan(Number) returns tangens of Argument
fac(Number) returns factorial of Argument
log(Number) returns natural logarithm of Argument
log10(Number) returns decimal logarithm of Argument
setpower(List) return set of subsets of Argument
min(OrderedList) return minimal element of Argument
max(OrderedList) return maximal element of Argument
Plans Statistical features of Attribute's history

Also, all the

  • binary operators with functional notation can be found in next table
Operator Description
complement(List, List) returns set with elements belonging to second argument and not beloning to first argument
except(List, List) returns set with elements belonging to first argument and not belonging to second argument
intersec(List, List) returns set with elements belonging to both arguments
union(List, List) returns set with elements belonging to at least one argument
  • binary operators with algebraic notations (all of them are left associative) are listed in next table (smaller number means higher precedence):
Operator Description Precedence
a ** b returns b-exponent of a 0
a * b returns product of a and b 1
a / b returns quotient of division a by b 1
a mod b returns remainder of division a by b 1
a + b returns sum of a and b 2
a - b returns difference between a and b 2
  • Actions is a list of Foreign Identifiers. Every identifiers indicates action, which should be performed after firing the rule. Actions can't change system state.
  • Links is a list of rules or schemes which receive control after firing the rule; every element of the list has a form:
| Link grammar rules
Link = RuleName / SchemeName;
  • Certainty Factor is an optional number from range ←1.0, 1.0>. If present, has to be preceded with # symbol. This number is used to handle uncertain knowledge in the reasoning phase.
  • Example of rule:
Rule example
xrule handle_wind/medium:
  [wind in [5.0 to 7.0], engine lt 10]
  [engine set log(wind) * (inertia + current_zero), detector_states set except(detector_states, [off])]
    * *>
  [handle_pressure, update_engine/wind].

which can be read as:

if value of wind attribute is between 5.0 and 7.0 AND value of engine attribute is less than 10 THEN set to attribute engine value equal log(wind attribute's value) * sum of inertia and current_zero values AND set detector_states to detector_states except element off PERFORM action update_engine MOVE CONTROL to schema handle_pressure AND rule update_engine/wind.


Having all elements already defined, HMR file is simply list of Types, Attributes, Schemas and Rules. The HMR example can be found here.

Further Remarks and Full Grammar

All the definitions written in earlier sections are strongly simplified. PEG grammars do not support polymorphic rules like List. Furthermore all the rules above hadn't coped with white characters. The grammar used in project is much richer — many subproblems of parsing the HMR file had to be moved into separate contextual analysis phase. Nonetheless following link contains the full HMR grammar at this moment of time. Grammar should be read according to Mouse parser generator manual.

pub/software/heartdroid/documentation/hmr.txt · Last modified: 2019/04/10 08:54 (external edit)