The solver
The techniques, moves, pricing parameters and the Solver class. Generated from the comments in the headers by Doxygen and tools/gen_cpp_reference.py; public members only.
solver.hpp
Two-phase logical solver: technique ids, moves, pricing parameters and the Solver class (solver.cpp and the technique files).
struct Cover
Fields
kindintshapedoubleuint
struct Move
One move: the feature tuple (tech, base_shape, cover, extra, meta) plus placement / eliminations.
cover and elims live in the owning buffer.
Fields
techintshapedoublecov_offintcov_nintextrainthas_metaboolmetaint[8] — cells groups digits links hidden arith relation notesspreaddoublemeta_synthbool — meta[] filled by describe() for export only (the technique is priced by B)has_descbool — desc[] is filleddescdouble[8] — structural descriptors (desc.cpp): log branches, log depth, search, uniqueness, counting, contradiction, held, coverage exported, not pricedscandouble —desc.cpp: patterns of this kind a human scans at the state (raw count behind desc[2])enumvdouble — log1p(max consistent assignments of the SUM rule instances the move touches)pcintpvint — placementel_offintel_nintnkintnaintnbint — nb: second group / cage (-1 = none)ddoublexmpm_long[XM_N]codeinttab_livepm_long — table-backed move: live tuples of the justifying table (case-analysis burden)pat_offintpat_nint — pattern cells (cells justifying the move) inMoveBuf::patsloadfloat[8] — cognitive loads (human mode), seeSolver::cog_loads; LOAD_N entrieshas_loadboolex_offintex_nint — explanation records inMoveBuf::ex: [tag, len, data...]...
struct MoveBuf
| Name | What it does |
|---|---|
clear |
Fields
movesstd::vector< Move >coversstd::vector< Cover >elimsstd::vector< uint32_t > — c*32 + vpatsstd::vector< int > — pattern cellsexstd::vector< int > — explanation records
void clear()
No comment.
struct Params
| Name | What it does |
|---|---|
size | board-size factor ((D - 1) / 8)^alpha scaling the prices |
difficulty | price of a move: the technique's base cost with shape, size and covers (or the structural meta model) |
Fields
Bdouble[N_TECH]Kstd::vector< double >gammadoublealphadoublethetastd::vector< double > — meta_theta (empty = per-technique B path)theta_fullstd::vector< double > — params meta_theta_full: 18-19 weights pricing every technique (empty = off)localitydouble — params locality: route choice by price x exp(locality x log2(1 + distance to the previous step)); 0 = offtheta_enumdouble — params meta_theta_enum (D5): weight onMove::enumvinside the meta_theta_full pricetech_obscstd::vector< double > — params tech_obscurity: per-technique log-price offset = cultural familiarity / obscurity (a property of the technique, measured from human outcomes); indexed by tech codetheta_interactstd::vector< double > — params meta_theta_interact 3 weights on log depth x log cells, log depth x links, log depth x log branches (added to the meta_theta_full sum)has_thetabooltheta_acdoubleguess_kdouble — guessing / trial prices: Guess d = B[Guess] * size * (1 + guess_k * expected refutation work); a wrong candidate that survives basic propagation costs its steps + guess_deep * empty cells; Trial / ShortTrial d *= 1 + trial_k * (rounds - 1)trial_kdoublecolour_chain_kdouble — ColourAlgebra chain multiplier (0 = off)k_tabdoublesnyderbool — params notes_mode = "snyder": Snyder marks before full candidatessnyder_maxint — params snyder_max: Snyder marks for digits confined to <= 2 (default) or <= 3 cells of a boxcase_lightint — params case_light: CaseAnalysis cases also run light techniques (intersections, pairs)case_roundsintcase_candsint — params case_rounds (default 0 = off until a refit prices descriptors; 3 = on), case_candsdc_linesbool — params dc_lines: DigitCount uses line rules' must-contain digitsmental_floorbool — params mental_floor: mental moves priced >= their written counterparttheta_full_v2bool — params theta_full_v2: meta_theta_full uses log1p(links); the mental floor's written counterpart also sets coverage (desc[7]) = 1notes_lazybool — params notes_lazy: candidates are written only for the cells a notes step usessets_firstbool — params route = "sets_first": chains / ALS tiers after the set-arithmetic tiersband_budgetpm_long — BandLogic node budget per state (0 = off)band_kdouble — BandLogic: d *= 1 + band_k * log(cases) (refutation case count / search nodes)ri_budgetpm_long — RuleIntersection node budget per state (0 = off) // table moves: d *= 1 + k_tab * log(live tuples)guess_deepint — meta interaction: arith x log(cells) (params "meta_theta_arith_cells")meta_max_techint — meta-theta applies to technique codes below this (params "meta_max_tech")meta_exclbool[N_TECH] — ... and not to these codes (params "meta_exclude": B pricing)tech_offsetdouble[N_TECH] — optional: meta-path difficulty *= exp(offset[tech])has_offsetbool[N_TECH]humanbool — human mode (params["human_mode"]): every family competes in the race (no tier gating within the direct / notes phase); difficulty *= exp(sum_j k_j * max(0, load_j - budget_j))cap_powdouble — 0: beyond the cap d = cap + (d - cap)^cap_pow (steeper than log1p; 1 = uncapped)cap_taudouble — soft guess cap: d > cap -> cap + tau * log1p((d - cap) / tau); 0 = hard caphbudgetdouble[8]hkdouble[8]fc_levelint — forcing chains: highest level searched by the solver (-1 off, 0 static, 1 dynamic, 2 nested), last notes tier usable inside branches, max options per level; price d *= exp(fc_depth * level) * k^fc_branch * (1 + log1p(propagation steps))fc_ceilingintband_escalateintband_escalate_maxintband_wide_factorint — params band_wide_factor: wide-region pass budget = this x band_budgetcolour_partialint — params colour_partial: partial structural colouring when the symbol puzzle is not uniqueband_outiesint — params band_outies: derived house sums may subtract pieces' outie cellsband_wide_rulesint — params band_wide_rules: largest subset of sticking-out rules per wide region (2 or 3)band_wide_maxint — params band_wide_max: at most this many wide regions (the smallest)band_wide_cellsint — params band_wide_cells: escalation regions with rules taken whole, <= this many cells (0 = off) // params band_escalate (budget factor, <= 1 = off), band_escalate_max (per solve)fc_fallbackpm_long — params forcing_fallback: work budget (branch steps per solve; default 5e4) for dynamic / nestedrefute_roundsint — forcing tried when a step would otherwise guess (0 = off) params refute_rounds: 1 = refute_profile counts propagation rounds (all singles of a round placed together: independent of cell order), 0 = placements (experiment, B1c)fish_max_nint — params fish_max_n: largest finned fish listed (the band path lists Medium with 2: larger finned fish are Hard, so they can't be picked there)exhaust_fallbackint — params exhaust_fallback: 1 = where a step would guess (GUESS disabled), refute one candidate by full search instead (tech TRIAL, 'Trial and error', band Extreme)fc_fallback_sdouble — params forcing_fallback_s: wall-time safety per solve (checked between calls; the deterministic work budget is meant to bind first)fc_kmaxint[3]fc_depthdoublefc_branchdoublegurthbool — Gurth's symmetry theorem (coordinate symmetries: not transform-invariant)fc_workdouble — budget: branches x (cells + 8 x rules); above it a level is skipped
double size(int D) const
board-size factor ((D - 1) / 8)^alpha scaling the prices
double difficulty(const Move &m, const Cover *covers, int D) const
price of a move: the technique's base cost with shape, size and covers (or the structural meta model)
struct StepRec
Fields
alt_offintalt_nintchosenintmodeint — 0 direct, 1 notesn_emptyinterasuresintnotes_writtenintn_candspm_long — candidates left in the empty cells before the step (engine view; Andrew Stuart's C)moveMove — cov/el offsets index intoSolveResultpools
struct SolveResult
Fields
stepsstd::vector< StepRec >altsstd::vector< Move > — features only (cov offsets into covers)coversstd::vector< Cover >elimsstd::vector< uint32_t >solvedboolpatsstd::vector< int >exstd::vector< int > — pattern cells / explanation records of the chosen movesstatsstd::map< std::string, Stat > —SolveOptions::stats: per strategy / direct stage.
struct SolveResult::Stat
Fields
msdoublecallspm_longhitspm_long
struct Strategy
Strategy interface: a strategy appends every instance it finds to the move buffer.
Tiers group strategies; the first tier yielding a move wins and the minimum-difficulty move of that tier is applied. New generic strategies (fish over arbitrary AllDiff families, AIC over a link graph, ALS, sum constraints...) plug in here without touching the solve loop.
| Name | What it does |
|---|---|
~Strategy | |
name | |
collect |
~Strategy()=default
No comment.
const char * name() const =0
No comment.
void collect(Solver &s, MoveBuf &out)=0
No comment.
struct Flags
the disabled techniques.
While a strategy's moves are listed for the listing cache (state_moves), every flag the strategy reads is recorded, so its cached moves are reused only where those flags are the same (listing_cache.cpp)
| Name | What it does |
|---|---|
assign | resets to n flags, all x |
size | number of flags |
operator[] | |
set |
Fields
vstd::vector< char >recstd::vector< char > *
void assign(size_t n, char x)
resets to n flags, all x
size_t size() const
number of flags
char operator[](size_t i) const
No comment.
void set(size_t i, char x)
No comment.
struct SolveOptions
Fields
max_stepsintallow_directbooldisabledstd::vector< int >skipstd::vector< int > — techniques whose strategies are not run in the notes tiers (state_moves(skip=...)): unlike disabled, the flags every other strategy reads stay as they are, so the moves listed are exactly the full listing's minus theirssolutionstd::vector< int > — empty = brute force for Guessassume_uniquebool — allow uniqueness techniques (UR, BUG+1)all_tiersbool — emit the moves of every technique family at each state (audit)all_tiers_capint — ... at most this many per technique (cheapest first; 0 = all)explainbool — add state-dependent explanation records to the chosen movesstatsbool — per-strategy time / calls / hits (SolveResult::stats)prune_tiersbool — skip a tier's expensive case-split strategies when a move found earlier in the tier is already cheaper than anything they can price at (same chosen move; fewer alternatives). Off for featurize. off by default: it drops priced alternatives (predict_time sums over them)coloursstd::vector< int > — human colouring (cell -> colour id, -1 none): a colour = "same digit" hypothesis seeding ColourAlgebra; with a solution it is used only where consistent with it, otherwise it is soft (moves flagged)
class Solver
| Name | What it does |
|---|---|
Solver | |
solve | solves from the givens, one human step at a time, recording the steps and alternatives in out |
collect_strategy | s->collect, through the listing cache when lcache is set |
direct_moves | mental: 0 off, 2 relations/lines, 3 + subsets |
direct_locks | fills lock tables; returns "locks" truthiness |
innies | rule-of-45 regions: the last cell of an innie / outie (no notes), or candidates the region sum rules out… |
notes_singles | naked and hidden singles over the notes; one move per placement |
locked | pointing and claiming: a digit confined to a line (or box) inside a house leaves the rest of that line (box) |
cage_combo | sum-cage combinations: candidates no combination of the cage allows are eliminated |
pairarc | arc consistency over relation pairs (kropki, difference ...): drops candidates without a partner |
relation_pointing | a digit confined to cells of a house that all relate to one cell: it loses what the relation forbids |
subsets | naked and hidden subsets of size k (pairs, triples, quads) in houses; adds the eliminations |
fish | basic fish of size k (2 X-Wing, 3 Swordfish) over houses; adds the eliminations |
xywing | XY-Wing (XYZ-Wing when xyz): pivot with two wings; adds the digit eliminated from cells seeing the wings. |
coloring | simple colouring of one digit's conjugate-pair chains: colour wraps and traps; adds the eliminations |
trial | bivalue cell whose candidate breaks under basic propagation (trial and error); eliminates that candidate |
guess | last resort: places the solution digit of the cell with fewest candidates, priced as the human cost of… |
exhaust | where guessing is off: refutes one wrong candidate by full search (recorded as Trial and error) |
nary_combination | n-ary constraints |
combo_lock | n-ary combination locks: a digit in every consistent assignment, or forced into a rule by a house |
nary_direct | no-notes read of a rule with one empty cell whose digit the arithmetic / set rule forces |
innie_sum | consistency over rule-of-45 regions too big for the innie/outie sets, as derived sum constraints |
compute_mental | builds the no-notes mental view (digits each cell can hold, relation / line bounds, mental subsets) up to… |
gfish | generalized fish (any complete groups as base/cover sets): size n, finless (Jellyfish; X-Wing/Swordfish stay… |
aic | alternating inference chains over the generic link graph, chain length (links) in [lo, hi]; includes… |
unique_rect | uniqueness (only with opt.assume_unique) |
bug_plus1 | BUG+1: one tri-value cell in an otherwise bivalue grid takes the digit that is odd in its houses. |
rule_intersect | two rules / houses taken together: digit combinations over their joint cells; adds the eliminations |
sum_algebra | interval algebra over house totals, cages and segments in a band or stack; adds the eliminations |
band_logic | a band's lines, boxes and rules taken together as a sub-puzzle; eliminations that hold in all its fillings |
describe | structural descriptors (desc.cpp) |
written_marks | candidates of c that are written down |
desc_stats | refreshes the per-state statistics (candidate counts, bivalue cells ...) used by the move descriptors |
struct_colours | structural colouring (symbol per cell, empty = none), computed once per solve |
colour_disambiguate | every colour is one digit: digits no consistent permutation gives a colour leave its cells |
bug_plus2 | BUG+2: tri-value cells T1, T2 in an otherwise bivalue grid; eliminates what all surviving cases share. |
extended_ur | extended unique rectangle (2 rows x 3 boxes, six cells): the sixth cell cannot take x, y or z |
als_xz | almost locked sets over any AllDiff group |
als_xywing | ALS-XY-Wing: pivot ALS linked by restricted commons to two wing ALS; adds the common-digit eliminations. |
death_blossom | death blossom: a stem cell whose every candidate has an ALS petal; adds the digit all petals share |
als_aic | alternating inference chains through almost locked sets, up to hi links; adds eliminations and placements |
short_trial | bounded case split (human "what if"): returns rounds to contradiction, 0 = none |
human_case | bounded human case analysis (refutation, cell and house forcing within a few rule rounds) |
combo_positions | cage combinations cap how many of a digit set the cage holds in a house; the rest lies outside it |
clique_house | cells that pairwise differ (knight's move, relations) treated as a virtual house: naked sets and singles |
line_sets | renban-type lines meeting a house use disjoint digit sets there; digits no joint choice allows leave |
line_clues | a line with two or more outside clues (sandwich, x-sum, skyscraper) enumerated as one unit |
weighted_sums | integer combinations of sum facts down to 1-3 weighted cells, which are enumerated |
mental_chains | short chains (<= 5 links) on the no-notes mental view, paying off as a single |
case_split | |
prop_rounds | basic propagation in place for up to max_rounds rounds; returns the round of the first contradiction (0 =… |
explain_chosen | explanation records of the chosen move that need the solver state (singles' reasons, trial branches);… |
either_way | both options of a two-way choice followed a few rounds; what both agree on holds (direct_view: placements… |
line_classes | arc consistency on digit classes (low / high, odd / even) along lines; removes whole classes |
digit_count | a digit counted over k base units and k cover units: exactly k copies, so it leaves the covers' other cells |
equal_digits | two cells forced to hold the same unknown digit (abstract colouring): each keeps the other's candidates |
line_scan | local scan of a long line: consistency over each window of 3 consecutive cells |
medusa | 3D Medusa: colouring over strong links of several digits; wraps and traps give eliminations |
multi_colouring | multi-colouring: two single-digit colour clusters interacting; adds the eliminations |
colour_algebra | cells that share an unknown digit (colour classes) combined with the rules; direct_view: on the mental view |
label_shadow | cells carrying the same unknown digit label (a permutation of digits) restrict each other's candidates |
table_live | number of rows of a table constraint consistent with the placed digits and candidates |
n_wing | WXYZ / VWXYZ wings (bent sets): the digit Z leaves cells seeing every Z of the set. |
sue_de_coq | Sue de Coq: a box-line intersection with a line set and a box set covering its digits exactly; adds… |
aligned_pair | aligned pair exclusion: value pairs of two cells that would empty a common peer; adds the leftovers |
fireworks | Fireworks: three digits confined to three cells (corner, one in its row, one in its column); others go. |
chute_remote_pairs | remote pairs along a chute (band / stack) with the same bivalue pair; adds the eliminations |
pattern_overlay | pattern overlay: per-digit templates over the rows; candidates in no template (or all) are eliminated (placed) |
gurth | Gurth's symmetrical placement: a grid symmetry forces digits (uniqueness; opt-in by params) |
sum_bound | min / max (triangular number) bounds of sums, cages and arrows; eliminates digits beyond the bounds |
class_count | odd / even (and thirds) counting in houses and sum parity; eliminates digits of a full class |
class_colour | class colouring: low / high or odd / even links between cells, sides fixed by known cells or house counts |
clue_facts | facts read off the clues alone (relations on an empty grid; with line shape): fires once as one step |
domino | relation dominoes: a digit every allowed pair uses leaves common houses; two dominoes locking four digits |
forcing | forcing chains (forcing.cpp) |
nishio | Nishio: follows one digit from an assumed cell; a house left without a place refutes the assumption. |
what_if | human "what if": a two-way choice followed with light logic; what both cases agree on holds |
mental_notes | notes logic done in the head on the no-notes view (rule combinations, intersections, pairs): a single |
fallback_open | true while the forcing fallback has work budget left (boards up to 9x9) |
forcing_fallback | last resort before a guess: band logic with a larger budget, then dynamic / nested forcing; true if moves… |
fc_propagate | propagates the hypothetical state at level; returns 0 or 1 + the iteration of the first contradiction |
fc_branch | |
gac_prop | nary_moves.cpp |
pspread | structural spread of a cell pattern: complete groups touched / (2 sqrt(n) + 1) (canonical; invariant under… |
compute_labels | refreshes the invariant cell labels (colour refinement) for the current state |
node_label | invariant label of candidate v at cell c, from the labels of the cells that share its houses |
canon_dedupe | keeps the cheapest move per placement and per (technique, elimination set) |
place | places v at c, clearing it from the peers; returns the number of candidates erased |
grid_valid | true if every cell is filled legally and every rule holds |
state_moves | every move available at the current state (direct and notes families; tiers ungated), priced; at most… |
init_state | resets the state to the givens (all candidates, then the givens placed) |
refute_profile | generic refutation profile (refute.cpp): technique-free difficulty |
basic_propagate | basic propagation to a fixpoint (singles, relations, rule consistency); false on contradiction |
trial_depth | placements until a contradiction, -1 if none within cap |
k_prepare | precomputes the houses and their overlaps the knowledge ladder uses |
k_step | -1 contradiction, 0 nothing, 1 progress |
pick_puzzle | the puzzle actually solved: p.implied (derived houses, leftovers) unless IMPLIED is disabled |
Fields
pconst Puzzle &Pconst Params &optSolveOptionsdisabledFlagsany_disabledboolskippedstd::vector< char > — opt.skip as flagslcachebool — state_moves: notes-tier strategies go through the listing cachelcache_paramsuint64_t — hash of the params the listing was asked with (part of the cache key)lcache_solvebool — the listing cache is used insidesolve()(the direct blocks bypass it there)valsstd::vector< uint8_t >candstd::vector< uint32_t >placed_gstd::vector< uint32_t >is_givenstd::vector< char > — cell was a given (avoidable rectangles)mex_relstd::vector< uint32_t > — relation arc consistency over house-restricted digits, inequality bounds (chains / mutually distinct predecessors), line consistency; then mental naked subsets (size 2-3). Exclusions beyond the house view: mex_rel / mex_ment.mex_mentstd::vector< uint32_t >mdstd::vector< uint32_t >rs_typestd::vector< uint8_t >rs_depthstd::vector< uint8_t >rs_sizestd::vector< uint8_t > — per cell*32+digitrs_linestd::vector< int16_t >mental_versionpm_longmental_levelintwritten_overridestd::vector< uint32_t >cand_overridestd::vector< uint32_t > — state_moves(cand=...): per cell, the candidates still open at this state // state_moves(written=...): per cell, the candidates written downdesc_modeint — notation context ofdescribe(): 0 no notes written, 1 notes, -1 unknown (state_moves: by technique)ds_versionpm_longds_validboolds_candsintds_bivalueintds_emptyintds_interintds_openstd::vector< int >ds_linesstd::vector< int >ds_subsetsdouble[5]struct_clsstd::vector< int > — structural colouring (struct_colours): symbol per cell, empty = nonestruct_doneboolband_regionsstd::vector< BandRegion >band_builtboolband_regions_widestd::vector< BandRegion > — escalation-only regions (rules taken whole)band_built_wideboolmarkedstd::vector< char > — notes_lazy: cells whose candidates have been writtenband_wide_nowbool — escalation pass over the wide regionsband_budget_nowpm_long — 0: band_logic runs once with this budget (fallback escalation)band_escalationsint — escalations used in this solveband_totalpm_long — all BandLogic search nodes in this solve (hard bound 32 x band_budget)band_spentpm_long — search nodes used by BandLogic in this solve (fruitless calls, capped at 8 x band_budget)band_cachestd::map< std::vector< uint32_t >, std::vector< std::array< pm_long, 3 > > > — exact: (region, region state) -> eliminations (cell*32+digit) with their refutation level / casesband_solsstd::vector< std::vector< std::vector< uint8_t > > > — per region: fillings found (region cells), reused as supportsband_cache_widestd::map< std::vector< uint32_t >, std::vector< std::array< pm_long, 3 > > >band_sols_widestd::vector< std::vector< std::vector< uint8_t > > >ri_cachestd::map< std::vector< uint32_t >, std::pair< std::vector< uint32_t >, pm_long > > — exact: (pair, union state) -> elims, nodesfc_ceiling_nowintfc_kmax_nowintfc_tech_nowintfc_step_capintfc_viewintfc_level_nowint — forcing fallback: level allowed for this call (overrides params forcing_level)fc_steps_totalpm_long — branch propagation steps offorcing()calls (fallback work budget)fc_abort_atpm_long —forcing()gives up (fc_aborted) once fc_steps_total passes this (-1 = never)fc_abortedboolfb_spentpm_long — fallback work used in this solvefb_secsdouble — fallback wall time used in this solve (safety only, checked between calls)versionpm_long — bumped whenever the state changes (chain cache key)split_memostd::unordered_map< uint64_t, SplitMemo > — case_split results by exact state + assumptionprop_gacstd::unordered_map< const void *, PropGac > — prop_rounds: last consistency result per ruledc_cachestd::vector< DcCache > — DigitCount results per digit, keyed on the digit plane + base units.canonboolcell_labelstd::vector< uint64_t > — invariant cell / candidate labels of the current state (colour refinement)label_versionpm_longprop_capint — basic_propagate stops (no contradiction) once it has made more placements than thisgac_refconst std::vector< uint32_t > * — a consistent state: rules none of whose cells differ from it are skippedrefKint — knowledge ladder: 0 singles+relations+GAC, 1 + locked candidates + pairs,k_nbrstd::vector< std::vector< int > > — 2 + triples (over all houses); houses sharing >= 2 cellsk_instd::vector< std::vector< char > > — house membership per cellk_okstd::vector< char > — houses the ladder may use (refK >= 10: standard geometry only)
Solver(const Puzzle &p, const Params &P, const SolveOptions &o)
No comment.
void solve(const std::vector< std::pair< int, int > > &givens, SolveResult &out)
solves from the givens, one human step at a time, recording the steps and alternatives in out
void collect_strategy(Strategy &s, MoveBuf &b)
s->collect, through the listing cache when lcache is set
void direct_moves(MoveBuf &out, bool use_locks, int mental=0)
mental: 0 off, 2 relations/lines, 3 + subsets
bool direct_locks()
fills lock tables; returns "locks" truthiness
void innies(MoveBuf &out, bool notes)
rule-of-45 regions: the last cell of an innie / outie (no notes), or candidates the region sum rules out (notes)
void notes_singles(MoveBuf &out)
naked and hidden singles over the notes; one move per placement
void locked(MoveBuf &out)
pointing and claiming: a digit confined to a line (or box) inside a house leaves the rest of that line (box)
void cage_combo(MoveBuf &out)
sum-cage combinations: candidates no combination of the cage allows are eliminated
void pairarc(MoveBuf &out)
arc consistency over relation pairs (kropki, difference ...): drops candidates without a partner
void relation_pointing(MoveBuf &out)
a digit confined to cells of a house that all relate to one cell: it loses what the relation forbids
void subsets(MoveBuf &out, int k)
naked and hidden subsets of size k (pairs, triples, quads) in houses; adds the eliminations
void fish(MoveBuf &out, int k)
basic fish of size k (2 X-Wing, 3 Swordfish) over houses; adds the eliminations
void xywing(MoveBuf &out, bool xyz)
XY-Wing (XYZ-Wing when xyz): pivot with two wings; adds the digit eliminated from cells seeing the wings.
void coloring(MoveBuf &out)
simple colouring of one digit's conjugate-pair chains: colour wraps and traps; adds the eliminations
void trial(MoveBuf &out)
bivalue cell whose candidate breaks under basic propagation (trial and error); eliminates that candidate
bool guess(MoveBuf &out)
last resort: places the solution digit of the cell with fewest candidates, priced as the human cost of guessing
bool exhaust(MoveBuf &out)
where guessing is off: refutes one wrong candidate by full search (recorded as Trial and error)
void nary_combination(MoveBuf &out, int part=0)
n-ary constraints
part 0: all but set equivalences, 1: only those, 2: all
void combo_lock(MoveBuf &out)
n-ary combination locks: a digit in every consistent assignment, or forced into a rule by a house
void nary_direct(MoveBuf &out)
no-notes read of a rule with one empty cell whose digit the arithmetic / set rule forces
void innie_sum(MoveBuf &out)
consistency over rule-of-45 regions too big for the innie/outie sets, as derived sum constraints
bool compute_mental(int level)
builds the no-notes mental view (digits each cell can hold, relation / line bounds, mental subsets) up to level
void gfish(MoveBuf &out, int n, bool finless, bool finned)
generalized fish (any complete groups as base/cover sets): size n, finless (Jellyfish; X-Wing/Swordfish stay with the reference techniques) and/or finned/sashimi; mutant shapes only for size 2
void aic(MoveBuf &out, int lo, int hi)
alternating inference chains over the generic link graph, chain length (links) in [lo, hi]; includes discontinuous nice loops (placements)
void unique_rect(MoveBuf &out)
uniqueness (only with opt.assume_unique)
void bug_plus1(MoveBuf &out)
BUG+1: one tri-value cell in an otherwise bivalue grid takes the digit that is odd in its houses.
void rule_intersect(MoveBuf &out)
two rules / houses taken together: digit combinations over their joint cells; adds the eliminations
void sum_algebra(MoveBuf &out)
interval algebra over house totals, cages and segments in a band or stack; adds the eliminations
void band_logic(MoveBuf &out)
a band's lines, boxes and rules taken together as a sub-puzzle; eliminations that hold in all its fillings
void describe(Move &m, const MoveBuf &b)
structural descriptors (desc.cpp)
uint32_t written_marks(int c, int mode) const
candidates of c that are written down
void desc_stats()
refreshes the per-state statistics (candidate counts, bivalue cells ...) used by the move descriptors
const std::vector< int > & struct_colours()
structural colouring (symbol per cell, empty = none), computed once per solve
void colour_disambiguate(MoveBuf &out)
every colour is one digit: digits no consistent permutation gives a colour leave its cells
void bug_plus2(MoveBuf &out, int T1, int T2, int G0)
BUG+2: tri-value cells T1, T2 in an otherwise bivalue grid; eliminates what all surviving cases share.
void extended_ur(MoveBuf &out)
extended unique rectangle (2 rows x 3 boxes, six cells): the sixth cell cannot take x, y or z
void als_xz(MoveBuf &out)
almost locked sets over any AllDiff group
void als_xywing(MoveBuf &out)
ALS-XY-Wing: pivot ALS linked by restricted commons to two wing ALS; adds the common-digit eliminations.
void death_blossom(MoveBuf &out)
death blossom: a stem cell whose every candidate has an ALS petal; adds the digit all petals share
void als_aic(MoveBuf &out, int hi)
alternating inference chains through almost locked sets, up to hi links; adds eliminations and placements
void short_trial(MoveBuf &out)
bounded case split (human "what if"): returns rounds to contradiction, 0 = none
void human_case(MoveBuf &out)
bounded human case analysis (refutation, cell and house forcing within a few rule rounds)
void combo_positions(MoveBuf &out)
cage combinations cap how many of a digit set the cage holds in a house; the rest lies outside it
void clique_house(MoveBuf &out)
cells that pairwise differ (knight's move, relations) treated as a virtual house: naked sets and singles
void line_sets(MoveBuf &out)
renban-type lines meeting a house use disjoint digit sets there; digits no joint choice allows leave
void line_clues(MoveBuf &out)
a line with two or more outside clues (sandwich, x-sum, skyscraper) enumerated as one unit
void weighted_sums(MoveBuf &out)
integer combinations of sum facts down to 1-3 weighted cells, which are enumerated
void mental_chains(MoveBuf &out)
short chains (<= 5 links) on the no-notes mental view, paying off as a single
int case_split(int c, int v, int max_rounds, int &placed, std::vector< uint8_t > *ov=nullptr, std::vector< uint32_t > *oc=nullptr, std::vector< int > *log=nullptr)
No comment.
int prop_rounds(int max_rounds, int &placed, std::vector< int > *log=nullptr)
basic propagation in place for up to max_rounds rounds; returns the round of the first contradiction (0 = none)
int explain_chosen(const Move &m, const MoveBuf &b, std::vector< int > &ex)
explanation records of the chosen move that need the solver state (singles' reasons, trial branches); appended to ex, returns the number of ints added
void either_way(MoveBuf &out, bool direct_view)
both options of a two-way choice followed a few rounds; what both agree on holds (direct_view: placements only)
void line_classes(MoveBuf &out)
arc consistency on digit classes (low / high, odd / even) along lines; removes whole classes
void digit_count(MoveBuf &out)
a digit counted over k base units and k cover units: exactly k copies, so it leaves the covers' other cells
void equal_digits(MoveBuf &out)
two cells forced to hold the same unknown digit (abstract colouring): each keeps the other's candidates
void line_scan(MoveBuf &out)
local scan of a long line: consistency over each window of 3 consecutive cells
void medusa(MoveBuf &out)
3D Medusa: colouring over strong links of several digits; wraps and traps give eliminations
void multi_colouring(MoveBuf &out)
multi-colouring: two single-digit colour clusters interacting; adds the eliminations
void colour_algebra(MoveBuf &out, bool direct_view=false)
cells that share an unknown digit (colour classes) combined with the rules; direct_view: on the mental view
void label_shadow(MoveBuf &out)
cells carrying the same unknown digit label (a permutation of digits) restrict each other's candidates
pm_long table_live(const NConstraint &k) const
number of rows of a table constraint consistent with the placed digits and candidates
void n_wing(MoveBuf &out)
WXYZ / VWXYZ wings (bent sets): the digit Z leaves cells seeing every Z of the set.
void sue_de_coq(MoveBuf &out)
Sue de Coq: a box-line intersection with a line set and a box set covering its digits exactly; adds eliminations.
void aligned_pair(MoveBuf &out)
aligned pair exclusion: value pairs of two cells that would empty a common peer; adds the leftovers
void fireworks(MoveBuf &out)
Fireworks: three digits confined to three cells (corner, one in its row, one in its column); others go.
void chute_remote_pairs(MoveBuf &out)
remote pairs along a chute (band / stack) with the same bivalue pair; adds the eliminations
void pattern_overlay(MoveBuf &out)
pattern overlay: per-digit templates over the rows; candidates in no template (or all) are eliminated (placed)
void gurth(MoveBuf &out)
Gurth's symmetrical placement: a grid symmetry forces digits (uniqueness; opt-in by params)
void sum_bound(MoveBuf &out)
min / max (triangular number) bounds of sums, cages and arrows; eliminates digits beyond the bounds
void class_count(MoveBuf &out)
odd / even (and thirds) counting in houses and sum parity; eliminates digits of a full class
void class_colour(MoveBuf &out)
class colouring: low / high or odd / even links between cells, sides fixed by known cells or house counts
void clue_facts(MoveBuf &out)
facts read off the clues alone (relations on an empty grid; with line shape): fires once as one step
void domino(MoveBuf &out)
relation dominoes: a digit every allowed pair uses leaves common houses; two dominoes locking four digits
void forcing(MoveBuf &out, int level, bool nested=false)
forcing chains (forcing.cpp)
void nishio(MoveBuf &out)
Nishio: follows one digit from an assumed cell; a house left without a place refutes the assumption.
void what_if(MoveBuf &out, bool direct_view)
human "what if": a two-way choice followed with light logic; what both cases agree on holds
void mental_notes(MoveBuf &out)
notes logic done in the head on the no-notes view (rule combinations, intersections, pairs): a single
bool fallback_open() const
true while the forcing fallback has work budget left (boards up to 9x9)
bool forcing_fallback(MoveBuf &fb)
last resort before a guess: band logic with a larger budget, then dynamic / nested forcing; true if moves found
int fc_propagate(int level, int &steps, std::vector< int > *log=nullptr)
propagates the hypothetical state at level; returns 0 or 1 + the iteration of the first contradiction
int fc_branch(int c, int v, int level, int &steps, std::vector< uint8_t > *ov=nullptr, std::vector< uint32_t > *oc=nullptr, std::vector< int > *log=nullptr)
No comment.
void gac_prop(const NConstraint &k, const uint32_t *dom, pm_long budget, GacOut &out)
nary_moves.cpp
double pspread(const std::vector< int > &cells) const
structural spread of a cell pattern: complete groups touched / (2 sqrt(n) + 1) (canonical; invariant under puzzle automorphisms) or the coordinate gyration ratio (reference behaviour)
void compute_labels()
refreshes the invariant cell labels (colour refinement) for the current state
uint64_t node_label(int c, int v)
invariant label of candidate v at cell c, from the labels of the cells that share its houses
void canon_dedupe(MoveBuf &b)
keeps the cheapest move per placement and per (technique, elimination set)
int place(int c, int v)
places v at c, clearing it from the peers; returns the number of candidates erased
bool grid_valid() const
true if every cell is filled legally and every rule holds
void state_moves(const std::vector< std::pair< int, int > > &givens, MoveBuf &b, int limit_per_tech)
every move available at the current state (direct and notes families; tiers ungated), priced; at most limit_per_tech per technique (0 = all)
every cell filled consistently with every rule
void init_state(const std::vector< std::pair< int, int > > &givens)
resets the state to the givens (all candidates, then the givens placed)
void refute_profile(const std::vector< std::pair< int, int > > &givens, const std::vector< int > &sol, int max_stuck, std::vector< std::array< int, 5 > > &out)
generic refutation profile (refute.cpp): technique-free difficulty
bool basic_propagate(int &placed)
basic propagation to a fixpoint (singles, relations, rule consistency); false on contradiction
int trial_depth(int c, int v, int cap=1<< 30)
placements until a contradiction, -1 if none within cap
void k_prepare()
precomputes the houses and their overlaps the knowledge ladder uses
int k_step()
-1 contradiction, 0 nothing, 1 progress
static const Puzzle & pick_puzzle(const Puzzle &pz, const SolveOptions &o)
the puzzle actually solved: p.implied (derived houses, leftovers) unless IMPLIED is disabled
struct Solver::BandRegion
Fields
linesstd::vector< int >boxesstd::vector< int >rulesstd::vector< int >cagesstd::vector< int >cellsstd::vector< int >supersstd::vector< int > — regions holding all of this one's houses, rules and cagesposstd::vector< int > — cell -> index in the sub-puzzle (-1 outside)substd::shared_ptr< Puzzle >
struct Solver::DcCache
Fields
validboolkeystd::vector< uint64_t >bufMoveBuf
struct Solver::SplitMemo
Fields
valsstd::vector< uint8_t >candstd::vector< uint32_t >c0intv0introundsintresultintplacedintovstd::vector< uint8_t >ocstd::vector< uint32_t >
struct Solver::PropGac
Fields
validbooldomstd::vector< uint32_t >outGacOut
struct Solver::Src
Fields
kindintshapedoublemaskuint32_t
struct Solver::HSrc
Fields
keyuint64_tkindintshapedoublelocaluint32_t
struct Solver::LockEntry
Fields
identuint64_tshapedoublemaskuint32_ttgtint — index into lock_tgt (W words each)
struct Solver::GacCache
Fields
validbooldomstd::vector< uint32_t >outGacOut
struct Solver::GacKey
| Name | What it does |
|---|---|
operator== |
Fields
kconst NConstraint *vintmaskuint64_t
bool operator==(const GacKey &o) const
No comment.
struct Solver::GacKeyHash
| Name | What it does |
|---|---|
operator() |
size_t operator()(const GacKey &x) const
No comment.
struct Solver::ALS
Fields
cellsstd::vector< uint64_t > — W words.liststd::vector< int >canduint32_tgroupint