Optionals

Optional patterns can be used in match stages to optionally match a pattern, or in insert stages to insert a pattern if all the variables involved are bound.

Schema for the following examples
#!test[schema, commit]
define
    attribute email, value string;
    attribute phone, value string;
    attribute username, value string;
    relation friendship, relates friend @card(0..2);
    relation marriage, relates spouse @card(0..2);
    relation policy, relates covered @card(0..);
    entity user,
        owns username, owns email, owns phone,
        plays friendship:friend;
    entity person, plays marriage:spouse, plays policy:covered;

Syntax & Basic behavior

try { <pattern> };

match

Variables which are present only in the try block are considered optional. If the entire optional pattern matches the data, it returns an answer per match. If it has no matches, it produces a single answer with all optional variables bound to None.

#!test[read]
match
    $person isa person;
    try {
        $_ isa marriage, links (spouse: $person, spouse: $spouse);
    };

Here, $spouse will be bound to the spouse if $person is in a marriage. Else, $spouse will be bound to None

insert & delete

Coming soon!

Optional patterns in insert or delete stages will execute only if ALL the variables present in them are bound.

match
    $person isa person;
    try {
        $_ isa marriage, links (spouse: $person, spouse: $spouse);
    };
insert
    $policy isa policy;
    $policy links (covered: $person);
    try { $policy links (covered: $spouse); };

If $person is in a marriage, the match stage will bind $spouse and the insert stage will add them to the policy.

Optional patterns are banned in put stages.

Behavior in match clauses

Single origin

In the stage that it first occurs, An optional variable may only occur in a single try-block.

#!test[read, fail_at=runtime]
match
    $person isa person;
    try {
        $_ isa marriage, links (spouse: $person, spouse: $spouse);
    };
    try {
        $policy isa policy, links (covered: $spouse); # Invalid
    };

Optional variables in subsequent stages

An optional variable can be used in subsequent stages. An unbound optional variable will cause the pattern to fail.

The following is a valid way to express the intent of the example above:

#!test[read]
match
    $person isa person;
    try {
        $_ isa marriage, links (spouse: $person, spouse: $spouse);
    };
match
    try {
        $policy isa policy, links (covered: $spouse);
    };

Nested try blocks

Optional patterns can be nested. This is also an option for the previous example

#!test[read]
match
    $person isa person;
    try {
        $_ isa marriage, links (spouse: $person, spouse: $spouse);
        try {
            $policy isa policy, links (covered: $spouse); # Ok
        };
    };

Disallowed in negations

Optional patterns may not occur in negations, as they can have no effect on the result of the query - they can neither fail the pattern, nor bind any variables for use outside the negation.