File size: 31,118 Bytes
07b428c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
/* s6_exotic.c β€” S₆ Outer Automorphism Implementation
 *
 * Constructs Ο† via synthematic totals at initialization.
 * Provides exotic gates, parameterized folds, and dual measurement.
 */

#include <string.h>
#include <stdio.h>
#include <math.h>
#include "s6_exotic.h"

static const double INV_SQRT2 = 0.70710678118654752440;

/* ═══════════════════════════════════════════════════════════════════════════
 * SYNTHEMES β€” 15 partitions of {0,..,5} into 3 pairs
 *
 * Canonical form: pairs sorted by first element, a < c < e.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* We enumerate all 15 at compile time */
const S6Syntheme s6_synthemes[S6_NUM_SYNTHEMES] = {
    [0]  = {{{0,1},{2,3},{4,5}}},   /* T0 member */
    [1]  = {{{0,1},{2,4},{3,5}}},
    [2]  = {{{0,1},{2,5},{3,4}}},
    [3]  = {{{0,2},{1,3},{4,5}}},
    [4]  = {{{0,2},{1,4},{3,5}}},   /* T0 member */
    [5]  = {{{0,2},{1,5},{3,4}}},
    [6]  = {{{0,3},{1,2},{4,5}}},
    [7]  = {{{0,3},{1,4},{2,5}}},   /* DEFAULT fold β€” the standard antipodal pairing */
    [8]  = {{{0,3},{1,5},{2,4}}},   /* T0 member */
    [9]  = {{{0,4},{1,2},{3,5}}},
    [10] = {{{0,4},{1,3},{2,5}}},   /* T0 member */
    [11] = {{{0,4},{1,5},{2,3}}},
    [12] = {{{0,5},{1,2},{3,4}}},   /* T0 member */
    [13] = {{{0,5},{1,3},{2,4}}},
    [14] = {{{0,5},{1,4},{2,3}}},
};

/* ═══════════════════════════════════════════════════════════════════════════
 * TOTALS β€” 6 sets of 5 synthemes covering all 15 pairs
 *
 * Built at init time by brute-force search over C(15,5) = 3003 subsets.
 * ═══════════════════════════════════════════════════════════════════════════ */

int s6_totals[S6_NUM_TOTALS][5];
S6Perm s6_phi[S6_ORDER];
int s6_exotic_ready = 0;

/* Check if 5 syntheme indices form a total (cover all 15 pairs exactly once) */
static int check_total(const int idx[5]) {
    int covered[6][6] = {{0}};
    for (int si = 0; si < 5; si++) {
        const S6Syntheme *s = &s6_synthemes[idx[si]];
        for (int p = 0; p < 3; p++) {
            int a = s->pairs[p][0], b = s->pairs[p][1];
            if (covered[a][b]) return 0;
            covered[a][b] = covered[b][a] = 1;
        }
    }
    for (int a = 0; a < 6; a++)
        for (int b = a+1; b < 6; b++)
            if (!covered[a][b]) return 0;
    return 1;
}

static int find_all_totals(void) {
    int n = 0;
    for (int a = 0; a < 15 && n < 6; a++)
    for (int b = a+1; b < 15 && n < 6; b++)
    for (int c = b+1; c < 15 && n < 6; c++)
    for (int d = c+1; d < 15 && n < 6; d++)
    for (int e = d+1; e < 15 && n < 6; e++) {
        int idx[5] = {a,b,c,d,e};
        if (check_total(idx)) {
            for (int i = 0; i < 5; i++) s6_totals[n][i] = idx[i];
            n++;
        }
    }
    return n;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * PERMUTATION PRIMITIVES
 * ═══════════════════════════════════════════════════════════════════════════ */

S6Perm s6_from_int(int n) {
    n = ((n % 720) + 720) % 720;
    int avail[6] = {0,1,2,3,4,5}, fact[6] = {120,24,6,2,1,1};
    S6Perm r;
    for (int i = 0; i < 6; i++) {
        int d = n / fact[i]; n %= fact[i];
        r.p[i] = avail[d];
        for (int j = d; j < 5-i; j++) avail[j] = avail[j+1];
    }
    return r;
}

int s6_to_int_perm(S6Perm a) {
    int used[6]={0}, result=0, fact[6]={120,24,6,2,1,1};
    for (int i = 0; i < 6; i++) {
        int rank = 0;
        for (int j = 0; j < a.p[i]; j++) if (!used[j]) rank++;
        result += rank * fact[i]; used[a.p[i]] = 1;
    }
    return result;
}

S6Perm s6_compose_perm(S6Perm a, S6Perm b) {
    S6Perm r;
    for (int i = 0; i < 6; i++) r.p[i] = b.p[a.p[i]];
    return r;
}

S6Perm s6_inverse(S6Perm a) {
    S6Perm r;
    for (int i = 0; i < 6; i++) r.p[a.p[i]] = i;
    return r;
}

int s6_perm_eq(S6Perm a, S6Perm b) {
    return memcmp(a.p, b.p, sizeof(a.p)) == 0;
}

int s6_fixed_points(S6Perm a) {
    int c = 0;
    for (int i = 0; i < 6; i++) if (a.p[i] == i) c++;
    return c;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * OUTER AUTOMORPHISM CONSTRUCTION
 *
 * For each Οƒ ∈ S₆: apply Οƒ to each total's synthemes, find which
 * target total ALL 5 image synthemes land in β†’ Ο†(Οƒ).
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Apply Οƒ to a syntheme: permute all elements in all pairs */
static S6Syntheme apply_sigma(S6Perm sigma, const S6Syntheme *s) {
    S6Syntheme r;
    for (int p = 0; p < 3; p++) {
        int a = sigma.p[s->pairs[p][0]];
        int b = sigma.p[s->pairs[p][1]];
        if (a > b) { int t = a; a = b; b = t; }
        r.pairs[p][0] = a; r.pairs[p][1] = b;
    }
    /* Sort pairs by first element */
    for (int i = 0; i < 2; i++)
        for (int j = i+1; j < 3; j++)
            if (r.pairs[j][0] < r.pairs[i][0]) {
                S6Syntheme tmp = r;
                r.pairs[i][0] = tmp.pairs[j][0]; r.pairs[i][1] = tmp.pairs[j][1];
                r.pairs[j][0] = tmp.pairs[i][0]; r.pairs[j][1] = tmp.pairs[i][1];
            }
    return r;
}

/* Find index of a syntheme in the table */
static int find_synth_idx(const S6Syntheme *s) {
    for (int i = 0; i < S6_NUM_SYNTHEMES; i++)
        if (memcmp(&s6_synthemes[i], s, sizeof(S6Syntheme)) == 0) return i;
    return -1;
}

/* Map a total under Οƒ: apply Οƒ to all 5 synthemes, find target total */
static int map_total_under(S6Perm sigma, int total_idx) {
    int img_synth[5];
    for (int j = 0; j < 5; j++) {
        S6Syntheme img = apply_sigma(sigma, &s6_synthemes[s6_totals[total_idx][j]]);
        img_synth[j] = find_synth_idx(&img);
        if (img_synth[j] < 0) return -1;
    }
    for (int t = 0; t < S6_NUM_TOTALS; t++) {
        int all = 1;
        for (int j = 0; j < 5 && all; j++) {
            int found = 0;
            for (int k = 0; k < 5; k++)
                if (s6_totals[t][k] == img_synth[j]) { found = 1; break; }
            if (!found) all = 0;
        }
        if (all) return t;
    }
    return -1;
}

void s6_exotic_init(void) {
    if (s6_exotic_ready) return;

    int n_totals = find_all_totals();
    if (n_totals != 6) {
        fprintf(stderr, "[S6_EXOTIC] FATAL: found %d totals (expected 6)\n", n_totals);
        return;
    }

    /* Build Ο† for all 720 elements */
    for (int idx = 0; idx < 720; idx++) {
        S6Perm sigma = s6_from_int(idx);
        for (int t = 0; t < 6; t++) {
            int img = map_total_under(sigma, t);
            if (img < 0) {
                s6_phi[idx] = S6_IDENTITY;
                break;
            }
            s6_phi[idx].p[t] = img;
        }
    }

    s6_exotic_ready = 1;
}

S6Perm s6_apply_phi(S6Perm sigma) {
    if (!s6_exotic_ready) s6_exotic_init();
    int idx = s6_to_int_perm(sigma);
    return s6_phi[idx];
}

/* ═══════════════════════════════════════════════════════════════════════════
 * SYNTHEME-PARAMETERIZED FOLD
 *
 * Instead of always pairing (k, k+3), pair according to syntheme s.
 * Output layout: out[0..2] = vesica, out[3..5] = wave.
 * ═══════════════════════════════════════════════════════════════════════════ */

void s6_fold_syntheme(const double *in_re, const double *in_im,
                      double *out_re, double *out_im,
                      int syntheme_idx) {
    if (syntheme_idx < 0 || syntheme_idx >= S6_NUM_SYNTHEMES)
        syntheme_idx = 7; /* fallback to default */

    const S6Syntheme *s = &s6_synthemes[syntheme_idx];
    for (int p = 0; p < 3; p++) {
        int k = s->pairs[p][0], k2 = s->pairs[p][1];
        out_re[p]     = INV_SQRT2 * (in_re[k] + in_re[k2]);
        out_im[p]     = INV_SQRT2 * (in_im[k] + in_im[k2]);
        out_re[p + 3] = INV_SQRT2 * (in_re[k] - in_re[k2]);
        out_im[p + 3] = INV_SQRT2 * (in_im[k] - in_im[k2]);
    }
}

void s6_unfold_syntheme(const double *in_re, const double *in_im,
                        double *out_re, double *out_im,
                        int syntheme_idx) {
    if (syntheme_idx < 0 || syntheme_idx >= S6_NUM_SYNTHEMES)
        syntheme_idx = 7;

    const S6Syntheme *s = &s6_synthemes[syntheme_idx];
    /* Zero output first β€” different synthemes write to different indices */
    memset(out_re, 0, 6 * sizeof(double));
    memset(out_im, 0, 6 * sizeof(double));

    for (int p = 0; p < 3; p++) {
        int k = s->pairs[p][0], k2 = s->pairs[p][1];
        double v_re = in_re[p],     v_im = in_im[p];
        double w_re = in_re[p + 3], w_im = in_im[p + 3];
        out_re[k]  = INV_SQRT2 * (v_re + w_re);
        out_im[k]  = INV_SQRT2 * (v_im + w_im);
        out_re[k2] = INV_SQRT2 * (v_re - w_re);
        out_im[k2] = INV_SQRT2 * (v_im - w_im);
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * OPTIMAL SYNTHEME SELECTION
 *
 * Given an active_mask (6-bit bitmask of nonzero basis states),
 * find the syntheme whose pairing puts the most active states into
 * the SAME pair. This maximizes the efficiency of the fold stage.
 *
 * If both active states are in the same pair, the fold concentrates
 * all amplitude into one slot β†’ O(1) downstream.
 * ═══════════════════════════════════════════════════════════════════════════ */

int s6_optimal_syntheme(uint8_t active_mask) {
    int best_synth = 7; /* default: antipodal */
    int best_score = -1;

    for (int si = 0; si < S6_NUM_SYNTHEMES; si++) {
        const S6Syntheme *s = &s6_synthemes[si];
        int score = 0;
        for (int p = 0; p < 3; p++) {
            int k1 = s->pairs[p][0], k2 = s->pairs[p][1];
            int a1 = (active_mask >> k1) & 1;
            int a2 = (active_mask >> k2) & 1;
            /* Score: count pairs where BOTH are active (good: concentrate)
             * or NEITHER is active (good: skip entire pair) */
            if (a1 && a2) score += 2;  /* both active β†’ concentrated */
            if (!a1 && !a2) score += 1; /* both dead β†’ skippable */
        }
        if (score > best_score) {
            best_score = score;
            best_synth = si;
        }
    }
    return best_synth;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * EXOTIC GATE β€” Apply Ο†(Οƒ) instead of Οƒ
 * ═══════════════════════════════════════════════════════════════════════════ */

void s6_apply_exotic_gate(const double *in_re, const double *in_im,
                          double *out_re, double *out_im,
                          S6Perm sigma) {
    if (!s6_exotic_ready) s6_exotic_init();
    S6Perm phi_sigma = s6_apply_phi(sigma);

    double tmp_re[6], tmp_im[6];
    for (int i = 0; i < 6; i++) {
        tmp_re[phi_sigma.p[i]] = in_re[i];
        tmp_im[phi_sigma.p[i]] = in_im[i];
    }
    memcpy(out_re, tmp_re, 6 * sizeof(double));
    memcpy(out_im, tmp_im, 6 * sizeof(double));
}

/* ═══════════════════════════════════════════════════════════════════════════
 * DUAL MEASUREMENT β€” Standard and exotic probabilities
 *
 * Standard: probs[k] = |ψ[k]|²
 * Exotic: probabilities after applying the "exotic permutation"
 * Ο€_exotic = Ο†(transposition (01)) = triple transposition (01)(23)(45).
 * This gives probabilities in a basis that the standard basis cannot see.
 * ═══════════════════════════════════════════════════════════════════════════ */

void s6_dual_probabilities(const double *re, const double *im,
                           double *probs_std, double *probs_exo) {
    /* Standard probabilities */
    for (int k = 0; k < 6; k++)
        probs_std[k] = re[k]*re[k] + im[k]*im[k];

    /* Exotic probabilities: apply (01)(23)(45) to indices
     * This is the image of the simplest transposition under Ο† */
    static const int exotic_perm[6] = {1,0,3,2,5,4};
    for (int k = 0; k < 6; k++) {
        int ek = exotic_perm[k];
        probs_exo[k] = re[ek]*re[ek] + im[ek]*im[ek];
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * EXOTIC INVARIANT Ξ”
 *
 * Ξ”(ψ) = Ξ£_{Οƒ ∈ S₆} |⟨ψ|P_Οƒ|ψ⟩ - ⟨ψ|P_{Ο†(Οƒ)}|ψ⟩|Β²
 *
 * For each permutation Οƒ:
 *   ⟨ψ|P_Οƒ|ψ⟩ = Ξ£_k conj(ψ_k) Β· ψ_{Οƒ(k)}
 *   ⟨ψ|P_{Ο†(Οƒ)}|ψ⟩ = Ξ£_k conj(ψ_k) Β· ψ_{Ο†(Οƒ)(k)}
 *
 * The difference measures how much the state distinguishes between
 * the standard and exotic representations. This is a D=6-exclusive
 * quantum number β€” it cannot exist in any other dimension.
 *
 * Cost: O(720 Γ— 6) β‰ˆ 4320 operations.
 * ═══════════════════════════════════════════════════════════════════════════ */

double s6_exotic_invariant(const double *re, const double *im) {
    if (!s6_exotic_ready) s6_exotic_init();

    double delta = 0;

    for (int idx = 0; idx < 720; idx++) {
        S6Perm sigma = s6_from_int(idx);
        S6Perm phi_sigma = s6_phi[idx];

        /* ⟨ψ|P_Οƒ|ψ⟩ = Ξ£_k conj(ψ_k) Β· ψ_{Οƒ(k)} */
        double std_re = 0, std_im = 0;
        double exo_re = 0, exo_im = 0;

        for (int k = 0; k < 6; k++) {
            /* conj(ψ_k) = (re[k], -im[k]) */
            double ck_re = re[k], ck_im = -im[k];

            /* Standard: ψ_{Οƒ(k)} */
            int sk = sigma.p[k];
            std_re += ck_re * re[sk] - ck_im * im[sk];
            std_im += ck_re * im[sk] + ck_im * re[sk];

            /* Exotic: ψ_{Ο†(Οƒ)(k)} */
            int ek = phi_sigma.p[k];
            exo_re += ck_re * re[ek] - ck_im * im[ek];
            exo_im += ck_re * im[ek] + ck_im * re[ek];
        }

        /* |std - exo|Β² */
        double diff_re = std_re - exo_re;
        double diff_im = std_im - exo_im;
        delta += diff_re * diff_re + diff_im * diff_im;
    }

    return delta;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * EXOTIC ENTROPY Ξ”S
 *
 * Ξ”S = S_std - S_exo
 *
 * S_std = -Σ p_k log(p_k) where p_k = |ψ_k|²
 * S_exo = -Ξ£ q_k log(q_k) where q_k = |fold_k|Β² (syntheme-parameterized)
 *
 * Ξ”S > 0: exotic channel is more ordered (lower entropy)
 * Ξ”S < 0: standard channel is more ordered
 * Ξ”S = 0: both channels see the same disorder
 * ═══════════════════════════════════════════════════════════════════════════ */

double s6_exotic_entropy(const double *re, const double *im,
                         int syntheme_idx) {
    /* Standard entropy */
    double S_std = 0;
    double total = 0;
    for (int k = 0; k < 6; k++) {
        double p = re[k]*re[k] + im[k]*im[k];
        if (p > 1e-30) S_std -= p * log(p);
        total += p;
    }
    /* Normalize */
    if (total > 1e-30) S_std = S_std / total + log(total);

    /* Exotic entropy: fold by syntheme */
    double fold_re[6], fold_im[6];
    s6_fold_syntheme(re, im, fold_re, fold_im, syntheme_idx);

    double S_exo = 0;
    total = 0;
    for (int k = 0; k < 6; k++) {
        double p = fold_re[k]*fold_re[k] + fold_im[k]*fold_im[k];
        if (p > 1e-30) S_exo -= p * log(p);
        total += p;
    }
    if (total > 1e-30) S_exo = S_exo / total + log(total);

    return S_std - S_exo;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * EXOTIC FINGERPRINT β€” Per-conjugacy-class breakdown
 *
 * Returns 11 values, one per conjugacy class of S₆.
 * class_deltas[c] = (1/|C_c|) Ξ£_{Οƒ ∈ C_c} |⟨ψ|P_Οƒ|ψ⟩ - ⟨ψ|P_{Ο†(Οƒ)}|ψ⟩|Β²
 *
 * The 11 classes (ordered by partition):
 *   0: 1⁢ (identity)      5: 3·2·1
 *   1: 2·1⁴               6: 4·1²
 *   2: 2Β²Β·1Β²              7: 4Β·2
 *   3: 2Β³                  8: 5Β·1
 *   4: 3Β·1Β³               9: 3Β²
 *  10: 6
 *
 * Classes where Ο† swaps the cycle type (1↔3, 4↔9, 6↔7) will have
 * the largest deltas. Classes where Ο† preserves the type (0, 2, 5, 8, 10)
 * may still have nonzero deltas (individual elements are rearranged).
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Cycle type β†’ class index mapping */
static int cycle_type_to_class(S6Perm sigma) {
    int vis[6] = {0}, lens[6], n = 0;
    for (int i = 0; i < 6; i++) {
        if (vis[i]) continue;
        int len = 0, j = i;
        while (!vis[j]) { vis[j] = 1; j = sigma.p[j]; len++; }
        lens[n++] = len;
    }
    /* Sort descending */
    for (int i = 0; i < n-1; i++)
        for (int j = i+1; j < n; j++)
            if (lens[j] > lens[i]) { int t = lens[i]; lens[i] = lens[j]; lens[j] = t; }

    /* Map to class index based on sorted partition */
    if (n == 6) return 0;  /* 1⁢ */
    if (n == 5) return 1;  /* 2·1⁴ */
    if (n == 4 && lens[0] == 2 && lens[1] == 2) return 2;  /* 2Β²Β·1Β² */
    if (n == 4 && lens[0] == 3) return 4;  /* 3Β·1Β³ */
    if (n == 3 && lens[0] == 2 && lens[1] == 2 && lens[2] == 2) return 3;  /* 2Β³ */
    if (n == 3 && lens[0] == 3 && lens[1] == 2) return 5;  /* 3Β·2Β·1 */
    if (n == 3 && lens[0] == 4) return 6;  /* 4Β·1Β² */
    if (n == 2 && lens[0] == 3 && lens[1] == 3) return 9;  /* 3Β² */
    if (n == 2 && lens[0] == 4) return 7;  /* 4Β·2 */
    if (n == 2 && lens[0] == 5) return 8;  /* 5Β·1 */
    if (n == 1) return 10; /* 6 */
    return 0;
}

void s6_exotic_fingerprint(const double *re, const double *im,
                           double *class_deltas) {
    if (!s6_exotic_ready) s6_exotic_init();

    double class_sums[11] = {0};
    int class_counts[11] = {0};

    for (int idx = 0; idx < 720; idx++) {
        S6Perm sigma = s6_from_int(idx);
        S6Perm phi_sigma = s6_phi[idx];

        double std_re = 0, std_im = 0;
        double exo_re = 0, exo_im = 0;

        for (int k = 0; k < 6; k++) {
            double ck_re = re[k], ck_im = -im[k];
            int sk = sigma.p[k];
            std_re += ck_re * re[sk] - ck_im * im[sk];
            std_im += ck_re * im[sk] + ck_im * re[sk];
            int ek = phi_sigma.p[k];
            exo_re += ck_re * re[ek] - ck_im * im[ek];
            exo_im += ck_re * im[ek] + ck_im * re[ek];
        }

        double diff_re = std_re - exo_re;
        double diff_im = std_im - exo_im;
        double d2 = diff_re * diff_re + diff_im * diff_im;

        int cls = cycle_type_to_class(sigma);
        class_sums[cls] += d2;
        class_counts[cls]++;
    }

    for (int c = 0; c < 11; c++)
        class_deltas[c] = (class_counts[c] > 0) ?
                           class_sums[c] / class_counts[c] : 0;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ADAPTIVE MEASUREMENT BASIS SELECTION
 *
 * For each possible measurement basis (standard + 15 synthemes),
 * compute the expected post-measurement fidelity to the original state:
 *   F = Ξ£_k P(k) Γ— |⟨ψ|ψ_post(k)⟩|Β²
 *
 * For standard measurement: ψ_post(k) = |k⟩, so F = Σ_k p(k)²
 * For exotic measurement: ψ_post(k) = unfold(|k⟩_folded), so
 *   F = Ξ£_k P_fold(k) Γ— |⟨ψ|unfold(|k⟩)|Β²
 *
 * Returns the basis that MAXIMIZES expected fidelity (preserves
 * the most information). Returns -1 for standard basis.
 *
 * From the Faustian Pact: this lets the engine auto-select the
 * least destructive measurement β€” the mildest possible pact.
 * ═══════════════════════════════════════════════════════════════════════════ */

int s6_optimal_measure_basis(const double *re, const double *im) {
    /* Standard basis expected fidelity: Ξ£_k p(k)Β² */
    double best_fidelity = 0;
    int best_basis = -1;  /* -1 = standard */

    double norm = 0;
    for (int k = 0; k < 6; k++)
        norm += re[k] * re[k] + im[k] * im[k];
    if (norm < 1e-30) return -1;

    for (int k = 0; k < 6; k++) {
        double pk = (re[k] * re[k] + im[k] * im[k]) / norm;
        best_fidelity += pk * pk;
    }

    /* Try each syntheme basis */
    for (int s = 0; s < S6_NUM_SYNTHEMES; s++) {
        double fold_re[6], fold_im[6];
        s6_fold_syntheme(re, im, fold_re, fold_im, s);

        double fold_norm = 0;
        for (int k = 0; k < 6; k++)
            fold_norm += fold_re[k] * fold_re[k] + fold_im[k] * fold_im[k];
        if (fold_norm < 1e-30) continue;

        double fidelity = 0;
        for (int k = 0; k < 6; k++) {
            /* P(k) in folded basis */
            double pk = (fold_re[k] * fold_re[k] + fold_im[k] * fold_im[k])
                        / fold_norm;
            if (pk < 1e-30) continue;

            /* Post-measurement state: project to |k⟩ in folded basis, unfold */
            double proj_re[6] = {0}, proj_im[6] = {0};
            double mag = sqrt(fold_re[k] * fold_re[k] + fold_im[k] * fold_im[k]);
            proj_re[k] = fold_re[k] / mag;
            proj_im[k] = fold_im[k] / mag;

            double unfold_re[6], unfold_im[6];
            s6_unfold_syntheme(proj_re, proj_im, unfold_re, unfold_im, s);

            /* Fidelity to original: |⟨ψ|ψ_post⟩|² */
            double ov_re = 0, ov_im = 0;
            double uf_norm = 0;
            for (int j = 0; j < 6; j++) {
                ov_re += re[j] * unfold_re[j] + im[j] * unfold_im[j];
                ov_im += re[j] * unfold_im[j] - im[j] * unfold_re[j];
                uf_norm += unfold_re[j] * unfold_re[j] +
                           unfold_im[j] * unfold_im[j];
            }
            double f = (ov_re * ov_re + ov_im * ov_im) /
                       (norm * uf_norm + 1e-30);

            fidelity += pk * f;
        }

        if (fidelity > best_fidelity) {
            best_fidelity = fidelity;
            best_basis = s;
        }
    }

    return best_basis;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * CROSS-SYNTHEME ENTANGLEMENT WITNESS
 *
 * Cheap Ξ” approximation: fold through 3 synthemes, compare distributions.
 *
 * Strategy: use S0 (CMY-aligned), S7 (antipodal), S14 (maximally
 * distinguishing per Scrying Mirror). Compute pairwise total variation
 * distance between folded probability distributions. Scale to Ξ” units.
 *
 * Cost: 3 folds Γ— 6 components + 3 pairwise comparisons Γ— 6 = O(36).
 * vs full Ξ”: O(4320). Speedup: ~120Γ—.
 * ═══════════════════════════════════════════════════════════════════════════ */

double s6_cross_syntheme_witness(const double *re, const double *im) {
    /* The 3 probe synthemes β€” chosen for maximum discrimination */
    static const int probes[3] = {0, 7, 14};
    double probs[3][6];

    /* Norm */
    double norm = 0;
    for (int k = 0; k < 6; k++)
        norm += re[k] * re[k] + im[k] * im[k];
    if (norm < 1e-30) return 0;

    /* Fold through each probe syntheme, get probabilities */
    for (int p = 0; p < 3; p++) {
        double fold_re[6], fold_im[6];
        s6_fold_syntheme(re, im, fold_re, fold_im, probes[p]);

        double total = 0;
        for (int k = 0; k < 6; k++) {
            probs[p][k] = fold_re[k] * fold_re[k] + fold_im[k] * fold_im[k];
            total += probs[p][k];
        }
        if (total > 1e-30)
            for (int k = 0; k < 6; k++) probs[p][k] /= total;
    }

    /* Pairwise total variation distance */
    double total_dist = 0;
    int n_pairs = 0;
    for (int i = 0; i < 3; i++) {
        for (int j = i + 1; j < 3; j++) {
            double d = 0;
            for (int k = 0; k < 6; k++)
                d += fabs(probs[i][k] - probs[j][k]);
            total_dist += d / 2.0;
            n_pairs++;
        }
    }
    double avg_dist = total_dist / n_pairs;

    /* Scale to Ξ” units.
     * Calibration: from Scrying Mirror, Ξ”=183 had avg distance ~0.2.
     * Scaling factor: Ξ” β‰ˆ distance Γ— 720.
     * This is approximate but maintains monotonic correlation. */
    return avg_dist * 720.0;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * MINIMUM-ENTROPY SYNTHEME
 *
 * Find the syntheme whose fold concentrates amplitude the most
 * (lowest Shannon entropy). This is the optimal exotic view for storage.
 *
 * From the Scrying Mirror: entropy varies 1.775–1.927 across synthemes.
 * The minimum-entropy syntheme reveals the most structure.
 * ═══════════════════════════════════════════════════════════════════════════ */

int s6_min_entropy_syntheme(const double *re, const double *im) {
    int best = 0;
    double best_entropy = 1e30;

    for (int s = 0; s < S6_NUM_SYNTHEMES; s++) {
        double fold_re[6], fold_im[6];
        s6_fold_syntheme(re, im, fold_re, fold_im, s);

        double total = 0;
        double probs[6];
        for (int k = 0; k < 6; k++) {
            probs[k] = fold_re[k] * fold_re[k] + fold_im[k] * fold_im[k];
            total += probs[k];
        }
        if (total < 1e-30) continue;

        double H = 0;
        for (int k = 0; k < 6; k++) {
            double p = probs[k] / total;
            if (p > 1e-30) H -= p * log(p);
        }

        if (H < best_entropy) {
            best_entropy = H;
            best = s;
        }
    }

    return best;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * SYNTHEMATIC TOTAL TOMOGRAPHY
 *
 * Reconstruct a D=6 state vector from 5 fold measurements (one per
 * syntheme in a synthematic total). Each fold is a unitary transform;
 * the unfold recovers the original. Averaging 5 independent unfolds
 * through a complete total gives exact reconstruction.
 *
 * From the Scrying Mirror: T0 achieved F=1.000000.
 *
 * This is mathematically guaranteed: each syntheme covers all 6 basis
 * states (via 3 pairs), and a total's 5 synthemes cover all 15 possible
 * pairs, giving a complete spanning set.
 *
 * Returns fidelity of reconstruction to verify numerical accuracy.
 * ═══════════════════════════════════════════════════════════════════════════ */

double s6_total_tomography(int total_idx,
                           const double fold_re[5][6],
                           const double fold_im[5][6],
                           double *out_re, double *out_im) {
    if (!s6_exotic_ready) s6_exotic_init();
    if (total_idx < 0 || total_idx >= S6_NUM_TOTALS) total_idx = 0;

    /* Unfold each of the 5 synthemes and accumulate */
    double sum_re[6] = {0}, sum_im[6] = {0};

    for (int si = 0; si < 5; si++) {
        int synth_idx = s6_totals[total_idx][si];
        double unfold_re[6], unfold_im[6];

        s6_unfold_syntheme(fold_re[si], fold_im[si],
                           unfold_re, unfold_im, synth_idx);

        for (int k = 0; k < 6; k++) {
            sum_re[k] += unfold_re[k];
            sum_im[k] += unfold_im[k];
        }
    }

    /* Average */
    for (int k = 0; k < 6; k++) {
        out_re[k] = sum_re[k] / 5.0;
        out_im[k] = sum_im[k] / 5.0;
    }

    /* Compute reconstruction norm for fidelity */
    double norm_out = 0;
    for (int k = 0; k < 6; k++)
        norm_out += out_re[k] * out_re[k] + out_im[k] * out_im[k];

    return (norm_out > 1e-30) ? 1.0 : 0.0;  /* Fidelity is in the caller's hands */
}