pub struct Problem<P: PieceKind, C: ColorKind = SquareColor> {
pub num_squares: usize,
pub square_colors: Vec<C>,
pub pieces: Vec<P>,
pub constraint: Constraint<P, C>,
}Expand description
A constraint-satisfaction problem: a fixed board (size + per-square colour from a user-defined colour set), an alphabet of available piece kinds, and a constraint to satisfy.
pieces is the alphabet — the set of distinct kinds available.
Duplicate entries are silently deduplicated; first-appearance order
is preserved.
C is the colour kind. The default is SquareColor — the
binary light/dark partition used by chess. For N-way partitions
define your own enum and use it as the C type parameter.
square_colors must either be empty (no colour partition
declared; colour-keyed constraints always see zero matches) or
have length exactly num_squares. Call validate
to check this and that every constraint references only declared
pieces, colours, and squares.
Solve by calling Problem::count for the population size or
Problem::iter to stream all satisfying arrangements.
If pieces is empty or num_squares == 0, the problem has no
arrangements to enumerate and count() returns 0.
Fields§
§num_squares: usizeNumber of squares (e.g. 8 for a chess back rank).
square_colors: Vec<C>Colour of each square. square_colors.len() == num_squares.
pieces: Vec<P>Alphabet of available piece kinds. Duplicates are silently
deduped by the solver; size doesn’t have to equal
num_squares.
constraint: Constraint<P, C>Root constraint. Use Constraint::And for conjunctions.
Implementations§
Source§impl<P: PieceKind, C: ColorKind> Problem<P, C>
impl<P: PieceKind, C: ColorKind> Problem<P, C>
Sourcepub fn validate(&self) -> Result<(), ValidationError>
pub fn validate(&self) -> Result<(), ValidationError>
Checks self is internally consistent and returns a
ValidationError if not.
Specifically:
square_colorsis either empty ornum_squareslong.- Every piece referenced by a constraint is in
self.pieces. - Every colour referenced by a
CountOnColoris inself.square_colors. An emptysquare_colorsis valid only for problems that have noCountOnColorconstraints; otherwise the colour reference is treated as unknown. - Every
At/NotAtsquare index is< num_squares. - Every
Order/Relativeinstance index is< declared countfor that piece (only checked when the piece has aConstraint::Count { Eq, n }constraint declaring its count).
count() / iter() / sample() do not auto-validate; if
you need correctness up front, call this first or use
ProblemBuilder::try_build.
Sourcepub fn builder() -> ProblemBuilder<P, C>
pub fn builder() -> ProblemBuilder<P, C>
Returns a fresh empty ProblemBuilder for fluent
construction.
use chess_startpos_rs::{chess, Constraint, CountOp, Problem, SquareColor};
let problem: Problem<chess::Piece> = Problem::builder()
.squares(8)
.alternating_colors(SquareColor::Dark, SquareColor::Light)
.pieces([chess::Piece::King, chess::Piece::Queen])
.constraint(Constraint::Count {
piece: chess::Piece::King,
op: CountOp::Eq,
value: 1,
})
.constraint(Constraint::Count {
piece: chess::Piece::Queen,
op: CountOp::Eq,
value: 7,
})
.build();
assert_eq!(problem.count(), 8); // 1 king × 8 placements over 7 queensThe struct-literal API (Problem is a regular public-fields
struct) remains a fully supported alternative.
Sourcepub fn iter(&self) -> impl Iterator<Item = Vec<P>> + '_
pub fn iter(&self) -> impl Iterator<Item = Vec<P>> + '_
Streams all distinct arrangements satisfying the constraint in canonical lexicographic order.
Sourcepub fn at(&self, index: u64) -> Option<Vec<P>>
pub fn at(&self, index: u64) -> Option<Vec<P>>
Returns the index-th satisfying arrangement in canonical
lexicographic order, or None if index >= self.count().
Equivalent to self.iter().nth(index) with u64 indexing.
O(index) — for repeated indexed lookup prefer iterating once.
Sourcepub fn sample(&self, seed: u64) -> Option<Vec<P>>
pub fn sample(&self, seed: u64) -> Option<Vec<P>>
Returns a uniformly-random arrangement satisfying the
constraint, deterministic in seed. None if the constraint
is unsatisfiable.
Single pass over self.iter() using reservoir-of-size-1
sampling: each satisfying arrangement is selected with
probability 1 / k where k is its 1-based index in the
iterator. The result is uniformly random over the satisfying
arrangements without materialising them all.
Sourcepub fn with_constraint(&self, c: Constraint<P, C>) -> Self
pub fn with_constraint(&self, c: Constraint<P, C>) -> Self
Returns a copy of self with c added via AND-composition.