Sudoku is a downloadable MDriven Designer example for developers who want to study how a model of types, relationships, derived values, and rules can validate a grid without imperative validation code.
What this example demonstrates
The Sudoku model uses the familiar number-placement problem to make rule-based modeling visible. You define the facts and constraints that make a board valid; when a cell changes, dependent expressions are re-evaluated and the user interface reflects the current state.
The example demonstrates:
- A board made up of cells and digit values.
- Digits limited to the values 1 through 9.
- Rule evaluation across related cells, including row, column, and group checks.
- A derived, settable value that lets a user enter a number while the model stores the corresponding digit object.
- Styling driven by rule results: invalid cells can receive a problem style, and grid boundaries can receive line styles.
- A generated UI that reacts to the model. The walkthrough shows this behavior without manually triggering UI updates.
For example, when you enter a digit that conflicts with the rules, the affected cells are marked as problematic. The model does not need a separate procedure that finds and repaints every affected cell; the styles are based on evaluated expressions and therefore react when the board facts change.
Download the model
Download the example model: Sudoko2022.modlr.
After you open the model in MDriven Designer, inspect the board, cell, and digit types first. Then inspect the derived values, constraints, and styles that use those types. This order makes it easier to connect a rule with the visible behavior in the generated UI.
Explore the model
Use the following sequence to understand the example.
- Open the model and locate the types that represent the board, its cells, and the allowed digit values.
- Find the cell value used in the grid. The example represents the allowed values as digit objects rather than storing the displayed number alone.
- Inspect the derived, settable input value. Its derived expression returns blank when the cell has no value; otherwise it returns the integer value of the selected digit.
- Inspect its set expression in the Actions Editor. The expression finds the digit whose integer value matches the entered value, takes the single matching object, and assigns it to the cell's value link.
- Inspect the expressions that determine whether a cell or board is valid. Check how they navigate from one cell to the related cells that must not contain the same digit.
- Inspect the styles applied to the grid cells. A problem style is used when a rule evaluates to a problem, while row and column styles provide the heavier visual boundaries between groups.
- Run the generated UI and enter a conflicting number. Observe that the relevant problem styles update as the rule results change.
How entered values are mapped
The generated UI can display an integer editor for the cell because the model exposes a derived, settable integer value. The stored model value remains a digit object.
| User action | Derived/settable behavior | Result |
|---|---|---|
| The cell has no digit | The derived value returns null. | The UI renders the cell as blank. |
The cell contains a digit whose integer value is 7
|
The derived value returns the digit's integer value. | The UI displays 7.
|
The user enters 7
|
The set expression selects the digit with integer value 7 and assigns that digit to the cell.
|
Rules and styles re-evaluate against the new cell value. |
This pattern is useful when your domain model uses value objects or related objects, but users need to edit a compact scalar value. Review Data transformation for related transformation concepts and Column.Texttype when configuring how values are presented in columns.
Rule evaluation and feedback
Sudoku is a useful constraint example because rule order is not the point: the board is acceptable only when all applicable rules are satisfied. Expressions can therefore state what must be true rather than prescribe a sequence of validation steps.
A rule can evaluate the current cell against the other cells in its row, column, or group. If a duplicate digit makes the rule fail, the corresponding expression yields a problem result used by the problem style. When you correct the value, the same expressions are evaluated again and the problem indication is removed when the constraints are satisfied.
The row and column boundary styling is decorative but follows the same model-driven approach. Expressions determine whether a cell sits at a group boundary, and the resulting style draws the heavier line. The UI behavior is therefore derived from model facts, not maintained through manual UI event handling.
Debug expressions in the example
When an expression returns an unexpected result, use the OCL debug stepper demonstrated in the walkthrough. Step into a derived expression to inspect intermediate values and navigation.
For example, the cell key derivation shown in the walkthrough constructs a coordinate string from x and y, such as 1,2. Stepping through the expression reveals each conversion and concatenation. This is useful when a rule appears wrong because a coordinate or collection contains a value you did not expect.
Use the stepper to verify:
- The cell currently being evaluated.
- The related cells selected by a row, column, or group expression.
- The digit value being compared.
- Whether a collection is reduced to one object before assignment. In the input mapping, the selected digit is reduced with a first-object operation before it is assigned.
The walkthrough also shows the Parse operator in the wider discussion of expression evaluation.
About solving and creating puzzles
The example can continue by selecting values for cells that have only one possible number under the current constraints. This is distinct from validating a completed board.
A playable puzzle also needs a unique solution. A board with too few given values can have multiple valid solutions, while another set of given values can make the board impossible. The walkthrough describes a practical generation approach: start with a fully solved board, remove values, and check after each removal that the remaining puzzle still has only one solution. The supplied model is best used as a rule and UI example; verify uniqueness separately when you create puzzle content.
Watch the walkthrough
Watch the OCL Debug Stepper and Sudoku walkthrough to see the generated grid, reactive problem styling, derived/settable input value, and expression debugging.
