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##
    }
}