Bixby Developer Center

Guides

Match Patterns

When Bixby dynamically generates programs, it needs a way to determine which actions apply to which concepts, and which dialogs, layouts, and strategies to use as it builds the execution graph. It does this with match patterns.

The keyword match introduces the root of the match pattern. This root is a .bxb format key-value pair:

match: concept (name)

As Bixby builds the plan, the current node is compared against the concept type, and if they're compatible, the match pattern is kept as a possible candidate to use in the execution plan. If the pattern is used, the name is said to be bound to the matched node.

How is the "winning" match pattern selected from possible candidates? Each match pattern root leads to other possible paths, with different branches along the possible execution path. The entire match pattern tree that starts at a given pattern must match the current plan execution for that pattern to remain a valid candidate. If more than one pattern remains valid after the whole-tree matching, the most specific pattern will be used by Bixby.

For examples of how to use match patterns, see the Match Pattern sample capsule and the Video Tutorial.

Match Pattern Examples

Let's say Bixby is looking for a dialog for restaurants found with the FindRestaurants action. This simple match pattern would be valid, because Restaurant extends Business:

match: viv.business.Business (this)

However, this one would be preferred, because it is more specific:

match: viv.restaurant.Restaurant (this)

This last option, though, is the most specific because the from-output key specifies this pattern should match concepts that are the output of FindRestuarants:

match: viv.restaurant.Restaurant (this) {
from-output: restaurant.FindRestaurants (action)
}

In this more complex example, the match pattern binds the layout of an open hours judgement with its source entity, regardless of its type:

match{
viv.hours.OpenHoursJudgement (judgement) {
from-output: viv.hours.JudgeOpenHours (judgeOpenHours) {
from-input: viv.hours.HoursInformation (hoursInformation) {
from-property: _ (source)
}
}
}
}

Wildcard type (_)

The node type in the match pattern can also be set to the wildcard underscore (_), which will match any node. This is particularly useful for property projections with concept models.

match: _(property) {
from-property: contact.Contact (output)
}

This pattern will match any property of a contact.

match

This is the outermost container that introduces a match pattern.

When modeling for Bixby, the match key has no value and a single child key, which is the match pattern root.

Remember that curly braces ({}) can be collapsed into a colon (:) when there is a single child. Thus, these are equivalent ways to introduce a match pattern:

match {
viv.restaurant.Restaurant (this)
}
match: viv.restaurant.Restaurant (this)

min and max

Use min and max to add cardinality constraints on a match pattern. The min key determines whether a single instance is required, while the max key determines how many instances are allowable.

For example, this view matches only when there is exactly one instance of VivContext:

result-view {
match: VivContext(this) {
min (Required) max (One)
}
render {
layout {
section {
content {
paragraph {
value ("#{raw(this)}")
}
}
}
}
}
}

View master on GitHub

Links

You can create more specific matches in your match patterns by specifying "from" and "to" links that the current node needs to be connected to in order for the match pattern to be valid. Here's an example to illustrate this from the Space Resorts sample capsule: this input view matches a SpaceResort result (the "parent" node of the link), but only when the SpaceResort is an input to the CreateItem action (the "child" node).

input-view {
match: SpaceResort(result) {
to-input: CreateItem(action)
}
message {
macro (SPACE_RESORT_SELECTION)
}
render {
if (size(result) > 1) {
selection-of (result) {
where-each (item) {
macro (space-resort-summary) {
param (spaceResort) {
expression(item)
}
}
}
submit-button {
macro (Book)
}
}
} else-if (size(result) == 1) {
layout {
macro (space-resort-details) {
param (spaceResort) {expression (result)}
}
select-button-text: macro (Book)
}
}
}
}

View master on GitHub

This example has a link going in the other direction: this dialog matches BusinessCategory, but requires that the BusinessCategory be a property of a Business concept.

dialog (Result) {
match {
BusinessCategory (this) {
from-property: Business (business)
}
}
template("#{value(business.name)} has #{joinAs('value', this)}.")
}

View master on GitHub

To and From links can be used in combination to refine match patterns even further.

Links can even be nested. In this example of an instantiation strategy for a capsule that looks for nearby airports, a SearchRadius is given a default suggested search radius of 25 miles by describing a chain of inputs and outputs from the SearchRadius to the FindAirport action. This match pattern is only a valid match for a execution path that reaches the child nodes in the specified order:

instantiation-strategy {
id (search-radius-for-airports-25-miles)

match {
geo.SearchRadius (default) {
to-input: geo.BuildPointRadius {
to-output: geo.PointRadius {
to-input: geo.BuildPointRadiusSearchRegion {
to-output: geo.SearchRegion {
to-input: FindAirport
}
}
}
}
}
}

strategy {
intent {
goal: geo.SearchRadius
value: geo.DistanceUnit (Miles)
value: geo.DistanceMagnitude (25.0)
}
}
}

To and From Links

We've seen several kinds of to- and from- links in the examples above. You can specify an input, output, role, or property as either a to- or a from- link:

  • to-input: Signifies that the parent is an input to the child. For this to be possible, the child has to be an action and the parent has to be a defined input to that action.
  • to-output: Signifies that the child is an output of the parent. For this to be possible, the parent has to be an action and the child has to be the defined output of that action.
  • to-property: Signifies that the child is a property of the parent. For this to be possible, the parent has to be a structure and the child has to be a defined property of that structure.
  • to-role: Signifies that the child is instantiating a role of the parent. For this to be possible, the parent has to be a primitive or a structure and the child has to define a role-of or extends relationship to that concept.
  • from-input: Signifies that the child is an input to the parent. For this to be possible, the parent has to be an action and the child has to be a defined input to that action.
  • from-output: Signifies that the parent is an output of the child. For this to be possible, the child has to be an action and the parent has to be the defined output of that action.
  • from-property: Signifies that the parent is a property of the child. For this to be possible, the child has to be a structure and the parent has to be a defined property of that structure.
  • from-role: Signifies that the parent is instantiating a role of the child. For this to be possible, the child has to be a primitive or a structure and the parent has to define a role-of or extends relationship to that concept.

Confirming

This is a special link type used for matching confirmation views. The parent of a confirming link is usually a concept that extends viv.core.Confirmation, a boolean set to true if the user has confirmed the linked action; confirming specifies which action has been confirmed.

In this example, this match pattern for a confirmation-view matches confirmations for the CommitOrder transaction:

    match {
core.Confirmation {
confirming {
CommitOrder (action)
}
}
}

View 867dde1 on GitHub

input-group

Sometimes you'll want to customize dialog for elicitation events or input events related to an entire input-group, not just a single input. There's a special match pattern form for this: the action name, a tilde (~), and the input group name.

match: actionName~inputGroupName

Here's an example:

dialog (Elicitation) {
match {
viv.hotel.FindHotelsWithAvailability~checkOutOrDuration {
to-input: viv.hotel.FindHotelsWithAvailability (action)
}
}
template ("When will you check out?")
}

This dialog matches elicitations for the input group checkOutOrDuration to the action viv.hotel.FindHotelsWithAvailability. The template could use action to refer to this action, but in this case it doesn't.

Expression Language

You can use Expression Language (EL) functions to perform tests and operations on concepts within match patterns. For example, this pattern matches when moon.MoonPhase is set and is equal to the string "New Moon":

match {
moon.MoonPhase (this) {
if (exists(this.name) && this.name == "New Moon") {
...
}
}
}

Video Tutorial: Match Patterns

The following video tutorial shows several ways to use match patterns.