|
1 | | -Integration with miniZinc directory: /src/zinc |
| 1 | +# Integration with FlatZinc |
2 | 2 |
|
3 | | -MiniZinc can export constraint satisfaction problem to FlatZinc format (*.fzn): |
4 | | - - https://docs.minizinc.dev/en/stable/flattening.html |
5 | | - - fzn specification: https://docs.minizinc.dev/en/latest/fzn-spec.html BNF grammar syntax at document end. |
| 3 | +## Overview |
6 | 4 |
|
| 5 | +This document provides a high-level overview of the FlatZinc integration with Selen. Detailed design documents are linked below. |
7 | 6 |
|
8 | | -FlatZinc examples: https://github.com/google/or-tools/tree/stable/examples/flatzinc |
9 | | -Examples explanation: https://www.hakank.org/minizinc/ |
10 | | -Local examples are in /src/zinc/flatzinc |
| 7 | +**Implementation Directory**: `/src/zinc` |
| 8 | + |
| 9 | +**Target Version**: FlatZinc 2.8.x/2.9.x (latest spec) |
| 10 | + |
| 11 | +**Status**: Planning phase |
| 12 | + |
| 13 | +## What is FlatZinc? |
| 14 | + |
| 15 | +MiniZinc can export constraint satisfaction problems to FlatZinc format (*.fzn): |
| 16 | +- **Flattening Process**: https://docs.minizinc.dev/en/stable/flattening.html |
| 17 | +- **FlatZinc Specification**: https://docs.minizinc.dev/en/latest/fzn-spec.html |
| 18 | + - BNF grammar is at the end of the spec document |
| 19 | +- **Latest MiniZinc Release**: 2.9.4 |
| 20 | + |
| 21 | +## Resources |
| 22 | + |
| 23 | +### Examples |
| 24 | +- **Google OR-Tools Examples**: https://github.com/google/or-tools/tree/stable/examples/flatzinc |
| 25 | +- **Håkan Kjellerstrand's Examples**: https://www.hakank.org/minizinc/ |
| 26 | +- **GitHub Repository**: https://github.com/hakank/hakank/tree/master/minizinc |
| 27 | +- **Local Examples**: `/src/zinc/flatzinc` (hidden from git, ~900 examples from small to large) |
| 28 | + |
| 29 | +## Architecture |
| 30 | + |
| 31 | +### High-Level Flow |
| 32 | +1. **Import** `.fzn` model file |
| 33 | +2. **Parse** using tokenizer + recursive-descent parser → AST |
| 34 | +3. **Map** AST to Selen's Model API |
| 35 | +4. **Solve** using Selen's solver |
| 36 | +5. **Output** results in FlatZinc format |
| 37 | + |
| 38 | +### Detailed Design Documents |
| 39 | +- **[ZINC_PARSING.md](ZINC_PARSING.md)** - Parser design, tokenizer, recursive-descent vs hybrid approach |
| 40 | +- **[ZINC_AST.md](ZINC_AST.md)** - AST structure, node types, trait-based design |
| 41 | +- **[ZINC_CONSTRAINTS_GAP.md](ZINC_CONSTRAINTS_GAP.md)** - Constraint audit, gap analysis, implementation priority |
| 42 | +- **[ZINC_MAPPING.md](ZINC_MAPPING.md)** - AST to Selen Model mapping strategy |
| 43 | +- **[ZINC_OUTPUT.md](ZINC_OUTPUT.md)** - FlatZinc output format specification |
| 44 | + |
| 45 | +## Design Decisions |
| 46 | + |
| 47 | +### Versioning Strategy |
| 48 | +- Target FlatZinc 2.8.x/2.9.x specification |
| 49 | +- Parser should detect version (if specified in file) |
| 50 | +- Design for extensibility to support future spec changes |
| 51 | +- **Note**: FlatZinc spec change frequency and change tracking location TBD |
| 52 | + |
| 53 | +### Parser Approach |
| 54 | +- **Tokenizer**: Handle comments, whitespace, line/column tracking |
| 55 | +- **Recursive-Descent**: Top-level statement parsing |
| 56 | +- **Expression Parser**: To be decided (recursive-descent or Pratt for complex precedence) |
| 57 | +- **No external dependencies**: Implement using Rust stdlib only |
| 58 | + |
| 59 | +### Modularity |
| 60 | +- Separate files for: tokenizer, parser, AST, mapper, output formatter |
| 61 | +- Trait-based design: `AstNode`, `MapToModel`, `FlatZincFormatter` |
| 62 | +- Clear boundaries between components |
| 63 | +- Independently testable modules |
| 64 | + |
| 65 | +### Constraint Coverage |
| 66 | +- **Phase 1**: Audit FlatZinc required builtins (Option A) |
| 67 | +- **Phase 2**: Consider full MiniZinc global constraints (Option B) if needed |
| 68 | +- Implement missing critical constraints before integration |
| 69 | +- See [ZINC_CONSTRAINTS_GAP.md](ZINC_CONSTRAINTS_GAP.md) for details |
| 70 | + |
| 71 | +### Output Format |
| 72 | +- Follow FlatZinc solution output specification |
| 73 | +- Support satisfaction status and variable assignments |
| 74 | +- Include solver statistics (optional) |
| 75 | +- Support multiple solutions via function parameter (enumerate_all) |
| 76 | +- No CLI flags for now (library-first approach) |
| 77 | + |
| 78 | +### Error Handling |
| 79 | +- **Fail fast**: Stop on first critical error |
| 80 | +- **Line/column tracking**: Every token and AST node includes location |
| 81 | +- **Clear error messages**: "Expected ';' at line 42, column 15 in constraint declaration" |
| 82 | +- **No external error libraries**: Custom error types using Rust stdlib |
| 83 | + |
| 84 | +### Testing Strategy |
| 85 | +- All tests must pass even if FlatZinc example files are not present |
| 86 | +- Cannot include example `.fzn` files in repo (legal reasons) |
| 87 | +- Test with local examples in `/src/zinc/flatzinc` during development |
| 88 | +- Unit tests for tokenizer, parser, mapper components |
| 89 | +- Integration tests with representative models |
| 90 | + |
| 91 | +### Integration Point |
| 92 | +- Library API (no CLI tool initially) |
| 93 | +- Public functions: `import_flatzinc_file()`, `import_flatzinc_str()` |
| 94 | +- Returns fully constructed Selen `Model` |
| 95 | +- Custom error type: `ZincImportError` |
| 96 | + |
| 97 | +## Implementation Plan |
| 98 | + |
| 99 | +### Phase 1: Analysis & Planning ✓ |
| 100 | +1. ✓ Review FlatZinc specification |
| 101 | +2. ✓ Survey existing parsers (none found in Rust) |
| 102 | +3. ✓ Design API and integration points |
| 103 | +4. ✓ Create detailed design documents |
| 104 | + |
| 105 | +### Phase 2: Constraint Audit (Current Phase) |
| 106 | +1. Extract FlatZinc required builtins from spec |
| 107 | +2. Audit Selen's existing constraints |
| 108 | +3. Identify gaps and prioritize implementation |
| 109 | +4. Implement missing critical constraints |
| 110 | + |
| 111 | +### Phase 3: Parser Implementation |
| 112 | +1. Implement tokenizer with location tracking |
| 113 | +2. Implement recursive-descent parser |
| 114 | +3. Build AST structures |
| 115 | +4. Add comprehensive error handling |
| 116 | +5. Test with simple FlatZinc examples |
| 117 | + |
| 118 | +### Phase 4: Mapping & Solver Integration |
| 119 | +1. Implement AST to Selen Model mapping |
| 120 | +2. Handle variable declarations and arrays |
| 121 | +3. Map constraints to Selen API |
| 122 | +4. Handle solve goals (satisfy, minimize, maximize) |
| 123 | +5. Test with complex FlatZinc examples |
| 124 | + |
| 125 | +### Phase 5: Output Formatting |
| 126 | +1. Implement FlatZinc output formatter |
| 127 | +2. Support all variable types |
| 128 | +3. Handle multiple solutions |
| 129 | +4. Add optional solver statistics |
| 130 | +5. Test output against FlatZinc spec |
| 131 | + |
| 132 | +### Phase 6: Testing & Refinement |
| 133 | +1. Run all ~900 local examples |
| 134 | +2. Fix bugs and edge cases |
| 135 | +3. Optimize performance if needed |
| 136 | +4. Document supported features and limitations |
| 137 | +5. Add examples to demonstrate usage |
| 138 | + |
| 139 | +## Open Questions |
| 140 | + |
| 141 | +### Versioning |
| 142 | +- How frequently does FlatZinc spec change? |
| 143 | +- Where are spec changes tracked/documented? |
| 144 | +- Should we support multiple spec versions simultaneously? |
| 145 | + |
| 146 | +### Constraints |
| 147 | +- Which FlatZinc builtins are most critical? |
| 148 | +- Can we decompose missing global constraints? |
| 149 | +- What's the fallback for unsupported constraints? |
| 150 | + |
| 151 | +### Implementation |
| 152 | +- Should we preserve comments in AST (for round-tripping)? |
| 153 | +- How to handle unknown/unsupported annotations? |
| 154 | +- Do we need incremental parsing for very large files? |
| 155 | + |
| 156 | +### Testing |
| 157 | +- Can we create synthetic minimal examples for CI? |
| 158 | +- How to validate correctness without reference solver? |
| 159 | + |
| 160 | +## Q&A Summary |
| 161 | + |
| 162 | +**Q: What constraints/functionality is missing in Selen for the integration?** |
| 163 | +A: To be determined in Phase 2 (constraint audit). See [ZINC_CONSTRAINTS_GAP.md](ZINC_CONSTRAINTS_GAP.md). |
| 164 | + |
| 165 | +**Q: How to make the implementation modular?** |
| 166 | +A: Separate files for each component (tokenizer, parser, AST, mapper, formatter). Trait-based design for extensibility. See design documents. |
| 167 | + |
| 168 | +**Q: Do we need JSON format?** |
| 169 | +A: No. Focus on FlatZinc text format only. |
| 170 | + |
| 171 | +**Q: Combinator parser or recursive-descent?** |
| 172 | +A: Tokenizer + recursive-descent for statements. Expression parser TBD. See [ZINC_PARSING.md](ZINC_PARSING.md) for detailed comparison. |
| 173 | + |
| 174 | +## Next Steps |
| 175 | + |
| 176 | +1. ✓ Create detailed design documents |
| 177 | +2. **→ Fetch and analyze FlatZinc spec** (extract builtins, BNF grammar) |
| 178 | +3. **→ Audit Selen constraints** (complete gap analysis) |
| 179 | +4. Implement missing critical constraints |
| 180 | +5. Begin parser implementation |
| 181 | + |
| 182 | +## References |
| 183 | + |
| 184 | +- [FlatZinc 2.8.4 Specification](https://docs.minizinc.dev/en/latest/fzn-spec.html) |
| 185 | +- [MiniZinc Documentation](https://docs.minizinc.dev/) |
| 186 | +- [MiniZinc Global Constraints](https://docs.minizinc.dev/en/stable/lib-globals.html) |
11 | 187 |
|
12 | | -1. Import .fzn model. |
13 | | -- Not sure what is the latest spec version? The MiniZinc latest release: 2.9.4 |
14 | 188 |
|
15 | | -2. Create AST. |
16 | 189 |
|
17 | | -3. Map AST to programmable Selen API. |
18 | 190 |
|
19 | | -4. Solve problem. |
20 | 191 |
|
21 | | -5. Output result/error in FlatZinc format |
22 | 192 |
|
0 commit comments