Skip to content

Commit 8448598

Browse files
authored
Merge pull request #21 from radevgit/zinc_phase1
Zinc phase1
2 parents 436722c + cf91a5c commit 8448598

22 files changed

+6617
-19
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.8.5] - 2025-10-01
6+
- Implemented reified constraint.
7+
58
## [0.8.4] - 2025-09-27
69
- Fixed some outdated examples
710

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "selen"
3-
version = "0.8.4"
3+
version = "0.8.5"
44
edition = "2024"
55
description = "Constraint Satisfaction Problem (CSP) solver"
66
rust-version = "1.88"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Add this to your `Cargo.toml`:
5151

5252
```toml
5353
[dependencies]
54-
selen = "0.8.4"
54+
selen = "0.8.5"
5555
```
5656

5757
```

docs/development/ZINC.md

Lines changed: 183 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,192 @@
1-
Integration with miniZinc directory: /src/zinc
1+
# Integration with FlatZinc
22

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
64

5+
This document provides a high-level overview of the FlatZinc integration with Selen. Detailed design documents are linked below.
76

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)
11187

12-
1. Import .fzn model.
13-
- Not sure what is the latest spec version? The MiniZinc latest release: 2.9.4
14188

15-
2. Create AST.
16189

17-
3. Map AST to programmable Selen API.
18190

19-
4. Solve problem.
20191

21-
5. Output result/error in FlatZinc format
22192

0 commit comments

Comments
 (0)