# How the Grammar Model Improves Sentence Prediction in Wanxiang RIME

> The grammar model improves sentence prediction in RIME by using configurable penalties and length constraints to rank plausible continuations higher, enhancing accuracy.

- Repository: [amzxyz/rime_wanxiang](https://github.com/amzxyz/rime_wanxiang)
- Tags: deep-dive
- Published: 2026-02-24

---

**The grammar model improves sentence prediction by applying configurable collocation penalties and length constraints that rank linguistically plausible continuations higher than random character combinations.**

The amzxyz/rime_wanxiang schema implements a sophisticated grammar model that works alongside Rime's prediction engine to deliver context-aware sentence completion. By analyzing token collocations and applying weighted penalties in real time, this system significantly improves sentence prediction accuracy compared to naive statistical methods.

## Architecture of the Grammar Model

### Core Configuration in wanxiang.schema.yaml

The grammar model is declared in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) (lines 103-110) within the `grammar` stanza. This configuration binds the language model `wanxiang-lts-zh-hans` and defines the numeric penalties that adjust candidate scoring.

```yaml

# wanxiang.schema.yaml – grammar configuration

grammar:
  language: wanxiang-lts-zh-hans
  collocation_max_length: 7
  collocation_min_length: 2
  collocation_penalty: -10
  non_collocation_penalty: -20
  weak_collocation_penalty: -35
  rear_penalty: -12

```

### Prediction Activation in default.yaml

Before the grammar model can influence results, the prediction feature must be enabled globally. In [`default.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/default.yaml) (lines 34-38), the `save_options` list includes the `prediction` switch, which instructs Rime to activate its language model for the active schema.

```yaml

# default.yaml – enabling grammar-driven prediction

switcher:
  save_options:
    - prediction

```

### Lua Processor Integration

The [`lua/super_processor.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/super_processor.lua) file (lines 30-73) serves as the bridge between the configuration and the Rime engine. It registers an **update_notifier** that monitors `env.engine.context` and caches the current pre-edit state in `env.seg_last_preedit_lens` whenever the composition changes. This ensures the grammar model always applies penalties using the most recent typing context.

## How the Grammar Model Improves Prediction

### Collocation-Aware Scoring

The grammar model improves sentence prediction by adjusting candidate quality scores based on bigram validity. When Rime generates continuations, it applies **collocation_penalty** (-10) to reward known collocations like "北京 天安门", while penalizing unlikely pairs with **non_collocation_penalty** (-20). For statistically weak bigrams, **weak_collocation_penalty** (-35) provides stronger demotion, preventing awkward phrase suggestions from appearing in the prediction list.

### Length Constraints and Rear Penalties

To prevent the engine from suggesting overly long, low-probability completions, the model enforces **collocation_max_length** (7) and **collocation_min_length** (2) limits. Additionally, **rear_penalty** (-12) specifically targets candidates appearing at the end of long phrases, discouraging unnecessary wordiness while maintaining context relevance.

### Repetition Control

The model works with [`super_processor.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/super_processor.lua) to detect repetitive input patterns. When the same initial exceeds **MAX_REPEAT** (8) limits, the `tail_rep` mechanism blocks candidates, while grammar penalties further demote these repetitions. This prevents cluttered prediction lists when typing sequences like "bbbbb".

### Real-Time Context Synchronization

Every keystroke triggers the update mechanism in [`super_processor.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/super_processor.lua), which extracts the current pre-edit string via `env.engine.context` and updates the grammar-related cache. This real-time synchronization allows the grammar model to evaluate collocation penalties against the actual sentence context rather than isolated character sequences.

## Customizing the Grammar Model

### Implementing Custom Lua Filters

Advanced users can access grammar data programmatically to implement specialized scoring logic. The `env.engine.schema.grammar` object exposes the same penalty values used by the built-in language model.

```lua
-- lua/custom_grammar_filter.lua
local function apply_grammar_penalty(cand, env)
  local score = cand:get_raw_score()
  if env.seg_last_input_caret then
    -- Check if candidate matches recent input context
    local tail = env.seg_last_input_caret:sub(-2)
    if cand.text:find(tail) then
      score = score + env.grammar.collocation_penalty
    else
      score = score + env.grammar.non_collocation_penalty
    end
    cand:set_quality(score)
  end
  return cand
end

return {
  init = function(env) 
    env.grammar = env.engine.schema.grammar 
  end,
  func = function(key, env) 
    return K_NOOP 
  end,
  filter = apply_grammar_penalty,
}

```

### Adjusting Penalty Sensitivity

Modify the values in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) to tune prediction behavior:

- Increase `collocation_penalty` toward 0 to favor common phrases more aggressively
- Decrease `weak_collocation_penalty` (more negative) to filter out unlikely bigrams completely
- Adjust `rear_penalty` to control how strongly the system avoids long-tail completions

## Summary

- The grammar model configuration resides in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) (lines 103-110) and activates via the `prediction` switch in [`default.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/default.yaml) (lines 34-38).
- Four penalty values (**collocation_penalty**, **non_collocation_penalty**, **weak_collocation_penalty**, **rear_penalty**) adjust candidate scoring to favor natural language patterns over random character combinations.
- Length constraints (**collocation_max_length**, **collocation_min_length**) limit the context window to statistically reliable spans between 2 and 7 tokens.
- The [`lua/super_processor.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/lua/super_processor.lua) update notifier (lines 30-73) maintains real-time synchronization between user input and grammar evaluation via `env.seg_last_preedit_lens`.
- Custom Lua filters can programmatically access `env.engine.schema.grammar` to implement domain-specific scoring logic while respecting the core penalty structure.

## Frequently Asked Questions

### How do I enable the grammar model to improve sentence prediction?

Enable the `prediction` option in [`default.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/default.yaml) under `switcher.save_options`. This activates Rime's language model, which automatically reads the grammar configuration from [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) and applies collocation penalties during candidate ranking to produce more natural sentence completions.

### What do the negative penalty values mean in the grammar configuration?

Negative values represent score adjustments in Rime's candidate ranking system. Lower (more negative) scores push candidates down the list, while higher (less negative) scores lift them up. The **collocation_penalty** (-10) is the least severe and rewards valid pairs, while **weak_collocation_penalty** (-35) aggressively demotes unlikely bigrams that would break sentence flow.

### Can I adjust the grammar model to allow longer phrase predictions?

Yes. Modify **collocation_max_length** in [`wanxiang.schema.yaml`](https://github.com/amzxyz/rime_wanxiang/blob/main/wanxiang.schema.yaml) to increase the token span considered for collocation scoring beyond the default 7 tokens. However, longer windows may reduce prediction accuracy if statistical data becomes sparse for rare bigrams, potentially introducing less reliable suggestions.

### How does the grammar model prevent repetitive character predictions?

The model collaborates with [`super_processor.lua`](https://github.com/amzxyz/rime_wanxiang/blob/main/super_processor.lua) to enforce **MAX_REPEAT** (8) limits through the `tail_rep` mechanism, which blocks candidates when identical initials exceed the threshold. Grammar penalties then further demote these repetitive candidates, ensuring the prediction list favors diverse, contextually appropriate vocabulary instead of redundant character sequences.