File size: 6,143 Bytes
be99550
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// 🌌 [BioPhys 6.0 μ‚΄μ•„μžˆλŠ” 유기적 μƒνƒœκ³„ μ§„ν™” μ—”μ§„] (src/ecosystem_evolution.rs)
// 1. μ˜λ„μ  λΉ„νŠΈ ν”Œλ¦½ λŒμ—°λ³€μ΄ (Mutation Injector)
// 2. μ„œλΈŒλ£¨ν‹΄ λ¬΄μ˜μ‹ λˆ„μˆ˜ λ―Ήμ„œ (Subconscious Bleed Mixer)
// 3. μ—΄μ„± μœ μ „μž 1-Bit 포자 μ••μΆ• 및 비상 λ°œμ•„κΈ° (Spore Archiver & Germinator)

use std::collections::HashMap;
use std::time::Instant;

/// 🧬 [1. μ˜λ„μ  λΉ„νŠΈ ν”Œλ¦½ λŒμ—°λ³€μ΄ 인젝터]
pub struct MutationInjector {
    pub mutation_rate: f32, // λŒμ—°λ³€μ΄ λ°œμƒ ν™•λ₯  (κΈ°λ³Έ 0.001 = 0.1%)
    pub total_mutations_applied: usize,
    pub beneficial_mutations: usize,
}

impl MutationInjector {
    pub fn new(mutation_rate: f32) -> Self {
        MutationInjector {
            mutation_rate,
            total_mutations_applied: 0,
            beneficial_mutations: 0,
        }
    }

    /// 2-Bit νŒ¨ν‚Ήλœ κ°€μ€‘μΉ˜ 배열에 μ‹€μ œ 우주 방사선(λΉ„νŠΈ ν”Œλ¦½)을 κ°€ν•˜κ³  적합도(Fitness) 평가
    pub fn inject_cosmic_mutation(
        &mut self,
        packed_weights: &mut [u32],
        baseline_energy: f32,
        eval_fn: impl Fn(&[u32]) -> f32,
    ) -> bool {
        let len = packed_weights.len();
        if len == 0 { return false; }

        let mut mutated_indices = Vec::new();
        let mut old_values = Vec::new();

        // 1. ν™•λ₯ μ  λΉ„νŠΈ ν”Œλ¦½ μˆ˜ν–‰
        for i in 0..len {
            let pseudo_rand = ((i as u32 * 1103515245 + 12345) & 0x7FFFFFFF) as f32 / 2147483648.0;
            if pseudo_rand < self.mutation_rate {
                let bit_shift = (i % 16) * 2;
                let flip_mask = 0b11 << bit_shift;
                old_values.push((i, packed_weights[i]));
                packed_weights[i] ^= flip_mask; // 2-Bit μœ„μƒ 전이
                mutated_indices.push(i);
                self.total_mutations_applied += 1;
            }
        }

        if mutated_indices.is_empty() { return false; }

        // 2. 적합도(Fitness) 평가: μƒˆλ‘œμš΄ 계면 μ—λ„ˆμ§€κ°€ 카였슀 졜적점(0.50~0.55)에 더 κ°€κΉŒμ›Œμ‘ŒλŠ”μ§€ 검증
        let new_energy = eval_fn(packed_weights);
        let old_diff = (baseline_energy - 0.52).abs();
        let new_diff = (new_energy - 0.52).abs();

        if new_diff <= old_diff {
            // μœ μ΅ν•œ λŒμ—°λ³€μ΄: 영ꡬ 보쑴(보쑴)
            self.beneficial_mutations += 1;
            true
        } else {
            // ν•΄λ‘œμš΄ λŒμ—°λ³€μ΄: μžμ—° λ„νƒœ (원볡 Rollback)
            for (idx, old_val) in old_values {
                packed_weights[idx] = old_val;
            }
            false
        }
    }
}

/// 🌊 [2. μ„œλΈŒλ£¨ν‹΄ λ¬΄μ˜μ‹ λˆ„μˆ˜ λ―Ήμ„œ (Subconscious Bleed Mixer)]
pub struct SubconsciousMixer {
    pub residual_wave: Vec<f32>, // 이전 μ„Έμ…˜μ˜ λ¬΄μ˜μ‹μ  μž”μ—¬ 진동 νŒŒν˜•
    pub bleed_ratio: f32,        // λˆ„μˆ˜ λΉ„μœ¨ (κΈ°λ³Έ 0.03 = 3%)
    pub session_count: usize,
}

impl SubconsciousMixer {
    pub fn new(dim: usize, bleed_ratio: f32) -> Self {
        SubconsciousMixer {
            residual_wave: vec![0.0; dim],
            bleed_ratio,
            session_count: 0,
        }
    }

    /// 이전 μ„Έμ…˜μ˜ 생각(잠재 μƒνƒœ)을 ν˜„μž¬ 연산에 3% λ―Έμ„Έ κ²°ν•©ν•˜μ—¬ 창의적 영감 μœ λ„
    pub fn blend_subconscious(&mut self, current_hidden: &mut [f32]) {
        self.session_count += 1;
        let len = current_hidden.len().min(self.residual_wave.len());

        for i in 0..len {
            // λ¬΄μ˜μ‹ λˆ„μˆ˜: ν˜„μž¬ 생각 + (이전 μž”μ—¬ κΈ°μ–΅ * 3%)
            let inspiration = self.residual_wave[i] * self.bleed_ratio;
            current_hidden[i] += inspiration;

            // ν˜„μž¬ μƒκ°μ˜ 20%λ₯Ό λ‹€μŒ μ„Έμ…˜μ˜ λ¬΄μ˜μ‹ μž”μ—¬ νŒŒν˜•μœΌλ‘œ μ €μž₯ (감쇠 μ €μž₯)
            self.residual_wave[i] = (self.residual_wave[i] * 0.7) + (current_hidden[i] * 0.2);
        }
    }
}

/// πŸ„ [3. μ—΄μ„± μœ μ „μž 1-Bit 포자 μ••μΆ• 및 비상 λ°œμ•„κΈ°]
pub struct SporeArchiver {
    pub spores: HashMap<String, Vec<u8>>, // 1-Bit 극단 μ••μΆ•λœ 씨앗 μ €μž₯μ†Œ
    pub total_archived: usize,
    pub total_germinated: usize,
}

impl SporeArchiver {
    pub fn new() -> Self {
        SporeArchiver {
            spores: HashMap::new(),
            total_archived: 0,
            total_germinated: 0,
        }
    }

    /// λΉ„ν™œμ„±/μ—΄μ„± κ°€μ€‘μΉ˜ ν…μ„œλ₯Ό 1-Bit 포자(Spore) ν˜•νƒœλ‘œ μ••μΆ• μ €μž₯ (8λ°° μΆ”κ°€ μ••μΆ•)
    pub fn archive_to_spore(&mut self, gene_name: &str, packed_2bit: &[u32]) {
        let mut spore_bytes = Vec::with_capacity(packed_2bit.len() / 2);
        
        for chunk in packed_2bit.chunks(8) {
            let mut byte: u8 = 0;
            for (bit_idx, &word) in chunk.iter().enumerate() {
                // μƒμœ„ ν₯λΆ„μ„± μœ„μƒ(0b11, 0b01)만 1둜 μΆ”μΆœν•˜μ—¬ 1-Bit둜 극단 μ••μΆ•
                let is_active = (word & 0x55555555).count_ones() > 8;
                if is_active {
                    byte |= 1 << bit_idx;
                }
            }
            spore_bytes.push(byte);
        }

        self.spores.insert(gene_name.to_string(), spore_bytes);
        self.total_archived += 1;
    }

    /// λͺ¨λ“œ λΆ•κ΄΄(Mode Collapse) λ˜λŠ” λ―Έμ§€μ˜ ν”„λ‘¬ν”„νŠΈ λ°œμƒ μ‹œ 1-Bit 포자λ₯Ό 2-Bit κ°€μ€‘μΉ˜λ‘œ 즉각 λ°œμ•„(Re-activate)
    pub fn germinate_spore(&mut self, gene_name: &str, output_len: usize) -> Option<Vec<u32>> {
        if let Some(spore_bytes) = self.spores.get(gene_name) {
            self.total_germinated += 1;
            let mut recovered_2bit = Vec::with_capacity(output_len);

            for &b in spore_bytes {
                for bit_idx in 0..8 {
                    if recovered_2bit.len() >= output_len { break; }
                    let bit = (b >> bit_idx) & 1;
                    let reconstructed_word = if bit == 1 { 0x55555555 } else { 0x00000000 };
                    recovered_2bit.push(reconstructed_word);
                }
            }

            while recovered_2bit.len() < output_len {
                recovered_2bit.push(0x00000000);
            }

            Some(recovered_2bit)
        } else {
            None
        }
    }
}