Skip to content

Sub-rules

Definition and references

A sub-rule is a portion of rule that does not get evaluated by itself but can be referenced, by name, in other rules.

Sub-rules are useful when you have several rules with some common parts, because they avoid writing these parts multiple times. This also helps reduce the occurrence of errors.

A sub-rule can either be used in a rule as the only element constituting the condition or combined with other attributes using for example boolean operators.

For example, consider this rule:

SCOPE SENTENCE
{
    DOMAIN(dom1:NORMAL)
    {
        ANCESTOR(12828) /*12828: plane, aeroplane, airplane*/
        AND
        LEMMA("hijack")
        AND NOT
        (
            LEMMA ("fiction") > LEMMA("story")
            OR
            ANCESTOR(30419, 30451)//  30419: film, movie // 30451: television show, television program
            OR
            SYNCON(29428,18571)//  29428: novel (genre)  18571: novel (physical object);
        )
    }
}

If you have more rules sharing the part of the condition highlighted in yellow, you can define a sub-rule like this:

#fiction# = LEMMA ("fiction") > LEMMA("story")
            OR
            ANCESTOR(30419, 30451)//  30419: film, movie // 30451: television show, television program
            OR
            SYNCON(29428,18571)//  29428: novel (genre)  18571: novel (physical object)
;

and then you can refer to it by its name in other rules:

SCOPE SENTENCE
{
    DOMAIN(dom1:NORMAL)
    {
        ANCESTOR(12828) /*12828: plane, aeroplane, airplane*/
        AND
        LEMMA("hijack")
        AND NOT
        #fiction#
    }
}

The syntax of the sub-rule definition is:

#sub-ruleName# = sub-rule;

Or, alternatively:

#sub-ruleName#
=
sub-rule
;

where sub-ruleName is the name of the sub-rule. The semi-colon at the end is a mandatory terminator.

Warning

If you write comments:

  • Between the sub-rule name and the equal sign (=).

Or:

  • Between the equal sign (=) and the sub-rule.

an error will occur.

Sub-rules must be defined before being referenced.
It's advisable to define them at the beginning of the rules file or in a separate .cr file that is imported in the main rules file.

There are two different syntaxes to refer to a sub-rule in a rule:

##sub-ruleName##

And:

#sub-ruleName#

In the first case it is as if the sub-rule was written verbatim in the rule.

In the second case it is as if round brackets were automatically added around the sub-rule, i.e. you don't have to write them in the sub-rule or in the rules referencing it.

The following is an example of rules in which to adopt the first syntax:

SCOPE scopeOption
{
    DOMAIN(domainName:scoreOption) | IDENTIFY(templateName)
    {
        operand
        positionalSequence | logicalOperator
        ##sub-ruleName##
    }
}

And this is an example of rules in which to adopt the second syntax:

SCOPE scopeOption
{
    DOMAIN(domainName:scoreOption) | IDENTIFY(templateName)
    {
        operand
        booleanOperator
        #sub-ruleName#
    }
}

Automatic parentheses help evaluating Boolean sub-expressions with the correct precedence order.

Combination of sub-rules

Sub-rules can contain references to other sub-rules, given referenced sub-rules are defined before the sub-rule referring to them.

For example:

#date_and_hour# = TYPE(DAT)
                  <>
                  TYPE(HOU) 
;

#fiction# = LEMMA ("fiction") > LEMMA("story"),
            ANCESTOR(30419, 30451),//  30419: film, movie // 30451: television show, television program
            SYNCON(29428,18571)//  29428: novel (genre)  18571: novel (physical object)
;

#fiction_date_and_hour# = ##date_and_hour##, ##fiction##;

SCOPE SENTENCE
{
    DOMAIN(dom1)
    {
        ANCESTOR(12828) /*12828: plane, aeroplane, airplane*/
        AND
        LEMMA("hijack")
        <>
        MANDATORY
        {
            ##fiction_date_and_hour##
        }
    }
}

In the sub-rule definition you can use two hashes (verbatim expansion) or one hash (automatic addition of surrounding parentheses) syntax for sub-rules placeholders.

Other applications of sub-rules

Being portions of rules, sub-rules applications are not limited to conditions.
The example below shows an application to rules that use segments.

Sub-rules can also be used with segments.
For example:

SEGMENTS
{
    @SEGMENT1,
    @SEGMENT2,
    @SEGMENT3
}

SCOPE SENTENCE
{
    SEGMENT(SEGMENT1)
    {
        LEMMA("storm", "snowfall", "tornado", "hurricane")
    }

    SEGMENT(SEGMENT2)
    {
        ANCESTOR(102221906)//@SYN: #102221906# [place]
    }

    SEGMENT(SEGMENT3)
    {
        TYPE(ADJ)
    }
}

#SEGMENTS_TO_NEGATE# = SEGMENT1, SEGMENT2, SEGMENT3;

SCOPE SENTENCE IF NOT IN SEGMENT(##SEGMENTS_TO_NEGATE##)
{
    DOMAIN(dom1)
    {
        LEMMA("destroy")
    }
}

Sub-rules and boolean operators

As stated above, when you write sub-rules using this syntax:

##sub-ruleName##

it is as if the sub-rule was written verbatim in the rule.

For this reason, pay attention when you combine a sub-rule of this type with boolean operators inside it.

A rule like this:

#fiction# = LEMMA ("fiction") > LEMMA("story")
            OR
            LEMMA("book")
            OR
            LEMMA("film", "television show")
            OR
            SYNCON(29428,18571)//  29428: novel (genre)  18571: novel (physical object)
;

SCOPE SENTENCE
{
    DOMAIN(dom1:NORMAL)
    {
        ANCESTOR(12828) /*12828: plane, aeroplane, airplane*/
        AND
        LEMMA("hijack")
        <>
        ##fiction##
    }
}

is the same as:

SCOPE SENTENCE
{
    DOMAIN(dom1:NORMAL)
    {
        ANCESTOR(12828) /*12828: plane, aeroplane, airplane*/
        <1:4>
        LEMMA("hijack")
        <>
        LEMMA ("fiction") > LEMMA("story")
        OR
        LEMMA("book")
        OR
        LEMMA("film", "television show")
        OR
        SYNCON(29428,18571)//  29428: novel (genre)  18571: novel (physical object)
    }
}

As you can see, only the first operand of the sub-rule is related to the portion of rule before the positional sequence.

To correctly relate all the sub-rule operands to the portion of rule before the positional sequence, use the MANDATORY operator, like this:

#fiction# = MANDATORY
            {
                LEMMA ("fiction") > LEMMA("story"),
                LEMMA("book"),
                LEMMA("film", "television show"),
                SYNCON(29428,18571)//  29428: novel (genre)  18571: novel (physical object)
            };

SCOPE SENTENCE
{
    DOMAIN(dom1:NORMAL)
    {
        ANCESTOR(12828) /*12828: plane, aeroplane, airplane*/
        <1:4>
        LEMMA("hijack")
        <>
        ##fiction##
    }
}