1use super::super::grid::{CellState, MappingGrid};
8use super::super::traits::{apply_gadget, pattern_matches, Pattern, PatternCell};
9use super::gadgets::{KsgReflectedGadget, KsgRotatedGadget, Mirror};
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12
13type WeightedPatternFactory = Box<dyn Fn() -> Box<dyn WeightedKsgPatternBoxed>>;
15
16pub type SourceGraph = (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>);
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
28pub struct WeightedKsgCross<const CON: bool>;
29
30impl Pattern for WeightedKsgCross<true> {
31 fn size(&self) -> (usize, usize) {
32 (3, 3)
33 }
34
35 fn cross_location(&self) -> (usize, usize) {
36 (2, 2)
37 }
38
39 fn is_connected(&self) -> bool {
40 true
41 }
42
43 fn is_cross_gadget(&self) -> bool {
44 true
45 }
46
47 fn connected_nodes(&self) -> Vec<usize> {
48 vec![0, 5]
49 }
50
51 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
52 let locs = vec![(2, 1), (2, 2), (2, 3), (1, 2), (2, 2), (3, 2)];
53 let edges = vec![(0, 1), (1, 2), (3, 4), (4, 5), (0, 5)];
54 let pins = vec![0, 3, 5, 2];
55 (locs, edges, pins)
56 }
57
58 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
59 let locs = vec![(2, 1), (2, 2), (2, 3), (1, 2), (3, 2)];
60 let pins = vec![0, 3, 4, 2];
61 (locs, pins)
62 }
63
64 fn mis_overhead(&self) -> i32 {
65 -2 }
67
68 fn source_weights(&self) -> Vec<i32> {
69 vec![2; 6]
70 }
71
72 fn mapped_weights(&self) -> Vec<i32> {
73 vec![2; 5]
74 }
75
76 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
77 [
78 (5, 5),
79 (12, 12),
80 (8, 0),
81 (1, 0),
82 (0, 0),
83 (6, 6),
84 (11, 11),
85 (9, 9),
86 (14, 14),
87 (3, 3),
88 (7, 7),
89 (4, 0),
90 (13, 13),
91 (15, 15),
92 (2, 0),
93 (10, 10),
94 ]
95 .into_iter()
96 .collect()
97 }
98
99 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
100 let mut map = HashMap::new();
101 map.insert(0, vec![vec![false, true, false, false, true, false]]);
102 map.insert(1, vec![vec![true, false, false, false, true, false]]);
103 map.insert(3, vec![vec![true, false, false, true, false, false]]);
104 map.insert(4, vec![vec![false, true, false, false, false, true]]);
105 map.insert(6, vec![vec![false, true, false, true, false, true]]);
106 map.insert(8, vec![vec![false, false, true, false, true, false]]);
107 map.insert(9, vec![vec![true, false, true, false, true, false]]);
108 map.insert(10, vec![vec![false, false, true, true, false, false]]);
109 map.insert(11, vec![vec![true, false, true, true, false, false]]);
110 map.insert(12, vec![vec![false, false, true, false, false, true]]);
111 map.insert(14, vec![vec![false, false, true, true, false, true]]);
112 map.insert(5, vec![]);
113 map.insert(7, vec![]);
114 map.insert(13, vec![]);
115 map.insert(15, vec![]);
116 map.insert(2, vec![vec![false, true, false, true, false, false]]);
117 map
118 }
119}
120
121impl Pattern for WeightedKsgCross<false> {
122 fn size(&self) -> (usize, usize) {
123 (4, 5)
124 }
125
126 fn cross_location(&self) -> (usize, usize) {
127 (2, 3)
128 }
129
130 fn is_connected(&self) -> bool {
131 false
132 }
133
134 fn is_cross_gadget(&self) -> bool {
135 true
136 }
137
138 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
139 let locs = vec![
140 (2, 1),
141 (2, 2),
142 (2, 3),
143 (2, 4),
144 (2, 5),
145 (1, 3),
146 (2, 3),
147 (3, 3),
148 (4, 3),
149 ];
150 let edges = vec![(0, 1), (1, 2), (2, 3), (3, 4), (5, 6), (6, 7), (7, 8)];
151 let pins = vec![0, 5, 8, 4];
152 (locs, edges, pins)
153 }
154
155 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
156 let locs = vec![
157 (2, 1),
158 (2, 2),
159 (2, 3),
160 (2, 4),
161 (2, 5),
162 (1, 3),
163 (3, 3),
164 (4, 3),
165 (3, 2),
166 (3, 4),
167 ];
168 let pins = vec![0, 5, 7, 4];
169 (locs, pins)
170 }
171
172 fn mis_overhead(&self) -> i32 {
173 -2 }
175
176 fn source_weights(&self) -> Vec<i32> {
177 vec![2; 9]
178 }
179
180 fn mapped_weights(&self) -> Vec<i32> {
181 vec![2; 10]
182 }
183
184 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
185 [
186 (5, 4),
187 (12, 4),
188 (8, 0),
189 (1, 0),
190 (0, 0),
191 (6, 0),
192 (11, 11),
193 (9, 9),
194 (14, 2),
195 (3, 2),
196 (7, 2),
197 (4, 4),
198 (13, 13),
199 (15, 11),
200 (2, 2),
201 (10, 2),
202 ]
203 .into_iter()
204 .collect()
205 }
206
207 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
208 let mut map = HashMap::new();
209 map.insert(
210 0,
211 vec![
212 vec![false, true, false, true, false, false, false, true, false],
213 vec![false, true, false, true, false, false, true, false, false],
214 ],
215 );
216 map.insert(
217 2,
218 vec![vec![
219 false, true, false, true, false, true, false, true, false,
220 ]],
221 );
222 map.insert(
223 4,
224 vec![vec![
225 false, true, false, true, false, false, true, false, true,
226 ]],
227 );
228 map.insert(
229 9,
230 vec![
231 vec![true, false, true, false, true, false, false, true, false],
232 vec![true, false, true, false, true, false, true, false, false],
233 ],
234 );
235 map.insert(
236 11,
237 vec![vec![
238 true, false, true, false, true, true, false, true, false,
239 ]],
240 );
241 map.insert(
242 13,
243 vec![vec![
244 true, false, true, false, true, false, true, false, true,
245 ]],
246 );
247 for i in [1, 3, 5, 6, 7, 8, 10, 12, 14, 15] {
248 map.entry(i).or_insert_with(Vec::new);
249 }
250 map
251 }
252}
253
254#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
256pub struct WeightedKsgTurn;
257
258impl Pattern for WeightedKsgTurn {
259 fn size(&self) -> (usize, usize) {
260 (4, 4)
261 }
262 fn cross_location(&self) -> (usize, usize) {
263 (3, 2)
264 }
265 fn is_connected(&self) -> bool {
266 false
267 }
268
269 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
270 let locs = vec![(1, 2), (2, 2), (3, 2), (3, 3), (3, 4)];
271 let edges = vec![(0, 1), (1, 2), (2, 3), (3, 4)];
272 let pins = vec![0, 4];
273 (locs, edges, pins)
274 }
275
276 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
277 let locs = vec![(1, 2), (2, 3), (3, 4)];
278 let pins = vec![0, 2];
279 (locs, pins)
280 }
281
282 fn mis_overhead(&self) -> i32 {
283 -2 }
285
286 fn source_weights(&self) -> Vec<i32> {
287 vec![2; 5]
288 }
289
290 fn mapped_weights(&self) -> Vec<i32> {
291 vec![2; 3]
292 }
293
294 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
295 [(0, 0), (2, 0), (3, 3), (1, 0)].into_iter().collect()
296 }
297
298 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
299 let mut map = HashMap::new();
300 map.insert(0, vec![vec![false, true, false, true, false]]);
301 map.insert(
302 1,
303 vec![
304 vec![true, false, true, false, false],
305 vec![true, false, false, true, false],
306 ],
307 );
308 map.insert(
309 2,
310 vec![
311 vec![false, true, false, false, true],
312 vec![false, false, true, false, true],
313 ],
314 );
315 map.insert(3, vec![vec![true, false, true, false, true]]);
316 map
317 }
318}
319
320#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
322pub struct WeightedKsgWTurn;
323
324impl Pattern for WeightedKsgWTurn {
325 fn size(&self) -> (usize, usize) {
326 (4, 4)
327 }
328 fn cross_location(&self) -> (usize, usize) {
329 (2, 2)
330 }
331 fn is_connected(&self) -> bool {
332 false
333 }
334
335 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
336 let locs = vec![(2, 3), (2, 4), (3, 2), (3, 3), (4, 2)];
337 let edges = vec![(0, 1), (0, 3), (2, 3), (2, 4)];
338 let pins = vec![1, 4];
339 (locs, edges, pins)
340 }
341
342 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
343 let locs = vec![(2, 4), (3, 3), (4, 2)];
344 let pins = vec![0, 2];
345 (locs, pins)
346 }
347
348 fn mis_overhead(&self) -> i32 {
349 -2 }
351
352 fn source_weights(&self) -> Vec<i32> {
353 vec![2; 5]
354 }
355
356 fn mapped_weights(&self) -> Vec<i32> {
357 vec![2; 3]
358 }
359
360 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
361 [(0, 0), (2, 0), (3, 3), (1, 0)].into_iter().collect()
362 }
363
364 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
365 let mut map = HashMap::new();
366 map.insert(0, vec![vec![true, false, true, false, false]]);
367 map.insert(
368 1,
369 vec![
370 vec![false, true, false, true, false],
371 vec![false, true, true, false, false],
372 ],
373 );
374 map.insert(
375 2,
376 vec![
377 vec![false, false, false, true, true],
378 vec![true, false, false, false, true],
379 ],
380 );
381 map.insert(3, vec![vec![false, true, false, true, true]]);
382 map
383 }
384}
385
386#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
388pub struct WeightedKsgBranch;
389
390impl Pattern for WeightedKsgBranch {
391 fn size(&self) -> (usize, usize) {
392 (5, 4)
393 }
394 fn cross_location(&self) -> (usize, usize) {
395 (3, 2)
396 }
397 fn is_connected(&self) -> bool {
398 false
399 }
400
401 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
402 let locs = vec![
403 (1, 2),
404 (2, 2),
405 (3, 2),
406 (3, 3),
407 (3, 4),
408 (4, 3),
409 (4, 2),
410 (5, 2),
411 ];
412 let edges = vec![(0, 1), (1, 2), (2, 3), (3, 4), (3, 5), (5, 6), (6, 7)];
413 let pins = vec![0, 4, 7];
414 (locs, edges, pins)
415 }
416
417 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
418 let locs = vec![(1, 2), (2, 3), (3, 2), (3, 4), (4, 3), (5, 2)];
419 let pins = vec![0, 3, 5];
420 (locs, pins)
421 }
422
423 fn mis_overhead(&self) -> i32 {
424 -2 }
426
427 fn source_weights(&self) -> Vec<i32> {
429 vec![2, 2, 2, 3, 2, 2, 2, 2]
430 }
431
432 fn mapped_weights(&self) -> Vec<i32> {
434 vec![2, 3, 2, 2, 2, 2]
435 }
436
437 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
438 [
439 (0, 0),
440 (4, 0),
441 (5, 5),
442 (6, 6),
443 (2, 0),
444 (7, 7),
445 (3, 3),
446 (1, 0),
447 ]
448 .into_iter()
449 .collect()
450 }
451
452 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
453 let mut map = HashMap::new();
454 map.insert(
455 0,
456 vec![vec![false, true, false, true, false, false, true, false]],
457 );
458 map.insert(
459 3,
460 vec![
461 vec![true, false, true, false, true, false, true, false],
462 vec![true, false, true, false, true, true, false, false],
463 ],
464 );
465 map.insert(
466 5,
467 vec![vec![true, false, true, false, false, true, false, true]],
468 );
469 map.insert(
470 6,
471 vec![
472 vec![false, false, true, false, true, true, false, true],
473 vec![false, true, false, false, true, true, false, true],
474 ],
475 );
476 map.insert(
477 7,
478 vec![vec![true, false, true, false, true, true, false, true]],
479 );
480 for i in [1, 2, 4] {
481 map.insert(i, vec![]);
482 }
483 map
484 }
485}
486
487#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
489pub struct WeightedKsgBranchFix;
490
491impl Pattern for WeightedKsgBranchFix {
492 fn size(&self) -> (usize, usize) {
493 (4, 4)
494 }
495 fn cross_location(&self) -> (usize, usize) {
496 (2, 2)
497 }
498 fn is_connected(&self) -> bool {
499 false
500 }
501
502 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
503 let locs = vec![(1, 2), (2, 2), (2, 3), (3, 3), (3, 2), (4, 2)];
504 let edges = vec![(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)];
505 let pins = vec![0, 5];
506 (locs, edges, pins)
507 }
508
509 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
510 let locs = vec![(1, 2), (2, 2), (3, 2), (4, 2)];
511 let pins = vec![0, 3];
512 (locs, pins)
513 }
514
515 fn mis_overhead(&self) -> i32 {
516 -2 }
518
519 fn source_weights(&self) -> Vec<i32> {
520 vec![2; 6]
521 }
522
523 fn mapped_weights(&self) -> Vec<i32> {
524 vec![2; 4]
525 }
526
527 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
528 [(0, 0), (2, 2), (3, 1), (1, 1)].into_iter().collect()
529 }
530
531 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
532 let mut map = HashMap::new();
533 map.insert(
534 0,
535 vec![
536 vec![false, true, false, true, false, false],
537 vec![false, true, false, false, true, false],
538 vec![false, false, true, false, true, false],
539 ],
540 );
541 map.insert(1, vec![vec![true, false, true, false, true, false]]);
542 map.insert(2, vec![vec![false, true, false, true, false, true]]);
543 map.insert(
544 3,
545 vec![
546 vec![true, false, false, true, false, true],
547 vec![true, false, true, false, false, true],
548 ],
549 );
550 map
551 }
552}
553
554#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
556pub struct WeightedKsgTCon;
557
558impl Pattern for WeightedKsgTCon {
559 fn size(&self) -> (usize, usize) {
560 (3, 4)
561 }
562 fn cross_location(&self) -> (usize, usize) {
563 (2, 2)
564 }
565 fn is_connected(&self) -> bool {
566 true
567 }
568 fn connected_nodes(&self) -> Vec<usize> {
569 vec![0, 1]
570 }
571
572 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
573 let locs = vec![(1, 2), (2, 1), (2, 2), (3, 2)];
574 let edges = vec![(0, 1), (0, 2), (2, 3)];
575 let pins = vec![0, 1, 3];
576 (locs, edges, pins)
577 }
578
579 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
580 let locs = vec![(1, 2), (2, 1), (2, 3), (3, 2)];
581 let pins = vec![0, 1, 3];
582 (locs, pins)
583 }
584
585 fn mis_overhead(&self) -> i32 {
586 0 }
588
589 fn source_weights(&self) -> Vec<i32> {
591 vec![2, 1, 2, 2]
592 }
593
594 fn mapped_weights(&self) -> Vec<i32> {
596 vec![2, 1, 2, 2]
597 }
598
599 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
600 [
601 (0, 0),
602 (4, 0),
603 (5, 5),
604 (6, 6),
605 (2, 2),
606 (7, 7),
607 (3, 3),
608 (1, 0),
609 ]
610 .into_iter()
611 .collect()
612 }
613
614 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
615 let mut map = HashMap::new();
616 map.insert(0, vec![vec![false, false, true, false]]);
617 map.insert(1, vec![vec![true, false, false, false]]);
618 map.insert(2, vec![vec![false, true, true, false]]);
619 map.insert(4, vec![vec![false, false, false, true]]);
620 map.insert(5, vec![vec![true, false, false, true]]);
621 map.insert(6, vec![vec![false, true, false, true]]);
622 map.insert(3, vec![]);
623 map.insert(7, vec![]);
624 map
625 }
626}
627
628#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
630pub struct WeightedKsgTrivialTurn;
631
632impl Pattern for WeightedKsgTrivialTurn {
633 fn size(&self) -> (usize, usize) {
634 (2, 2)
635 }
636 fn cross_location(&self) -> (usize, usize) {
637 (2, 2)
638 }
639 fn is_connected(&self) -> bool {
640 true
641 }
642 fn connected_nodes(&self) -> Vec<usize> {
643 vec![0, 1]
644 }
645
646 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
647 let locs = vec![(1, 2), (2, 1)];
648 let edges = vec![(0, 1)];
649 let pins = vec![0, 1];
650 (locs, edges, pins)
651 }
652
653 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
654 let locs = vec![(1, 2), (2, 1)];
655 let pins = vec![0, 1];
656 (locs, pins)
657 }
658
659 fn mis_overhead(&self) -> i32 {
660 0 }
662
663 fn source_weights(&self) -> Vec<i32> {
665 vec![1, 1]
666 }
667
668 fn mapped_weights(&self) -> Vec<i32> {
670 vec![1, 1]
671 }
672
673 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
674 [(0, 0), (2, 2), (3, 3), (1, 1)].into_iter().collect()
675 }
676
677 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
678 let mut map = HashMap::new();
679 map.insert(0, vec![vec![false, false]]);
680 map.insert(1, vec![vec![true, false]]);
681 map.insert(2, vec![vec![false, true]]);
682 map.insert(3, vec![]);
683 map
684 }
685}
686
687#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
689pub struct WeightedKsgEndTurn;
690
691impl Pattern for WeightedKsgEndTurn {
692 fn size(&self) -> (usize, usize) {
693 (3, 4)
694 }
695 fn cross_location(&self) -> (usize, usize) {
696 (2, 2)
697 }
698 fn is_connected(&self) -> bool {
699 false
700 }
701
702 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
703 let locs = vec![(1, 2), (2, 2), (2, 3)];
704 let edges = vec![(0, 1), (1, 2)];
705 let pins = vec![0];
706 (locs, edges, pins)
707 }
708
709 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
710 let locs = vec![(1, 2)];
711 let pins = vec![0];
712 (locs, pins)
713 }
714
715 fn mis_overhead(&self) -> i32 {
716 -2 }
718
719 fn source_weights(&self) -> Vec<i32> {
721 vec![2, 2, 1]
722 }
723
724 fn mapped_weights(&self) -> Vec<i32> {
726 vec![1]
727 }
728
729 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
730 [(0, 0), (1, 1)].into_iter().collect()
731 }
732
733 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
734 let mut map = HashMap::new();
735 map.insert(0, vec![vec![false, false, true], vec![false, true, false]]);
736 map.insert(1, vec![vec![true, false, true]]);
737 map
738 }
739}
740
741#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
743pub struct WeightedKsgBranchFixB;
744
745impl Pattern for WeightedKsgBranchFixB {
746 fn size(&self) -> (usize, usize) {
747 (4, 4)
748 }
749 fn cross_location(&self) -> (usize, usize) {
750 (2, 2)
751 }
752 fn is_connected(&self) -> bool {
753 false
754 }
755
756 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
757 let locs = vec![(2, 3), (3, 2), (3, 3), (4, 2)];
758 let edges = vec![(0, 2), (1, 2), (1, 3)];
759 let pins = vec![0, 3];
760 (locs, edges, pins)
761 }
762
763 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
764 let locs = vec![(3, 2), (4, 2)];
765 let pins = vec![0, 1];
766 (locs, pins)
767 }
768
769 fn mis_overhead(&self) -> i32 {
770 -2 }
772
773 fn source_weights(&self) -> Vec<i32> {
775 vec![1, 2, 2, 2]
776 }
777
778 fn mapped_weights(&self) -> Vec<i32> {
780 vec![1, 2]
781 }
782
783 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
784 [(0, 0), (2, 2), (3, 3), (1, 1)].into_iter().collect()
785 }
786
787 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
788 let mut map = HashMap::new();
789 map.insert(
790 0,
791 vec![
792 vec![false, false, true, false],
793 vec![false, true, false, false],
794 ],
795 );
796 map.insert(1, vec![vec![true, true, false, false]]);
797 map.insert(2, vec![vec![false, false, true, true]]);
798 map.insert(3, vec![vec![true, false, false, true]]);
799 map
800 }
801}
802
803#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
805pub struct WeightedKsgDanglingLeg;
806
807impl Pattern for WeightedKsgDanglingLeg {
808 fn size(&self) -> (usize, usize) {
809 (4, 3)
810 }
811 fn cross_location(&self) -> (usize, usize) {
812 (2, 1)
813 }
814 fn is_connected(&self) -> bool {
815 false
816 }
817
818 fn source_graph(&self) -> (Vec<(usize, usize)>, Vec<(usize, usize)>, Vec<usize>) {
819 let locs = vec![(2, 2), (3, 2), (4, 2)];
820 let edges = vec![(0, 1), (1, 2)];
821 let pins = vec![2];
822 (locs, edges, pins)
823 }
824
825 fn mapped_graph(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
826 let locs = vec![(4, 2)];
827 let pins = vec![0];
828 (locs, pins)
829 }
830
831 fn mis_overhead(&self) -> i32 {
832 -2 }
834
835 fn source_weights(&self) -> Vec<i32> {
837 vec![1, 2, 2]
838 }
839
840 fn mapped_weights(&self) -> Vec<i32> {
842 vec![1]
843 }
844
845 fn mapped_entry_to_compact(&self) -> HashMap<usize, usize> {
846 [(0, 0), (1, 1)].into_iter().collect()
847 }
848
849 fn source_entry_to_configs(&self) -> HashMap<usize, Vec<Vec<bool>>> {
850 let mut map = HashMap::new();
851 map.insert(0, vec![vec![true, false, false], vec![false, true, false]]);
852 map.insert(1, vec![vec![true, false, true]]);
853 map
854 }
855}
856
857#[derive(Debug, Clone)]
863pub enum WeightedKsgPattern {
864 CrossFalse(WeightedKsgCross<false>),
865 CrossTrue(WeightedKsgCross<true>),
866 Turn(WeightedKsgTurn),
867 WTurn(WeightedKsgWTurn),
868 Branch(WeightedKsgBranch),
869 BranchFix(WeightedKsgBranchFix),
870 TCon(WeightedKsgTCon),
871 TrivialTurn(WeightedKsgTrivialTurn),
872 EndTurn(WeightedKsgEndTurn),
873 BranchFixB(WeightedKsgBranchFixB),
874 DanglingLeg(WeightedKsgDanglingLeg),
875 RotatedTCon1(KsgRotatedGadget<WeightedKsgTCon>),
876 ReflectedCrossTrue(KsgReflectedGadget<WeightedKsgCross<true>>),
877 ReflectedTrivialTurn(KsgReflectedGadget<WeightedKsgTrivialTurn>),
878 ReflectedRotatedTCon1(KsgReflectedGadget<KsgRotatedGadget<WeightedKsgTCon>>),
879 DanglingLegRot1(KsgRotatedGadget<WeightedKsgDanglingLeg>),
880 DanglingLegRot2(KsgRotatedGadget<KsgRotatedGadget<WeightedKsgDanglingLeg>>),
881 DanglingLegRot3(KsgRotatedGadget<KsgRotatedGadget<KsgRotatedGadget<WeightedKsgDanglingLeg>>>),
882 DanglingLegReflX(KsgReflectedGadget<WeightedKsgDanglingLeg>),
883 DanglingLegReflY(KsgReflectedGadget<WeightedKsgDanglingLeg>),
884}
885
886impl WeightedKsgPattern {
887 pub fn from_tape_idx(idx: usize) -> Option<Self> {
889 match idx {
890 0 => Some(Self::CrossFalse(WeightedKsgCross::<false>)),
891 1 => Some(Self::Turn(WeightedKsgTurn)),
892 2 => Some(Self::WTurn(WeightedKsgWTurn)),
893 3 => Some(Self::Branch(WeightedKsgBranch)),
894 4 => Some(Self::BranchFix(WeightedKsgBranchFix)),
895 5 => Some(Self::TCon(WeightedKsgTCon)),
896 6 => Some(Self::TrivialTurn(WeightedKsgTrivialTurn)),
897 7 => Some(Self::RotatedTCon1(KsgRotatedGadget::new(
898 WeightedKsgTCon,
899 1,
900 ))),
901 8 => Some(Self::ReflectedCrossTrue(KsgReflectedGadget::new(
902 WeightedKsgCross::<true>,
903 Mirror::Y,
904 ))),
905 9 => Some(Self::ReflectedTrivialTurn(KsgReflectedGadget::new(
906 WeightedKsgTrivialTurn,
907 Mirror::Y,
908 ))),
909 10 => Some(Self::BranchFixB(WeightedKsgBranchFixB)),
910 11 => Some(Self::EndTurn(WeightedKsgEndTurn)),
911 12 => Some(Self::ReflectedRotatedTCon1(KsgReflectedGadget::new(
912 KsgRotatedGadget::new(WeightedKsgTCon, 1),
913 Mirror::Y,
914 ))),
915 100 => Some(Self::DanglingLeg(WeightedKsgDanglingLeg)),
916 101 => Some(Self::DanglingLegRot1(KsgRotatedGadget::new(
917 WeightedKsgDanglingLeg,
918 1,
919 ))),
920 102 => Some(Self::DanglingLegRot2(KsgRotatedGadget::new(
921 KsgRotatedGadget::new(WeightedKsgDanglingLeg, 1),
922 1,
923 ))),
924 103 => Some(Self::DanglingLegRot3(KsgRotatedGadget::new(
925 KsgRotatedGadget::new(KsgRotatedGadget::new(WeightedKsgDanglingLeg, 1), 1),
926 1,
927 ))),
928 104 => Some(Self::DanglingLegReflX(KsgReflectedGadget::new(
929 WeightedKsgDanglingLeg,
930 Mirror::X,
931 ))),
932 105 => Some(Self::DanglingLegReflY(KsgReflectedGadget::new(
933 WeightedKsgDanglingLeg,
934 Mirror::Y,
935 ))),
936 _ => None,
937 }
938 }
939
940 pub fn map_config_back(&self, gi: usize, gj: usize, config: &mut [Vec<usize>]) {
942 match self {
943 Self::CrossFalse(p) => map_config_back_pattern(p, gi, gj, config),
944 Self::CrossTrue(p) => map_config_back_pattern(p, gi, gj, config),
945 Self::Turn(p) => map_config_back_pattern(p, gi, gj, config),
946 Self::WTurn(p) => map_config_back_pattern(p, gi, gj, config),
947 Self::Branch(p) => map_config_back_pattern(p, gi, gj, config),
948 Self::BranchFix(p) => map_config_back_pattern(p, gi, gj, config),
949 Self::TCon(p) => map_config_back_pattern(p, gi, gj, config),
950 Self::TrivialTurn(p) => map_config_back_pattern(p, gi, gj, config),
951 Self::EndTurn(p) => map_config_back_pattern(p, gi, gj, config),
952 Self::BranchFixB(p) => map_config_back_pattern(p, gi, gj, config),
953 Self::DanglingLeg(p) => map_config_back_pattern(p, gi, gj, config),
954 Self::RotatedTCon1(p) => map_config_back_pattern(p, gi, gj, config),
955 Self::ReflectedCrossTrue(p) => map_config_back_pattern(p, gi, gj, config),
956 Self::ReflectedTrivialTurn(p) => map_config_back_pattern(p, gi, gj, config),
957 Self::ReflectedRotatedTCon1(p) => map_config_back_pattern(p, gi, gj, config),
958 Self::DanglingLegRot1(p) => map_config_back_pattern(p, gi, gj, config),
959 Self::DanglingLegRot2(p) => map_config_back_pattern(p, gi, gj, config),
960 Self::DanglingLegRot3(p) => map_config_back_pattern(p, gi, gj, config),
961 Self::DanglingLegReflX(p) => map_config_back_pattern(p, gi, gj, config),
962 Self::DanglingLegReflY(p) => map_config_back_pattern(p, gi, gj, config),
963 }
964 }
965}
966
967#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
973pub struct WeightedKsgTapeEntry {
974 pub pattern_idx: usize,
975 pub row: usize,
976 pub col: usize,
977}
978
979pub fn weighted_tape_entry_mis_overhead(entry: &WeightedKsgTapeEntry) -> i32 {
981 match entry.pattern_idx {
982 0 => WeightedKsgCross::<false>.mis_overhead(),
983 1 => WeightedKsgTurn.mis_overhead(),
984 2 => WeightedKsgWTurn.mis_overhead(),
985 3 => WeightedKsgBranch.mis_overhead(),
986 4 => WeightedKsgBranchFix.mis_overhead(),
987 5 => WeightedKsgTCon.mis_overhead(),
988 6 => WeightedKsgTrivialTurn.mis_overhead(),
989 7 => KsgRotatedGadget::new(WeightedKsgTCon, 1).mis_overhead(),
990 8 => KsgReflectedGadget::new(WeightedKsgCross::<true>, Mirror::Y).mis_overhead(),
991 9 => KsgReflectedGadget::new(WeightedKsgTrivialTurn, Mirror::Y).mis_overhead(),
992 10 => WeightedKsgBranchFixB.mis_overhead(),
993 11 => WeightedKsgEndTurn.mis_overhead(),
994 12 => KsgReflectedGadget::new(KsgRotatedGadget::new(WeightedKsgTCon, 1), Mirror::Y)
995 .mis_overhead(),
996 100..=105 => WeightedKsgDanglingLeg.mis_overhead(),
997 _ => 0,
998 }
999}
1000
1001pub trait WeightedKsgPatternBoxed {
1003 fn size_boxed(&self) -> (usize, usize);
1004 fn cross_location(&self) -> (usize, usize);
1005 fn source_matrix(&self) -> Vec<Vec<PatternCell>>;
1006 fn mapped_matrix(&self) -> Vec<Vec<PatternCell>>;
1007 fn source_graph_boxed(&self) -> SourceGraph;
1008 fn mapped_graph_boxed(&self) -> (Vec<(usize, usize)>, Vec<usize>);
1009 fn source_weights_boxed(&self) -> Vec<i32>;
1010 fn mapped_weights_boxed(&self) -> Vec<i32>;
1011 fn pattern_matches_boxed(&self, grid: &MappingGrid, i: usize, j: usize) -> bool;
1012 fn apply_gadget_boxed(&self, grid: &mut MappingGrid, i: usize, j: usize);
1013 fn apply_weighted_gadget_boxed(&self, grid: &mut MappingGrid, i: usize, j: usize);
1014}
1015
1016impl<P: Pattern> WeightedKsgPatternBoxed for P {
1017 fn size_boxed(&self) -> (usize, usize) {
1018 self.size()
1019 }
1020 fn cross_location(&self) -> (usize, usize) {
1021 Pattern::cross_location(self)
1022 }
1023 fn source_matrix(&self) -> Vec<Vec<PatternCell>> {
1024 Pattern::source_matrix(self)
1025 }
1026 fn mapped_matrix(&self) -> Vec<Vec<PatternCell>> {
1027 Pattern::mapped_matrix(self)
1028 }
1029 fn source_graph_boxed(&self) -> SourceGraph {
1030 Pattern::source_graph(self)
1031 }
1032 fn mapped_graph_boxed(&self) -> (Vec<(usize, usize)>, Vec<usize>) {
1033 Pattern::mapped_graph(self)
1034 }
1035 fn source_weights_boxed(&self) -> Vec<i32> {
1036 Pattern::source_weights(self)
1037 }
1038 fn mapped_weights_boxed(&self) -> Vec<i32> {
1039 Pattern::mapped_weights(self)
1040 }
1041 fn pattern_matches_boxed(&self, grid: &MappingGrid, i: usize, j: usize) -> bool {
1042 pattern_matches(self, grid, i, j)
1043 }
1044 fn apply_gadget_boxed(&self, grid: &mut MappingGrid, i: usize, j: usize) {
1045 apply_gadget(self, grid, i, j);
1046 }
1047 fn apply_weighted_gadget_boxed(&self, grid: &mut MappingGrid, i: usize, j: usize) {
1048 apply_weighted_gadget(self, grid, i, j);
1049 }
1050}
1051
1052#[allow(clippy::needless_range_loop)]
1055pub fn apply_weighted_gadget<P: Pattern>(pattern: &P, grid: &mut MappingGrid, i: usize, j: usize) {
1056 let (m, n) = pattern.size();
1057 let (mapped_locs, _) = pattern.mapped_graph();
1058 let mapped_weights = pattern.mapped_weights();
1059
1060 for r in 0..m {
1062 for c in 0..n {
1063 let grid_r = i + r;
1064 let grid_c = j + c;
1065 grid.set(grid_r, grid_c, CellState::Empty);
1066 }
1067 }
1068
1069 let mut weight_map: HashMap<(usize, usize), i32> = HashMap::new();
1071 for (idx, &(r, c)) in mapped_locs.iter().enumerate() {
1072 let weight = mapped_weights.get(idx).copied().unwrap_or(2);
1073 *weight_map.entry((r, c)).or_insert(0) += weight;
1074 }
1075
1076 let mut count_map: HashMap<(usize, usize), usize> = HashMap::new();
1078 for &(r, c) in &mapped_locs {
1079 *count_map.entry((r, c)).or_insert(0) += 1;
1080 }
1081
1082 for (&(r, c), &total_weight) in &weight_map {
1084 let grid_r = i + r - 1; let grid_c = j + c - 1;
1086 let count = count_map.get(&(r, c)).copied().unwrap_or(1);
1087
1088 let state = if count > 1 {
1089 CellState::Doubled {
1090 weight: total_weight,
1091 }
1092 } else {
1093 CellState::Occupied {
1094 weight: total_weight,
1095 }
1096 };
1097 grid.set(grid_r, grid_c, state);
1098 }
1099}
1100
1101pub fn apply_weighted_crossing_gadgets(
1103 grid: &mut MappingGrid,
1104 copylines: &[super::super::copyline::CopyLine],
1105) -> Vec<WeightedKsgTapeEntry> {
1106 let mut tape = Vec::new();
1107 let n = copylines.len();
1108
1109 for j in 0..n {
1110 for i in 0..n {
1111 let (cross_row, cross_col) = crossat(grid, copylines, i, j);
1112 if let Some((pattern_idx, row, col)) =
1113 try_match_and_apply_weighted_crossing(grid, cross_row, cross_col)
1114 {
1115 tape.push(WeightedKsgTapeEntry {
1116 pattern_idx,
1117 row,
1118 col,
1119 });
1120 }
1121 }
1122 }
1123 tape
1124}
1125
1126fn crossat(
1128 grid: &MappingGrid,
1129 copylines: &[super::super::copyline::CopyLine],
1130 v: usize,
1131 w: usize,
1132) -> (usize, usize) {
1133 let line_v = copylines.get(v);
1134 let line_w = copylines.get(w);
1135
1136 match (line_v, line_w) {
1137 (Some(lv), Some(lw)) => {
1138 let (line_first, line_second) = if lv.vslot < lw.vslot {
1139 (lv, lw)
1140 } else {
1141 (lw, lv)
1142 };
1143 grid.cross_at(line_first.vslot, line_second.vslot, line_first.hslot)
1144 }
1145 _ => (0, 0),
1146 }
1147}
1148
1149fn try_match_and_apply_weighted_crossing(
1150 grid: &mut MappingGrid,
1151 cross_row: usize,
1152 cross_col: usize,
1153) -> Option<(usize, usize, usize)> {
1154 let patterns: Vec<(usize, WeightedPatternFactory)> = vec![
1156 (0, Box::new(|| Box::new(WeightedKsgCross::<false>))),
1157 (1, Box::new(|| Box::new(WeightedKsgTurn))),
1158 (2, Box::new(|| Box::new(WeightedKsgWTurn))),
1159 (3, Box::new(|| Box::new(WeightedKsgBranch))),
1160 (4, Box::new(|| Box::new(WeightedKsgBranchFix))),
1161 (5, Box::new(|| Box::new(WeightedKsgTCon))),
1162 (6, Box::new(|| Box::new(WeightedKsgTrivialTurn))),
1163 (
1164 7,
1165 Box::new(|| Box::new(KsgRotatedGadget::new(WeightedKsgTCon, 1))),
1166 ),
1167 (
1168 8,
1169 Box::new(|| Box::new(KsgReflectedGadget::new(WeightedKsgCross::<true>, Mirror::Y))),
1170 ),
1171 (
1172 9,
1173 Box::new(|| Box::new(KsgReflectedGadget::new(WeightedKsgTrivialTurn, Mirror::Y))),
1174 ),
1175 (10, Box::new(|| Box::new(WeightedKsgBranchFixB))),
1176 (11, Box::new(|| Box::new(WeightedKsgEndTurn))),
1177 (
1178 12,
1179 Box::new(|| {
1180 Box::new(KsgReflectedGadget::new(
1181 KsgRotatedGadget::new(WeightedKsgTCon, 1),
1182 Mirror::Y,
1183 ))
1184 }),
1185 ),
1186 ];
1187
1188 for (idx, make_pattern) in patterns {
1189 let pattern = make_pattern();
1190 let cl = pattern.cross_location();
1191 if cross_row + 1 >= cl.0 && cross_col + 1 >= cl.1 {
1192 let x = cross_row + 1 - cl.0;
1193 let y = cross_col + 1 - cl.1;
1194 let matches = pattern.pattern_matches_boxed(grid, x, y);
1195 if matches {
1196 pattern.apply_weighted_gadget_boxed(grid, x, y);
1197 return Some((idx, x, y));
1198 }
1199 }
1200 }
1201 None
1202}
1203
1204pub fn apply_weighted_simplifier_gadgets(
1206 grid: &mut MappingGrid,
1207 nrepeat: usize,
1208) -> Vec<WeightedKsgTapeEntry> {
1209 let mut tape = Vec::new();
1210 let (rows, cols) = grid.size();
1211
1212 let patterns = rotated_and_reflected_weighted_danglingleg();
1213
1214 for _ in 0..nrepeat {
1215 for (pattern_idx, pattern) in patterns.iter().enumerate() {
1216 for j in 0..cols {
1217 for i in 0..rows {
1218 if pattern_matches_weighted(pattern.as_ref(), grid, i, j) {
1219 pattern.apply_weighted_gadget_boxed(grid, i, j);
1220 tape.push(WeightedKsgTapeEntry {
1221 pattern_idx: 100 + pattern_idx,
1222 row: i,
1223 col: j,
1224 });
1225 }
1226 }
1227 }
1228 }
1229 }
1230
1231 tape
1232}
1233
1234fn pattern_matches_weighted(
1237 pattern: &dyn WeightedKsgPatternBoxed,
1238 grid: &MappingGrid,
1239 i: usize,
1240 j: usize,
1241) -> bool {
1242 if !pattern.pattern_matches_boxed(grid, i, j) {
1244 return false;
1245 }
1246
1247 let (locs, _, _) = pattern.source_graph_boxed();
1249 let source_weights = pattern.source_weights_boxed();
1250
1251 for (idx, (loc_r, loc_c)) in locs.iter().enumerate() {
1252 let grid_r = i + loc_r - 1;
1253 let grid_c = j + loc_c - 1;
1254 if let Some(cell) = grid.get(grid_r, grid_c) {
1255 let expected_weight = source_weights.get(idx).copied().unwrap_or(2);
1256 if cell.weight() != expected_weight {
1257 return false;
1258 }
1259 }
1260 }
1261
1262 true
1263}
1264
1265fn rotated_and_reflected_weighted_danglingleg() -> Vec<Box<dyn WeightedKsgPatternBoxed>> {
1266 vec![
1267 Box::new(WeightedKsgDanglingLeg),
1268 Box::new(KsgRotatedGadget::new(WeightedKsgDanglingLeg, 1)),
1269 Box::new(KsgRotatedGadget::new(WeightedKsgDanglingLeg, 2)),
1270 Box::new(KsgRotatedGadget::new(WeightedKsgDanglingLeg, 3)),
1271 Box::new(KsgReflectedGadget::new(WeightedKsgDanglingLeg, Mirror::X)),
1272 Box::new(KsgReflectedGadget::new(WeightedKsgDanglingLeg, Mirror::Y)),
1273 ]
1274}
1275
1276pub fn map_config_back_pattern<P: Pattern>(
1278 pattern: &P,
1279 gi: usize,
1280 gj: usize,
1281 config: &mut [Vec<usize>],
1282) {
1283 let (m, n) = pattern.size();
1284 let (mapped_locs, mapped_pins) = pattern.mapped_graph();
1285 let (source_locs, _, _) = pattern.source_graph();
1286
1287 let mapped_config: Vec<usize> = mapped_locs
1289 .iter()
1290 .map(|&(r, c)| {
1291 let row = gi + r - 1;
1292 let col = gj + c - 1;
1293 config
1294 .get(row)
1295 .and_then(|row_vec| row_vec.get(col))
1296 .copied()
1297 .unwrap_or(0)
1298 })
1299 .collect();
1300
1301 let bc = {
1303 let mut result = 0usize;
1304 for (i, &pin_idx) in mapped_pins.iter().enumerate() {
1305 if pin_idx < mapped_config.len() && mapped_config[pin_idx] > 0 {
1306 result |= 1 << i;
1307 }
1308 }
1309 result
1310 };
1311
1312 let d1 = pattern.mapped_entry_to_compact();
1314 let d2 = pattern.source_entry_to_configs();
1315
1316 let compact = d1.get(&bc).copied();
1317 debug_assert!(
1318 compact.is_some(),
1319 "Boundary config {} not found in mapped_entry_to_compact",
1320 bc
1321 );
1322 let compact = compact.unwrap_or(0);
1323
1324 let source_configs = d2.get(&compact).cloned();
1325 debug_assert!(
1326 source_configs.is_some(),
1327 "Compact {} not found in source_entry_to_configs",
1328 compact
1329 );
1330 let source_configs = source_configs.unwrap_or_default();
1331
1332 debug_assert!(
1333 !source_configs.is_empty(),
1334 "Empty source configs for compact {}.",
1335 compact
1336 );
1337 let new_config = if source_configs.is_empty() {
1338 vec![false; source_locs.len()]
1339 } else {
1340 source_configs[0].clone()
1341 };
1342
1343 for row in gi..gi + m {
1345 for col in gj..gj + n {
1346 if let Some(row_vec) = config.get_mut(row) {
1347 if let Some(cell) = row_vec.get_mut(col) {
1348 *cell = 0;
1349 }
1350 }
1351 }
1352 }
1353
1354 for (k, &(r, c)) in source_locs.iter().enumerate() {
1356 let row = gi + r - 1;
1357 let col = gj + c - 1;
1358 if let Some(rv) = config.get_mut(row) {
1359 if let Some(cv) = rv.get_mut(col) {
1360 *cv += if new_config.get(k).copied().unwrap_or(false) {
1361 1
1362 } else {
1363 0
1364 };
1365 }
1366 }
1367 }
1368}
1369
1370#[cfg(test)]
1371#[path = "../../../unit_tests/rules/unitdiskmapping/ksg/gadgets_weighted.rs"]
1372mod tests;