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 |
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);
};