Uh oh! We couldn’t find any match.

Please try other search keywords.

Bixby Developer Center

Guides

Match Patterns

Match patterns are the expressional instructions that tie everything together. Bixby uses them during execution to dynamically lookup the appropriate layout, dialog, strategy, etc for the current context.

The keyword match is used to introduce the root of the match pattern. This root is a .bxb format key value pair in the form of %type%(%name%). At runtime, the current node in the plan execution is compared against this %type% and if they are deemed compatible the match pattern is retained as a valid candidate. You can define any %name% value to later refer to that node in your layout, dialog, strategy, etc. (should it be selected).

How will the winning match pattern be selected from these candidates? Well, each match pattern root can define any number of links, creating match pattern branches. The entire match pattern tree must match with the current plan execution for it to remain a valid candidate. Should there be multiple valid candidates, the most specific one will be selected.

Match Pattern Examples

Let's say we are looking for a dialog for restaurants found via the FindRestaurants action. This simple match pattern would work 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 would trump all of the above, because it is the most specific.

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)
}
}
}
</match>

Wildcard type '_'

Note

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.

Example

This will match any property of a contact.

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

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 {
%match-pattern%
}

match: %match-pattern%

In layouts, match takes the form of an XML tag:

<match>
<!--%match-pattern%-->
</match>

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, in this example, the dialog will match only when there is exactly one instance of PercentDailyCholesterol:

dialog (Result) {
match: PercentDailyCholesterol (this) {
min (Required) max (One)
from-property: NutritionInformation (source)
}
template ("One portion of #{value(source.food)} will meet #{percent(this)} of your daily needs for cholesterol.")
}

Links

Links allow walking along the branches of the current plan to produce a more elaborate match pattern. This can be useful to craft a more specific match pattern for a particular context, or to bind additional nodes for reuse in the dialog, layout, strategy, etc. We will use the following convention in explaining the different link types below.

%parent-Type%(%parent-Name%) {
%link%: %childType%(%childName%)
}

Examples

This match pattern uses a combination of links to refer to events being booked in the same way as it refers to EventSets.

dialog (Concept) {
match {
viv.event.Event(event) {
from-property: viv.event.EventSet(eventSet)
to-input: viv.event.GetTickets(getTickets)
}
}
template("#{concept(eventSet)}")
}

This strategy suggests a search radius of 25 miles when looking for an airport.

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

match {
viv.geo.SearchRadius {
to-input: viv.geo.PointRadius$build {
to-output: viv.geo.PointRadius {
to-input: viv.geo.BuildPointRadiusSearchRegion {
to-output: viv.geo.SearchRegion {
to-input: viv.air.FindAirport
}
}
}
}
}
}

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

confirming

Signifies what action is being confirmed by the confirmation NodeID defined in this link.

If I'm using viv.core.Confirmation to confirm my TransactionalAction, the match-pattern needs to look like this:

 match: viv.core.Confirmation (this) {
confirming: TransactionalAction (action)
}

The confirmation node must be a Boolean type and it must be used to confirm an action.

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.

Examples

This match pattern will apply whenever we need an input dialog for viv.geo.AdministrativeDivision and that viv.geo.AdministrativeDivision is functioning as an input to the action viv.geoFact.FindPopulation. As a side-effect, our dialog can refer to the contents of division and find.

dialog (Input) {
match: geo.AdministrativeDivision (division) {
to-input: geoFact.FindPopulation (find)
}
...
}

Sometimes actions will have an input-group and you will want to customize the dialog for elicitation events or input events related to that group. Here's an example:

dialog (Elicitation) {
match {
viv.hotel.FindHotelsWithAvailability$constraint-checkOutOrDuration {
to-input: viv.hotel.FindHotelsWithAvailability (action)
}
}

template ("When will you check out?")
}

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

This example sets the Selection dialog asking the user to choose a departure airport in order to search for flights.

dialog (Selection) {
match: viv.air.DepartureAirport(this) {
to-input: viv.flightBooking.SearchFlightAvailability
}
template (From which airport are you departing?)
}

This example shows the summary layout for a ride share produced by the FindRideShare action in order to pass it along to the FindRideShare action.

<layout mode="Summary">
<match>
viv.rideShare.RideShare (this) {
to-input: viv.rideShare.BookRideShare
from-output: viv.rideShare.FindRideShare
}
</match>
<content>
...

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.

Example

This dialog is used to refer to the value of the route's origin as the value of the ride share pickup location.

dialog (Value) {
match {
viv.route.SourcePoint {
to-input: viv.rideShare.FindRideShare (action) {
to-output: viv.rideShare.RideShare (rideShare)
}
}
}
expression("#{value (viv.rideShare.pickupLocation)}")
}

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.

Example

This layout is used to render a ride share differently when it is part of a receipt.

<layout mode="Details">
<match>
viv.rideShare.Activity(this) {
to-property: viv.rideShare.Receipt (receipt)
}
</match>
<content>
...
</content>
</layout>

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.

Example

This strategy is used to disfavor localities that are too far out of range.

selection-strategy {
match {
geo.Locality(this) {
to-property: viv.geo.GeoPoint {
to-role: viv.route.DestinationPoint {
to-input: rideShare.FindRideShare
}
}
}
}
id (reject-out-of-range-localities)
named-advice ("reject") {
advice ("${geoDistance($user.currentLocation, this.centroid, 'Miles')}")
advise-against { lowerBound(100.0) }
}
}

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.

Examples

This allows customizing the confirmation layout before completing a transaction, using elements from the order that are bound by the match pattern.

<layout type="confirmation">
<match>
viv.foodorder.FinalizeOrder (finalize) {
from-input: viv.foodorder.Order (order)
}
</match>
<content>
<layout-macro id="foodorder-order-builder">
<order>{{viv.finalize.order}}</order>
<contact>{{viv.finalize.shippingContact}}</contact>
</layout-macro>
</content>
</layout>

Another example is this result dialog adapted specifically for when users ask if a particular restaurant offers a certain menu item.

dialog (Result) {
match: viv.restaurant.Menu (default) {
from-property: viv.restaurant.Restaurant (menu) {
from-output: viv.restaurant.FindRestaurants {
from-input: viv.food.FoodName (menuItem)
from-input: viv.restaurant.RestaurantName (restaurantName)
}
}
}
template ("Yes, #{value (restaurantName)} has #{value (menuItem)} on their menu, do you want to order one?")
}

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.

Examples

In this example, match: viv.phone.PhoneCallReceipt (this) will match any viv.phone.PhoneCallReceipt in the dialog context. But if you only want this dialog to apply when the phone call receipt is the output from a phone.Call action, we can write a more specific pattern:

match: viv.phone.PhoneCallReceipt (this) {
from-output: viv.phone.Call (call)
}

At the same time this match pattern sets up the rest of the dialog such that call refers to the phone.Call action, and this refers to the phone call receipt. Using this also means that any unprefixed name that is otherwise unknown will be treated as a property of this: timestamp is shorthand for this.timestamp.

dialog (Result) {
match {
viv.flightBooking.FlightBooking (this) {
from-output: viv.flightBooking.CreateFlightBooking {
from-input: viv.flightBooking.RecommendedSeats {
from-output: viv.flightBooking.GetRecommendedSeats (action)
}
}
}
}
...
}

This more involved example threads through the search time for a question back into the response dialog.

dialog (Result) {
// This covers cases where there was a time input, which could refer to
// past, present or future.
match : viv.moon.MoonPhaseJudgement (this) {
from-output: viv.moon.JudgeMoonPhase {
from-input: viv.moon.MoonPhase {
from-output: viv.moon.GetMoonPhase (action) {
from-input: viv.time.Date (when)
}
}
}
}
if (this.judgement) {
template ("Yes, good guess!")
}
else {
template ("No, my lunar calendar shows a #{value(this.moonPhase)} on #{value(when)}")
}
}

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.

Examples

This result-view has a match pattern that uses a wildcard (_), which will tie it to any property of a business. It is useful for defining property projections.

result-view {
match {
_ (this) {
from-property: Business (business)
}
}
...
}

You can even dig several levels deep.

dialog (Concept) {
match {
viv.entity.PhotoInfo (this) {
from-property:viv.hotel.Room (room) {
from-property:viv.hotel.AvailableHotel (hotel)
}
}
}
...
}

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.

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") {
...
}
}
}