Match Expressions and Guards
NeuroScript's match expressions let you route tensors to different processing pipelines based on their shape. Combined with guards (where clauses), you can create adaptive networks that handle varying input sizes optimally.
Basic Match Syntax
in -> match: ->
[pattern]: pipeline -> out
[pattern]: different_pipeline -> out
Each arm has:
- A pattern that matches tensor shapes
- An optional guard (
whereclause) with a condition - A pipeline to execute if the pattern matches
Dimension Binding
Patterns can capture dimensions into variables:
[*, d] # Captures last dimension as 'd'
[*, seq, dim] # Captures last two dimensions
[*batch, d] # Captures batch dimensions as variadic
Captured dimensions can be used in:
- Guard conditions (
where d > 512) - Neuron arguments (
Linear(d, 256))
Adaptive Projection Example
Adaptive Projection
Different processing paths based on input dimension size
This neuron:
- For large inputs (
d > 512): Single projection to 512 - For small inputs (
d <= 512): Two-stage expansion through 256
Click "Show Analysis" to see the match arms and their patterns.
Multi-Tier Compression
Multi-Tier Compression
Four different compression strategies based on input size
This creates four tiers:
- Very large inputs (d > 1024): Two-stage aggressive compression
- Large inputs (d > 512): Two-stage moderate compression
- Medium inputs (d > 128): Single-stage compression
- Small inputs (d <= 128): Pass through unchanged
Pattern Ordering
Match arms are checked in order. More specific patterns should come before general ones:
# Correct ordering: specific to general
[*, 512]: Identity() -> out # Exact match first
[*, d] where d > 512: compress(d) # Guarded pattern
[*, d]: expand(d) # Catch-all last
# Wrong ordering: catch-all shadows others
[*, d]: expand(d) # This catches everything!
[*, 512]: Identity() -> out # Never reached
The compiler will warn you about unreachable arms.
Sequence-Aware Processing
Match on multiple dimensions for sequence models:
Sequence-Aware Encoder
Different processing based on sequence length and dimension
Using Captured Dimensions in Pipelines
Captured dimensions can be used as arguments to neurons in the pipeline:
Dynamic Layer Sizing
Captured dimension 'd' is used in Linear layer arguments
Notice how d appears in Linear(d, 512) and Linear(d, d * 2). The actual values are determined at runtime based on the input shape.
Guards with Multiple Conditions
Guards can use and/or for complex conditions:
[*, d] where d > 256 and d < 1024: medium_path()
[*, seq, d] where seq > 100 or d > 512: large_path()
Try It Yourself
Experiment with match expressions:
- Add new pattern arms with different thresholds
- Try capturing multiple dimensions
- Use captured dimensions in different ways
- Watch for "unreachable arm" warnings when ordering is wrong
- Click "Show Analysis" to see which patterns are reachable