Способ использования цепочек сценариев пассивного режима для развития семантики абстракций
Концептуальная основа
В пассивном режиме система может обобщать конкретный эпизодический опыт в семантические структуры абстракций. Ключевая идея: цепочки связанных кадров ЭП содержат паттерны «условия → действие → эффект», которые можно транслировать в semanticStructure абстрактных образов.
Алгоритм развития semanticStructure из цепочек ЭП
Этап 1: Выявление сценарных цепочек в ЭП
javascript
function extractScenarioChainsFromEpisodes(maxChainLength = 5) {
    var chains = [];
    var episodes = global.Episodes || [];
    
    // Ищем последовательности кадров с ненулевым effect
    for (var i = 0; i < episodes.length; i++) {
        var frame = episodes[i];
        if (!frame || typeof frame.effect !== 'number' || frame.effect === 0) continue;
        
        var chain = [frame];
        var currentPerceptionNode = frame.perceptionNodeId;
        
        // Ищем продолжения цепочки (те же perceptionNodeId или родительские узлы)
        for (var j = i + 1; j < episodes.length && chain.length < maxChainLength; j++) {
            var nextFrame = episodes[j];
            if (!nextFrame) break;
            
            // Критерии связи кадров в цепочку:
            var isRelated = (
                nextFrame.perceptionNodeId === currentPerceptionNode ||  // та же ветка
                isParentNode(nextFrame.perceptionNodeId, currentPerceptionNode) ||  // родительская ветка
                (nextFrame.stimulusImageId === frame.actionImageId)  // стимул = предыдущее действие
            );
            
            if (isRelated && typeof nextFrame.effect === 'number') {
                chain.push(nextFrame);
                currentPerceptionNode = nextFrame.perceptionNodeId;
            }
        }
        
        if (chain.length >= 2) {
            chains.push({
                startIndex: i,
                frames: chain,
                totalEffect: chain.reduce(function(sum, f) { return sum + (f.effect || 0); }, 0),
                perceptionNodeId: chain[0].perceptionNodeId
            });
        }
    }
    
    return chains;
}
Этап 2: Извлечение паттернов из цепочек
javascript
function extractPatternsFromChain(chain) {
    var patterns = [];
    
    for (var i = 0; i < chain.frames.length; i++) {
        var frame = chain.frames[i];
        
        // Паттерн для абстракции восприятия
        if (frame.stimulusImageId) {
            var absPerceptionId = global.findAbstractPerceptionRecordId(
                frame.perceptionNodeId, 
                frame.stimulusImageId
            );
            
            if (absPerceptionId) {
                patterns.push({
                    type: 'perception',
                    abstractId: absPerceptionId,
                    perceptionNodeId: frame.perceptionNodeId,
                    situationId: frame.situationId || 0,
                    ruleKind: 'episodic',
                    stimulusImageId: frame.stimulusImageId,
                    actionImageId: frame.actionImageId || null,
                    effect: frame.effect,
                    responseStimulusImageId: frame.responseStimulusImageId || null,
                    chainPosition: i,
                    chainTotalEffect: chain.totalEffect
                });
            }
        }
        
        // Паттерн для абстракции действия
        if (frame.actionImageId) {
            var absActionId = global.findAbstractActionRecordId(
                frame.perceptionNodeId, 
                frame.actionImageId
            );
            
            if (absActionId) {
                patterns.push({
                    type: 'action',
                    abstractId: absActionId,
                    perceptionNodeId: frame.perceptionNodeId,
                    situationId: frame.situationId || 0,
                    ruleKind: 'episodic',
                    stimulusImageId: frame.stimulusImageId || null,
                    actionImageId: frame.actionImageId,
                    effect: frame.effect,
                    responseStimulusImageId: frame.responseStimulusImageId || null,
                    chainPosition: i,
                    chainTotalEffect: chain.totalEffect
                });
            }
        }
    }
    
    return patterns;
}
Этап 3: Обновление semanticStructure абстракций
javascript
function updateAbstractSemanticStructureFromPatterns(patterns) {
    var updatedCount = 0;
    
    for (var p = 0; p < patterns.length; p++) {
        var pattern = patterns[p];
        var absRecord = null;
        
        // Находим запись абстракции
        if (pattern.type === 'perception') {
            absRecord = global.Info_findAbstractPerceptionImage(pattern.abstractId);
        } else if (pattern.type === 'action') {
            absRecord = global.Info_findAbstractActionImage(pattern.abstractId);
        }
        
        if (!absRecord || !absRecord.semanticStructure) continue;
        
        // Ищем существующий кадр в semanticStructure по условиям
        var existingFrameIndex = -1;
        var frames = absRecord.semanticStructure.frames || [];
        
        for (var f = 0; f < frames.length; f++) {
            var fr = frames[f];
            if (fr.perceptionNodeId === pattern.perceptionNodeId &&
                fr.situationId === pattern.situationId) {
                existingFrameIndex = f;
                break;
            }
        }
        
        // Создаём новый кадр или обновляем существующий
        var newFrame = {
            perceptionNodeId: pattern.perceptionNodeId,
            situationId: pattern.situationId,
            ruleKind: pattern.ruleKind,
            stimulusImageId: pattern.stimulusImageId,
            actionImageId: pattern.actionImageId,
            effect: pattern.effect,
            responseStimulusImageId: pattern.responseStimulusImageId,
            updatedAt: Date.now(),
            // Новые поля для цепочек:
            chainEffect: pattern.chainTotalEffect,
            chainPosition: pattern.chainPosition
        };
        
        if (existingFrameIndex >= 0) {
            // Обновляем существующий: усредняем effect, сохраняем лучший chainEffect
            var existing = frames[existingFrameIndex];
            existing.effect = (existing.effect + pattern.effect) / 2;
            if (!existing.chainEffect || pattern.chainTotalEffect > existing.chainEffect) {
                existing.chainEffect = pattern.chainTotalEffect;
            }
            existing.updatedAt = Date.now();
        } else {
            // Добавляем новый кадр
            frames.push(newFrame);
            updatedCount++;
        }
        
        absRecord.semanticStructure.frames = frames;
        global.memDirty = true;
    }
    
    return updatedCount;
}
Этап 4: Интеграция в пассивный режим
javascript
// В goals.js: PassiveMode_processUnderstandingModels()
function PassiveMode_processUnderstandingModels() {
    if (!global.InfoPicture || global.InfoPicture.mode !== 'passive') return;
    
    // 1. Извлекаем сценарные цепочки из ЭП
    var chains = extractScenarioChainsFromEpisodes(5);
    if (!chains || chains.length === 0) return;
    
    // 2. Извлекаем паттерны из цепочек
    var allPatterns = [];
    for (var c = 0; c < chains.length; c++) {
        var patterns = extractPatternsFromChain(chains[c]);
        allPatterns = allPatterns.concat(patterns);
    }
    
    // 3. Обновляем semanticStructure абстракций
    var updated = updateAbstractSemanticStructureFromPatterns(allPatterns);
    
    // 4. Логирование для отладки
    if (updated > 0 && typeof global.Consciousness_cycleAppendLog === 'function') {
        var mainCycle = global.Consciousness_getMainCycle();
        if (mainCycle) {
            global.Consciousness_cycleAppendLog(
                mainCycle,
                'Пассивный режим: обновлено ' + updated + ' кадров semanticStructure из ' + 
                chains.length + ' цепочек ЭП (' + allPatterns.length + ' паттернов).',
                global.cpuls,
                { force: true }
            );
        }
    }
    
    // 5. Сохранение изменений
    if (updated > 0 && typeof global.AbstractImages_flushIndexedDB === 'function') {
        global.AbstractImages_flushIndexedDB();
    }
}
Дополнительные механизмы развития
4.1: Приоритизация цепочек по суммарному эффекту
javascript
function prioritizeChainsByEffect(chains) {
    chains.sort(function(a, b) {
        // Положительные цепочки приоритетнее
        if (a.totalEffect > 0 && b.totalEffect <= 0) return -1;
        if (a.totalEffect <= 0 && b.totalEffect > 0) return 1;
        // Сортировка по абсолютной величине эффекта
        return Math.abs(b.totalEffect) - Math.abs(a.totalEffect);
    });
    
    // Обрабатываем только топ-3 цепочки за один проход пассивного режима
    return chains.slice(0, 3);
}
4.2: Обобщение по родительским узлам дерева восприятия
javascript
function generalizePatternToParentNodes(pattern) {
    var generalized = [pattern];
    var currentNodeId = pattern.perceptionNodeId;
    
    // Поднимаемся по дереву до 3 уровней вверх
    for (var level = 0; level < 3; level++) {
        var parentNode = global.PerceptionTree_getNode(currentNodeId);
        if (!parentNode || !parentNode.parentId || parentNode.parentId === 0) break;
        
        generalized.push({
            type: pattern.type,
            abstractId: pattern.abstractId,
            perceptionNodeId: parentNode.parentId,  // обобщённый узел
            situationId: pattern.situationId,
            ruleKind: 'episodic_generalized',
            stimulusImageId: pattern.stimulusImageId,
            actionImageId: pattern.actionImageId,
            effect: pattern.effect * 0.7,  // снижаем вес для обобщённых правил
            chainPosition: pattern.chainPosition,
            chainTotalEffect: pattern.chainTotalEffect
        });
        
        currentNodeId = parentNode.parentId;
    }
    
    return generalized;
}
4.3: Слияние дублирующихся кадров semanticStructure
javascript
function mergeDuplicateSemanticFrames(absRecord) {
    if (!absRecord || !absRecord.semanticStructure || 
        !Array.isArray(absRecord.semanticStructure.frames)) {
        return 0;
    }
    
    var frames = absRecord.semanticStructure.frames;
    var merged = 0;
    
    // Группируем по ключу (perceptionNodeId + situationId)
    var grouped = {};
    for (var i = 0; i < frames.length; i++) {
        var key = frames[i].perceptionNodeId + '|' + frames[i].situationId;
        if (!grouped[key]) {
            grouped[key] = [];
        }
        grouped[key].push(frames[i]);
    }
    
    // Сливаем дубликаты
    var newFrames = [];
    for (var k in grouped) {
        var group = grouped[k];
        if (group.length === 1) {
            newFrames.push(group[0]);
        } else {
            // Усредняем effect, сохраняем максимальный chainEffect
            var mergedFrame = Object.assign({}, group[0]);
            mergedFrame.effect = group.reduce(function(sum, f) { 
                return sum + (f.effect || 0); 
            }, 0) / group.length;
            mergedFrame.chainEffect = Math.max.apply(null, 
                group.map(function(f) { return f.chainEffect || 0; })
            );
            newFrames.push(mergedFrame);
            merged++;
        }
    }
    
    absRecord.semanticStructure.frames = newFrames;
    return merged;
}

Точки интеграции в существующий код
Модуль
Функция
Изменение
goals.js
PassiveMode_processUnderstandingModels()
Вызов extractScenarioChainsFromEpisodes() + updateAbstractSemanticStructureFromPatterns()
abstract_images.js
AbstractImages_cloneFromEpisodeFrame()
Добавление полей chainEffect, chainPosition в кадр semanticStructure
episodic_memory.js
EpisodicMemory_onPulse()
Флаг episodesChanged для триггера обработки в пассивном режиме
puls.js
sep_of_puls()
Вызов PassiveMode_processUnderstandingModels() только в пассивном режиме