1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
//! Torus cover -- a sound (but *not* complete) periodic-acceptance stage.
//!
//! This certifies periodicity by folding a grown patch onto the flat torus and
//! exact-checking. It is **sound** (a "yes" is a verified tiling) but **not
//! exhaustive**: the candidate lattices are read off a corona patch, so if the
//! patch jams before reaching lattice scale, a real k-tile tiling is missed and
//! the answer is an inconclusive `None` -- never a proof of non-periodicity.
//! (A genuinely complete-for-fixed-k test enumerates every connected k-cluster
//! by edge-gluing and Beauquier-Nivat-tests each -- but that is exponential in k;
//! this is the cheap heuristic that reaches large k, e.g. tile0's 8-tile domain,
//! when exhaustive cluster enumeration is infeasible.)
//!
//! # The geometric picture
//!
//! A tile tiles the plane periodically exactly when some rank-2 lattice
//! `L = <v1, v2>` is a symmetry of a tiling: the plane folds onto the flat
//! torus `R^2 / L` (a parallelogram with opposite sides identified), and a
//! finite **fundamental domain** of `k` tile-copies covers that torus once,
//! with no gap and no overlap. Unfold by the lattice and the whole plane is
//! tiled. So "tiles periodically with a domain of at most `K` tiles" is
//! *characterized* by: for each `k <= K`, is there a lattice `L` of covolume
//! `k * area(tile)` and a set of `k` placements (rotations only, our
//! single-chirality scope) that exact-cover `R^2 / L`? (We only *search* this
//! space via patch-derived lattices below -- we do not enumerate it
//! exhaustively, so a negative answer is not a proof.)
//!
//! This is the acceptance counterpart to the finite-Heesch reject: a Heesch
//! number proves a tile *cannot* tile; a torus cover proves it *does* (and
//! periodically, which disqualifies it as an aperiodic monotile -- the
//! spectre family tiles only aperiodically).
//!
//! # Why the lattice candidates come from a grown patch (and why that is a
//! *speed* choice, not a necessity)
//!
//! Exhaustive fixed-k enumeration is in fact **finite**: tiles have area, so by
//! area-packing (and the cyclotomic spacing bound -- two non-overlapping copies
//! that are geometrically close must be combinatorially far apart) only finitely
//! many non-overlapping placements fit in the bounded region a k-tile domain
//! occupies. So the candidate fundamental domains -- the connected k-clusters --
//! are a finite (though *exponential in k*) set, and BN-testing each is the
//! complete-for-fixed-k acceptance. The density of
//! `Z[zeta12]` as an abstract point set is irrelevant here: we never enumerate
//! abstract ring points, only non-overlapping placements, which packing bounds.
//!
//! This module takes the cheaper, **incomplete** route: grow ONE patch and read
//! candidate lattices off it (two equally-oriented tiles differ by a lattice
//! vector, so once corona growth reaches lattice scale the true `v1, v2` appear
//! among the same-orientation displacements). That is O(patch) instead of the
//! exponential cluster enumeration, and it reached e.g. tile0's 8-tile domain --
//! but if the patch jams first, a real tiling is missed (a `None` is not a
//! proof). For each candidate lattice we fold the patch onto the torus and read
//! off the `k` domain classes.
//!
//! # Soundness
//!
//! The accept is gated by two complementary EXACT checks -- the whole
//! acceptance chain is integer/ring arithmetic, floats never decide:
//!
//! - [`gold_check`] (per-class angle sums to a full turn + every edge shared
//! by exactly two, at shared ring coordinates) proves the configuration
//! `domain x L` is a complete flat covering of the plane of CONSTANT
//! integer multiplicity `m >= 1`. It cannot by itself distinguish `m = 1`
//! from a clean `m`-sheet cover whose sheets share no vertex or edge
//! coordinates (a transversally overlapping tile contributes nothing to
//! another sheet's angle/edge maps).
//! - MULTIPLICITY 1 is forced by the exact ring identity
//! `covol == domain.len() * area`
//! ([`covol_eq_m_areas`]): cross products
//! and shoelace areas are `Im`-parts of ring products (`z - conj(z) =
//! 2i Im(z)` stays in the ring), so the identity is an integer-coefficient
//! equality that an `m`-sheet cover misses by an exact factor of `m`.
//!
//! Everything float-guided (candidate ranking around `COVOL_INT_EPS`,
//! lattice reduction, coverage-block sizing) only proposes or sizes; a wrong
//! value yields a miss, never an accept. A miss proves nothing (the grower
//! may not have reached lattice scale) -- a tile that fails here is left a
//! candidate, never wrongly rejected.
// Fx hashers (fixed seed) rather than std's random-seeded HashMap: the cover
// detection iterates these maps, so a random per-process seed made the chosen
// cover -- and thus the whole cert -- vary run to run. Fx makes iteration order
// deterministic (the same discipline `patch.rs` relies on).
use FxHashMap as HashMap;
use crateIsRing;
use crate;
use crateboundary_vertices;
use grow_coronas;
use ;
use ;
use crate;
use crateIso;
/// A confirmed periodic-tiling certificate: the tile tiles `R^2` invariant
/// under the lattice `L = lattice`, with the `k`-tile `domain` as a
/// fundamental domain. Verified by the exact gold check.
/// One representative placement per `(orientation, position mod L)` class of
/// the patch -- the candidate fundamental domain. Within each orientation
/// group, anchors that differ by a lattice vector are the same torus class.
///
/// Corona growth lays only a *near*-periodic surrounding, so a few boundary
/// tiles can land in spurious one-off classes. We keep only the **recurring**
/// classes (seen in at least half as many cells as the most-populated class),
/// which is the periodic core; the exact gold check then confirms it. This
/// recurrence filter is what lets a deep but imperfect patch still reveal the
/// true fundamental domain.
/// The exact gold check: instantiate a provably-sufficient block of the
/// infinite configuration `S = domain x L` and verify EVERY domain
/// representative is exactly surrounded in it (`all_exactly_surrounded`:
/// every vertex's incident interior angles sum to a full turn, catching both
/// gaps and overlaps, and every edge is shared by exactly two tiles).
///
/// Two ingredients make the block-local check extend to the whole plane:
///
/// - PER-CLASS checking: the lattice maps each translation class to itself,
/// so certifying one representative per class certifies, by `L`-invariance,
/// every tile of `S` -- a single checked tile would leave defects strictly
/// between tiles of the other classes unexamined.
/// - PROVEN COVERAGE: the block must contain every tile of `S` that can touch
/// a representative, else a defect (e.g. a short lattice combination
/// landing a far cell on top of a rep) would sit outside the block and the
/// truncated view could look exact. Every rep tile lies in the origin disk
/// of radius `D`, so a touching `rep + l1*v1 + l2*v2` needs
/// `|l1*v1 + l2*v2| <= 2D`; the perpendicular-component bounds
/// `|l1*v1 + l2*v2| >= |l1| * covol/|v2|` (and symmetrically for `l2`) turn
/// that into exact per-axis reaches. The basis is Gauss-reduced first (same
/// lattice) so the reaches stay small; a block that would still exceed
/// `GOLD_ORBIT_CAP` is rejected outright (fail closed).
///
/// The comparisons here are exact (ring equality, integer angles) and the
/// floats only size the block (oversizing is harmless) -- but note the exact
/// checks alone certify a constant-multiplicity covering, not multiplicity 1;
/// the caller's EXACT multiplicity gate
/// ([`covol_eq_m_areas`]) supplies that
/// final step (see the module-level Soundness section).
/// Maximum distinct same-orientation displacement vectors retained as lattice
/// candidates (most frequent first -- a true lattice vector recurs across the
/// patch, so the frequent ones are the real candidates).
const MAX_DISP: usize = 160;
/// Placement cap for the gold-check orbit block. The adaptive reaches keep
/// benign cases tiny (tens to a few thousand placements); a pathologically
/// skewed basis that would explode the block is rejected outright instead
/// (fail closed -- a genuine tiling's reduced basis never comes close).
const GOLD_ORBIT_CAP: i64 = 50_000;
/// PROPOSAL filter only: a candidate lattice pair is kept when its covolume
/// is within this of an integer multiple of the tile area (k tiles per
/// cell). Generous -- the exact multiplicity gate (`covol_eq_m_areas`) and
/// the gold check decide; this just prunes hopeless pairs cheaply.
const COVOL_INT_EPS: f64 = 0.3;
/// Candidate pairs with covolume below this fraction of one tile area are
/// degenerate (near-parallel vectors) and skipped outright.
const MIN_COVOL_FRACTION: f64 = 0.5;
/// A torus class is part of the periodic core only if it recurs in at least
/// 1/RECURRENCE_DIVISOR of the cells the most-populated class shows in --
/// corona growth lays a NEAR-periodic patch, so one-off boundary classes are
/// noise, not domain tiles.
const RECURRENCE_DIVISOR: usize = 2;
/// Does `seq` tile the plane periodically with a fundamental domain of at most
/// `kmax` tiles? Grows a `coronas`-deep patch, reads candidate lattices off its
/// same-orientation displacements, and gold-checks each. Returns the verified
/// cover, or `None` (a candidate is then left undecided, never rejected).
///
/// See the module docs for why the candidate lattices come from a grown patch
/// (the ring is dense, so abstract covolume enumeration is not finite) and why
/// the float-guided search is sound (the exact gold check gates every accept).
/// Read a torus cover off an already-grown near-periodic `patch`: group by
/// orientation, collect recurring same-orientation displacements as candidate
/// lattice vectors, and for each covolume-consistent pair fold the patch onto
/// `k` classes and exact-`gold_check` it. Returns the first verified cover.
///
/// Decoupled from the grower so a cheaply-built periodic orbit (e.g. a Conway
/// or isohedral `build_orbit` patch) can be handed straight in -- the lattice
/// detection here is what produces a *verified* primitive cell + domain, which
/// cert minting needs, without paying for `grow_coronas`'s backtracking.
pub