首页 理论 架构 工程 文档 白皮书 著作 研究 案例 下载 博客 关于 开始使用 →

第226章 LearningRepository——学习、更新、能力变化与知识变化

第226章 LearningRepository——学习、更新、能力变化与知识变化

226.1 LearningRepository定义

在ICAI体系中,第207章LearningEngine负责学习计算,第208章UpdateEngine负责已经确认变化的正式应用。

因此,LearningRepository处于学习计算结果与持久化数据之间。

其核心定义为:

LearningRepository=LearningSave+LearningQuery+UpdateRecord+CapabilityChange+KnowledgeChangeLearningRepository = LearningSave + LearningQuery + UpdateRecord + CapabilityChange + KnowledgeChange

进一步形式化:

LR=(L,U,ΔC,ΔK,Q,P,H,T)LR=(L,U,\Delta C,\Delta K,Q,P,H,T)

其中:

  • LL:Learning,学习记录;
  • UU:Update,更新记录;
  • ΔC\Delta C:Capability Change,能力变化;
  • ΔK\Delta K:Knowledge Change,知识变化;
  • QQ:Query,查询;
  • PP:Persistence,持久化;
  • HH:History,变化历史;
  • TT:Time,时间。

这里必须首先明确:

LearningRepository不是LearningEngine,也不是UpdateEngine。

LearningEngine负责:

反馈
↓
历史
↓
记忆
↓
经验
↓
学习计算
↓
学习结果
↓
更新候选

UpdateEngine负责:

更新候选
↓
验证
↓
条件检查
↓
规则检查
↓
正式更新
↓
更新结果

LearningRepository负责:

学习记录保存
更新记录保存
能力变化保存
知识变化保存
历史查询
结果查询

完整关系:

Feedback
    ↓
Memory
    ↓
Experience
    ↓
LearningEngine
    ↓
Learning Result
    ↓
LearningRepository
    ↓
MySQL

Learning Result
    ↓
UpdateEngine
    ↓
Update Result
    ↓
LearningRepository
    ↓
MySQL

226.2 学习Domain Object

第181章和第184章已经建立Learning概念。

ICAI中的学习不是神经网络训练,而是基于实际事实、反馈、历史、记忆、经验和验证结果,对未来认知计算基础进行确定性的结构变化计算。

学习可以表示为:

L=(I,T,O,B,N,R,V,Tm)L=(I,T,O,B,N,R,V,T_m)

其中:

  • II:Learning ID;
  • TT:Learning Type;
  • OO:Target Object;
  • BB:Before,变化前;
  • NN:New,新的内容;
  • RR:Reason,变化原因;
  • VV:Verification,验证状态;
  • TmT_m:学习时间。

例如:

Learning L-001

Target:
Method-M1

Before:
Resource >= 1

New:
Resource >= 2

Reason:
Previous execution failed because resource was insufficient

Verification:
Passed

Repository保存的是这个学习事实。

它不负责重新判断:

Resource >= 2

是否正确。

这个判断已经属于LearningEngine、Verification体系和UpdateEngine的职责。


226.3 学习记录与更新记录的区别

Learning和Update不能合并。

Learning回答:

从实际经验中发现了什么需要改变?

Update回答:

已确认的变化如何正式应用到系统结构?

因此:

Learning≠UpdateLearning \neq Update

例如:

Execution Failure
    ↓
Diagnosis
    ↓
Experience
    ↓
Learning

产生:

“Method-M1可能需要Resource >= 2”

这只是学习结果。

然后:

Learning Candidate
    ↓
UpdateEngine
    ↓
Verification
    ↓
Method-M1正式修改

这才形成Update。

所以:

Learning Candidate
≠
Applied Update

LearningRepository应该同时保存这两个过程。


226.4 Update记录

更新记录可以定义:

U=(ID,T,O,B,N,R,V,S,Tm)U=(ID,T,O,B,N,R,V,S,T_m)

其中:

  • IDID:Update ID;
  • TT:Update Type;
  • OO:Update Target;
  • BB:Before;
  • NN:New;
  • RR:Reason;
  • VV:Verification;
  • SS:Update State;
  • TmT_m:Update Time。

例如:

Update U-001

Target:
Method-M1

Before:
Resource >= 1

After:
Resource >= 2

Reason:
Verified execution history

State:
completed

Verification:
passed

这里的Update记录描述:

Before→AfterBefore \rightarrow After

而不是只保存最终值。


226.5 能力变化

能力变化是LearningRepository的重要数据。

第159章定义:

C=(T,Co,S,R,V)C=(T,Co,S,R,V)

其中:

  • TT:Capability Type;
  • CoCo:Condition;
  • SS:State;
  • RR:Range;
  • VV:Verification。

能力变化可以定义:

ΔC=(Cb,Ca,R,V,Tm)\Delta C=(C_b,C_a,R,V,T_m)

其中:

  • CbC_b:Capability Before;
  • CaC_a:Capability After;
  • RR:Reason;
  • VV:Verification;
  • TmT_m:Change Time。

例如:

Capability C-001

Before:
Range = 0-100

After:
Range = 0-80

Reason:
Verified actual operating range

Verification:
passed

Repository保存的是能力变化事实。

真正计算:

Ct+ΔC→Ct+1C_t+\Delta C\rightarrow C_{t+1}

属于UpdateEngine。


226.6 能力变化不能直接等同于能力失效

这一点对于ICAI非常重要。

一次执行失败:

Execution
↓
Failure

不能直接得出:

Capability = unavailable

例如:

Capability:
process_object

Execution:
failed

Cause:
resource insufficient

正确路径是:

Failure
↓
Feedback
↓
Diagnosis
↓
Cause = Resource
↓
Repair
↓
Verification

如果能力本身没有被证明发生变化:

ΔC=0\Delta C=0

那么CapabilityRepository不应该被错误更新。

因此:

Failure≠CapabilityInvalidFailure \neq CapabilityInvalid

只有经过:

Evidence
+
Diagnosis
+
Verification
+
Applicable Change

才能形成:

ΔC\Delta C


226.7 知识变化

第174章和第191章定义Knowledge:

K=(S,P,O,C,St)K=(S,P,O,C,S_t)

其中:

  • SS:Subject;
  • PP:Predicate;
  • OO:Object;
  • CC:Condition;
  • StS_t:Knowledge State。

知识变化:

ΔK=(Kb,Ka,R,V,Tm)\Delta K=(K_b,K_a,R,V,T_m)

其中:

  • KbK_b:旧知识;
  • KaK_a:新知识;
  • RR:变化原因;
  • VV:验证;
  • TmT_m:时间。

例如:

Knowledge K-001

Before:
Method-M1
requires
Resource >= 1

After:
Method-M1
requires
Resource >= 2

Reason:
Verified execution result

Verification:
passed

LearningRepository保存:

K_before
K_after
reason
verification
time

而正式Knowledge对象仍然由KnowledgeRepository负责保存。


226.8 LearningRepository与KnowledgeRepository的关系

这里必须保持两个Repository的边界。

LearningRepository
    ↓
保存Knowledge Change Record

而:

KnowledgeRepository
    ↓
保存Current Knowledge

因此:

KnowledgeChangeRecord≠KnowledgeKnowledgeChangeRecord \neq Knowledge

例如:

LearningRepository
    ↓
ΔK:
Resource >= 1
→
Resource >= 2

经过UpdateEngine确认后:

KnowledgeRepository
    ↓
Knowledge:
Resource >= 2

形成:

LearningRepository
        ↓
Knowledge Change
        ↓
UpdateEngine
        ↓
KnowledgeRepository

这比直接让LearningRepository修改Knowledge更加清晰。


226.9 LearningRepository与CapabilityRepository的关系

能力变化同样如此。

LearningRepository保存:

Capability Change Record

CapabilityRepository保存:

Current Capability

因此:

CapabilityChangeRecord≠CapabilityCapabilityChangeRecord \neq Capability

流程:

LearningEngine
    ↓
Capability Change Candidate
    ↓
UpdateEngine
    ↓
Verification
    ↓
CapabilityRepository
    ↓
Current Capability

LearningRepository同时保存变化记录:

Capability Before
Capability After
Reason
Verification
Time

形成完整历史。


226.10 LearningRepository接口

PHP中定义:

interface LearningRepositoryInterface
{
    /* Learning */

    public function findLearningById($id);

    public function findLearningsByIndividualId($individualId);

    public function findLearningsByTarget($targetType, $targetId);

    public function findLearningsByType($type);

    public function findLearningsByState($state);

    public function saveLearning($learning);

    public function updateLearning($learning);

    /* Update */

    public function findUpdateById($id);

    public function findUpdatesByTarget($targetType, $targetId);

    public function findUpdatesByLearningId($learningId);

    public function findUpdatesByState($state);

    public function saveUpdate($update);

    public function updateUpdate($update);

    /* Capability Change */

    public function findCapabilityChanges($capabilityId);

    public function saveCapabilityChange($change);

    /* Knowledge Change */

    public function findKnowledgeChanges($knowledgeId);

    public function saveKnowledgeChange($change);

    /* History */

    public function findLearningHistory($learningId);

    public function findUpdateHistory($updateId);
}

这里的接口体现:

Learning+Update+ΔCapability+ΔKnowledge+HistoryLearning + Update + \Delta Capability + \Delta Knowledge + History


226.11 LearningMapper

class LearningMapper
{
    public function toDomain($row)
    {
        if (!$row) {
            return null;
        }

        return array(
            'id' => $row['id'],
            'learning_code' => $row['learning_code'],
            'individual_id' => $row['individual_id'],
            'learning_type' => $row['learning_type'],
            'target_type' => $row['target_type'],
            'target_id' => $row['target_id'],
            'before_data' => $this->decode(
                $row['before_data']
            ),
            'new_data' => $this->decode(
                $row['new_data']
            ),
            'reason' => $row['reason'],
            'verification' => $this->decode(
                $row['verification_data']
            ),
            'state' => $row['state'],
            'created_at' => $row['created_at'],
            'updated_at' => $row['updated_at']
        );
    }

    public function toPersistence($learning)
    {
        return array(
            'learning_code' => $learning['learning_code'],
            'individual_id' => $learning['individual_id'],
            'learning_type' => $learning['learning_type'],
            'target_type' => $learning['target_type'],
            'target_id' => $learning['target_id'],
            'before_data' => isset($learning['before_data'])
                ? json_encode($learning['before_data'])
                : null,
            'new_data' => isset($learning['new_data'])
                ? json_encode($learning['new_data'])
                : null,
            'reason' => isset($learning['reason'])
                ? $learning['reason']
                : null,
            'verification_data' =>
                isset($learning['verification'])
                ? json_encode($learning['verification'])
                : null,
            'state' => $learning['state']
        );
    }

    protected function decode($value)
    {
        if ($value === null || $value === '') {
            return array();
        }

        $data = json_decode($value, true);

        return is_array($data) ? $data : $value;
    }
}

226.12 UpdateMapper

class UpdateMapper
{
    public function toDomain($row)
    {
        if (!$row) {
            return null;
        }

        return array(
            'id' => $row['id'],
            'update_code' => $row['update_code'],
            'learning_id' => $row['learning_id'],
            'target_type' => $row['target_type'],
            'target_id' => $row['target_id'],
            'update_type' => $row['update_type'],
            'before_data' => $this->decode(
                $row['before_data']
            ),
            'after_data' => $this->decode(
                $row['after_data']
            ),
            'reason' => $row['reason'],
            'verification' => $this->decode(
                $row['verification_data']
            ),
            'state' => $row['state'],
            'created_at' => $row['created_at']
        );
    }

    public function toPersistence($update)
    {
        return array(
            'update_code' => $update['update_code'],
            'learning_id' => isset($update['learning_id'])
                ? $update['learning_id']
                : null,
            'target_type' => $update['target_type'],
            'target_id' => $update['target_id'],
            'update_type' => $update['update_type'],
            'before_data' => isset($update['before_data'])
                ? json_encode($update['before_data'])
                : null,
            'after_data' => isset($update['after_data'])
                ? json_encode($update['after_data'])
                : null,
            'reason' => isset($update['reason'])
                ? $update['reason']
                : null,
            'verification_data' =>
                isset($update['verification'])
                ? json_encode($update['verification'])
                : null,
            'state' => $update['state']
        );
    }

    protected function decode($value)
    {
        if ($value === null || $value === '') {
            return array();
        }

        $data = json_decode($value, true);

        return is_array($data) ? $data : $value;
    }
}

226.13 CapabilityChangeMapper

class CapabilityChangeMapper
{
    public function toPersistence($change)
    {
        return array(
            'capability_id' => $change['capability_id'],
            'learning_id' => isset($change['learning_id'])
                ? $change['learning_id']
                : null,
            'before_data' => isset($change['before'])
                ? json_encode($change['before'])
                : null,
            'after_data' => isset($change['after'])
                ? json_encode($change['after'])
                : null,
            'reason' => isset($change['reason'])
                ? $change['reason']
                : null,
            'verification_data' =>
                isset($change['verification'])
                ? json_encode($change['verification'])
                : null
        );
    }

    public function toDomain($row)
    {
        if (!$row) {
            return null;
        }

        return array(
            'id' => $row['id'],
            'capability_id' => $row['capability_id'],
            'learning_id' => $row['learning_id'],
            'before' => $this->decode(
                $row['before_data']
            ),
            'after' => $this->decode(
                $row['after_data']
            ),
            'reason' => $row['reason'],
            'verification' => $this->decode(
                $row['verification_data']
            ),
            'created_at' => $row['created_at']
        );
    }

    protected function decode($value)
    {
        if (!$value) {
            return array();
        }

        $data = json_decode($value, true);

        return is_array($data) ? $data : $value;
    }
}

226.14 KnowledgeChangeMapper

class KnowledgeChangeMapper
{
    public function toPersistence($change)
    {
        return array(
            'knowledge_id' => $change['knowledge_id'],
            'learning_id' => isset($change['learning_id'])
                ? $change['learning_id']
                : null,
            'before_data' => isset($change['before'])
                ? json_encode($change['before'])
                : null,
            'after_data' => isset($change['after'])
                ? json_encode($change['after'])
                : null,
            'reason' => isset($change['reason'])
                ? $change['reason']
                : null,
            'verification_data' =>
                isset($change['verification'])
                ? json_encode($change['verification'])
                : null
        );
    }

    public function toDomain($row)
    {
        if (!$row) {
            return null;
        }

        return array(
            'id' => $row['id'],
            'knowledge_id' => $row['knowledge_id'],
            'learning_id' => $row['learning_id'],
            'before' => $this->decode(
                $row['before_data']
            ),
            'after' => $this->decode(
                $row['after_data']
            ),
            'reason' => $row['reason'],
            'verification' => $this->decode(
                $row['verification_data']
            ),
            'created_at' => $row['created_at']
        );
    }

    protected function decode($value)
    {
        if (!$value) {
            return array();
        }

        $data = json_decode($value, true);

        return is_array($data) ? $data : $value;
    }
}

226.15 MySQL数据表:learning_records

CREATE TABLE learning_records (
    id BIGINT NOT NULL AUTO_INCREMENT,
    learning_code VARCHAR(100) NOT NULL,
    individual_id BIGINT NOT NULL,
    learning_type VARCHAR(100) NOT NULL,
    target_type VARCHAR(100) NOT NULL,
    target_id BIGINT NOT NULL,
    before_data TEXT,
    new_data TEXT,
    reason TEXT,
    verification_data TEXT,
    state VARCHAR(50) NOT NULL,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY uk_learning_code (learning_code),
    KEY idx_learning_individual (individual_id),
    KEY idx_learning_target (target_type, target_id),
    KEY idx_learning_type (learning_type),
    KEY idx_learning_state (state)
);

该表保存的是:

LearningRecordLearningRecord

而不是当前Knowledge或Capability。


226.16 MySQL数据表:update_records

CREATE TABLE update_records (
    id BIGINT NOT NULL AUTO_INCREMENT,
    update_code VARCHAR(100) NOT NULL,
    learning_id BIGINT NULL,
    target_type VARCHAR(100) NOT NULL,
    target_id BIGINT NOT NULL,
    update_type VARCHAR(100) NOT NULL,
    before_data TEXT,
    after_data TEXT,
    reason TEXT,
    verification_data TEXT,
    state VARCHAR(50) NOT NULL,
    created_at DATETIME NOT NULL,
    updated_at DATETIME NOT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY uk_update_code (update_code),
    KEY idx_update_learning (learning_id),
    KEY idx_update_target (target_type, target_id),
    KEY idx_update_state (state)
);

226.17 MySQL数据表:capability_change_history

CREATE TABLE capability_change_history (
    id BIGINT NOT NULL AUTO_INCREMENT,
    capability_id BIGINT NOT NULL,
    learning_id BIGINT NULL,
    before_data TEXT,
    after_data TEXT,
    reason TEXT,
    verification_data TEXT,
    created_at DATETIME NOT NULL,
    PRIMARY KEY (id),
    KEY idx_capability_change_capability (
        capability_id
    ),
    KEY idx_capability_change_learning (
        learning_id
    )
);

226.18 MySQL数据表:knowledge_change_history

CREATE TABLE knowledge_change_history (
    id BIGINT NOT NULL AUTO_INCREMENT,
    knowledge_id BIGINT NOT NULL,
    learning_id BIGINT NULL,
    before_data TEXT,
    after_data TEXT,
    reason TEXT,
    verification_data TEXT,
    created_at DATETIME NOT NULL,
    PRIMARY KEY (id),
    KEY idx_knowledge_change_knowledge (
        knowledge_id
    ),
    KEY idx_knowledge_change_learning (
        learning_id
    )
);

226.19 LearningRepository完整实现

下面实现Repository核心方法。

class MySQLLearningRepository
    implements LearningRepositoryInterface
{
    protected $pdo;

    protected $learningMapper;

    protected $updateMapper;

    protected $capabilityChangeMapper;

    protected $knowledgeChangeMapper;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;

        $this->learningMapper =
            new LearningMapper();

        $this->updateMapper =
            new UpdateMapper();

        $this->capabilityChangeMapper =
            new CapabilityChangeMapper();

        $this->knowledgeChangeMapper =
            new KnowledgeChangeMapper();
    }

    /*
     * ============================================================
     * Learning
     * ============================================================
     */

    public function findLearningById($id)
    {
        $sql = "
            SELECT *
            FROM learning_records
            WHERE id = :id
            LIMIT 1
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':id' => $id
        ));

        return $this->learningMapper->toDomain(
            $stmt->fetch(PDO::FETCH_ASSOC)
        );
    }

    public function findLearningsByIndividualId(
        $individualId
    ) {
        $sql = "
            SELECT *
            FROM learning_records
            WHERE individual_id = :individual_id
            ORDER BY id DESC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':individual_id' => $individualId
        ));

        return $this->mapLearningRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function findLearningsByTarget(
        $targetType,
        $targetId
    ) {
        $sql = "
            SELECT *
            FROM learning_records
            WHERE target_type = :target_type
              AND target_id = :target_id
            ORDER BY id DESC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':target_type' => $targetType,
            ':target_id' => $targetId
        ));

        return $this->mapLearningRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function findLearningsByType($type)
    {
        $sql = "
            SELECT *
            FROM learning_records
            WHERE learning_type = :learning_type
            ORDER BY id DESC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':learning_type' => $type
        ));

        return $this->mapLearningRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function findLearningsByState($state)
    {
        $sql = "
            SELECT *
            FROM learning_records
            WHERE state = :state
            ORDER BY id DESC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':state' => $state
        ));

        return $this->mapLearningRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function saveLearning($learning)
    {
        $this->validateLearning($learning);

        $data =
            $this->learningMapper
                ->toPersistence($learning);

        $sql = "
            INSERT INTO learning_records
            (
                learning_code,
                individual_id,
                learning_type,
                target_type,
                target_id,
                before_data,
                new_data,
                reason,
                verification_data,
                state,
                created_at,
                updated_at
            )
            VALUES
            (
                :learning_code,
                :individual_id,
                :learning_type,
                :target_type,
                :target_id,
                :before_data,
                :new_data,
                :reason,
                :verification_data,
                :state,
                NOW(),
                NOW()
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':learning_code' =>
                $data['learning_code'],

            ':individual_id' =>
                $data['individual_id'],

            ':learning_type' =>
                $data['learning_type'],

            ':target_type' =>
                $data['target_type'],

            ':target_id' =>
                $data['target_id'],

            ':before_data' =>
                $data['before_data'],

            ':new_data' =>
                $data['new_data'],

            ':reason' =>
                $data['reason'],

            ':verification_data' =>
                $data['verification_data'],

            ':state' =>
                $data['state']
        ));

        return $this->pdo->lastInsertId();
    }

    public function updateLearning($learning)
    {
        if (!isset($learning['id'])) {
            throw new InvalidArgumentException(
                'Learning ID is required.'
            );
        }

        $data =
            $this->learningMapper
                ->toPersistence($learning);

        $sql = "
            UPDATE learning_records
            SET
                new_data = :new_data,
                reason = :reason,
                verification_data = :verification_data,
                state = :state,
                updated_at = NOW()
            WHERE id = :id
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':id' => $learning['id'],
            ':new_data' => $data['new_data'],
            ':reason' => $data['reason'],
            ':verification_data' =>
                $data['verification_data'],
            ':state' => $data['state']
        ));
    }

    /*
     * ============================================================
     * Update
     * ============================================================
     */

    public function findUpdateById($id)
    {
        $sql = "
            SELECT *
            FROM update_records
            WHERE id = :id
            LIMIT 1
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':id' => $id
        ));

        return $this->updateMapper->toDomain(
            $stmt->fetch(PDO::FETCH_ASSOC)
        );
    }

    public function findUpdatesByTarget(
        $targetType,
        $targetId
    ) {
        $sql = "
            SELECT *
            FROM update_records
            WHERE target_type = :target_type
              AND target_id = :target_id
            ORDER BY id DESC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':target_type' => $targetType,
            ':target_id' => $targetId
        ));

        return $this->mapUpdateRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function findUpdatesByLearningId($learningId)
    {
        $sql = "
            SELECT *
            FROM update_records
            WHERE learning_id = :learning_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':learning_id' => $learningId
        ));

        return $this->mapUpdateRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function findUpdatesByState($state)
    {
        $sql = "
            SELECT *
            FROM update_records
            WHERE state = :state
            ORDER BY id DESC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':state' => $state
        ));

        return $this->mapUpdateRows(
            $stmt->fetchAll(PDO::FETCH_ASSOC)
        );
    }

    public function saveUpdate($update)
    {
        $this->validateUpdate($update);

        $data =
            $this->updateMapper
                ->toPersistence($update);

        $sql = "
            INSERT INTO update_records
            (
                update_code,
                learning_id,
                target_type,
                target_id,
                update_type,
                before_data,
                after_data,
                reason,
                verification_data,
                state,
                created_at,
                updated_at
            )
            VALUES
            (
                :update_code,
                :learning_id,
                :target_type,
                :target_id,
                :update_type,
                :before_data,
                :after_data,
                :reason,
                :verification_data,
                :state,
                NOW(),
                NOW()
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':update_code' =>
                $data['update_code'],

            ':learning_id' =>
                $data['learning_id'],

            ':target_type' =>
                $data['target_type'],

            ':target_id' =>
                $data['target_id'],

            ':update_type' =>
                $data['update_type'],

            ':before_data' =>
                $data['before_data'],

            ':after_data' =>
                $data['after_data'],

            ':reason' =>
                $data['reason'],

            ':verification_data' =>
                $data['verification_data'],

            ':state' =>
                $data['state']
        ));

        return $this->pdo->lastInsertId();
    }

    public function updateUpdate($update)
    {
        if (!isset($update['id'])) {
            throw new InvalidArgumentException(
                'Update ID is required.'
            );
        }

        $data =
            $this->updateMapper
                ->toPersistence($update);

        $sql = "
            UPDATE update_records
            SET
                after_data = :after_data,
                reason = :reason,
                verification_data = :verification_data,
                state = :state,
                updated_at = NOW()
            WHERE id = :id
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':id' => $update['id'],
            ':after_data' =>
                $data['after_data'],
            ':reason' =>
                $data['reason'],
            ':verification_data' =>
                $data['verification_data'],
            ':state' =>
                $data['state']
        ));
    }

    /*
     * ============================================================
     * Capability Change
     * ============================================================
     */

    public function findCapabilityChanges(
        $capabilityId
    ) {
        $sql = "
            SELECT *
            FROM capability_change_history
            WHERE capability_id = :capability_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':capability_id' => $capabilityId
        ));

        $rows =
            $stmt->fetchAll(PDO::FETCH_ASSOC);

        $result = array();

        foreach ($rows as $row) {
            $result[] =
                $this->capabilityChangeMapper
                    ->toDomain($row);
        }

        return $result;
    }

    public function saveCapabilityChange($change)
    {
        if (!isset($change['capability_id'])) {
            throw new InvalidArgumentException(
                'Capability ID is required.'
            );
        }

        $data =
            $this->capabilityChangeMapper
                ->toPersistence($change);

        $sql = "
            INSERT INTO capability_change_history
            (
                capability_id,
                learning_id,
                before_data,
                after_data,
                reason,
                verification_data,
                created_at
            )
            VALUES
            (
                :capability_id,
                :learning_id,
                :before_data,
                :after_data,
                :reason,
                :verification_data,
                NOW()
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':capability_id' =>
                $data['capability_id'],

            ':learning_id' =>
                $data['learning_id'],

            ':before_data' =>
                $data['before_data'],

            ':after_data' =>
                $data['after_data'],

            ':reason' =>
                $data['reason'],

            ':verification_data' =>
                $data['verification_data']
        ));
    }

    /*
     * ============================================================
     * Knowledge Change
     * ============================================================
     */

    public function findKnowledgeChanges(
        $knowledgeId
    ) {
        $sql = "
            SELECT *
            FROM knowledge_change_history
            WHERE knowledge_id = :knowledge_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':knowledge_id' => $knowledgeId
        ));

        $rows =
            $stmt->fetchAll(PDO::FETCH_ASSOC);

        $result = array();

        foreach ($rows as $row) {
            $result[] =
                $this->knowledgeChangeMapper
                    ->toDomain($row);
        }

        return $result;
    }

    public function saveKnowledgeChange($change)
    {
        if (!isset($change['knowledge_id'])) {
            throw new InvalidArgumentException(
                'Knowledge ID is required.'
            );
        }

        $data =
            $this->knowledgeChangeMapper
                ->toPersistence($change);

        $sql = "
            INSERT INTO knowledge_change_history
            (
                knowledge_id,
                learning_id,
                before_data,
                after_data,
                reason,
                verification_data,
                created_at
            )
            VALUES
            (
                :knowledge_id,
                :learning_id,
                :before_data,
                :after_data,
                :reason,
                :verification_data,
                NOW()
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':knowledge_id' =>
                $data['knowledge_id'],

            ':learning_id' =>
                $data['learning_id'],

            ':before_data' =>
                $data['before_data'],

            ':after_data' =>
                $data['after_data'],

            ':reason' =>
                $data['reason'],

            ':verification_data' =>
                $data['verification_data']
        ));
    }

    /*
     * ============================================================
     * History
     * ============================================================
     */

    public function findLearningHistory(
        $learningId
    ) {
        $sql = "
            SELECT *
            FROM update_records
            WHERE learning_id = :learning_id
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':learning_id' => $learningId
        ));

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function findUpdateHistory($updateId)
    {
        $sql = "
            SELECT *
            FROM update_records
            WHERE id = :id
            LIMIT 1
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':id' => $updateId
        ));

        $row =
            $stmt->fetch(PDO::FETCH_ASSOC);

        return $row ? $row : null;
    }

    /*
     * ============================================================
     * Validation
     * ============================================================
     */

    protected function validateLearning($learning)
    {
        $required = array(
            'learning_code',
            'individual_id',
            'learning_type',
            'target_type',
            'target_id',
            'state'
        );

        foreach ($required as $field) {

            if (!isset($learning[$field])
                || $learning[$field] === '') {

                throw new InvalidArgumentException(
                    'Learning field required: ' . $field
                );
            }
        }
    }

    protected function validateUpdate($update)
    {
        $required = array(
            'update_code',
            'target_type',
            'target_id',
            'update_type',
            'state'
        );

        foreach ($required as $field) {

            if (!isset($update[$field])
                || $update[$field] === '') {

                throw new InvalidArgumentException(
                    'Update field required: ' . $field
                );
            }
        }
    }

    /*
     * ============================================================
     * Mapping helpers
     * ============================================================
     */

    protected function mapLearningRows($rows)
    {
        $result = array();

        foreach ($rows as $row) {
            $result[] =
                $this->learningMapper
                    ->toDomain($row);
        }

        return $result;
    }

    protected function mapUpdateRows($rows)
    {
        $result = array();

        foreach ($rows as $row) {
            $result[] =
                $this->updateMapper
                    ->toDomain($row);
        }

        return $result;
    }
}

以上实现覆盖:

Learning
├── findById
├── findByIndividual
├── findByTarget
├── findByType
├── findByState
├── save
└── update

Update
├── findById
├── findByTarget
├── findByLearning
├── findByState
├── save
└── update

Capability Change
├── find
└── save

Knowledge Change
├── find
└── save

History
├── Learning History
└── Update History

226.20 学习到更新的完整数据流程

完整流程不是:

LearningRepository
↓
直接修改Capability
↓
直接修改Knowledge

而是:

Feedback
    ↓
History
    ↓
Memory
    ↓
Experience
    ↓
LearningEngine
    ↓
Learning Result
    ↓
LearningRepository
    ↓
Update Candidate
    ↓
UpdateEngine
    ↓
Verification
    ↓
Update Result
    ↓
LearningRepository
    ↓
CapabilityRepository / KnowledgeRepository

因此:

Learning→UpdateCandidate→UpdateEngine→VerifiedUpdateLearning \rightarrow UpdateCandidate \rightarrow UpdateEngine \rightarrow VerifiedUpdate


226.21 能力变化完整流程

能力变化:

Execution
    ↓
Result
    ↓
Feedback
    ↓
Diagnosis
    ↓
Experience
    ↓
LearningEngine
    ↓
Capability Change Candidate
    ↓
UpdateEngine
    ↓
Verification
    ↓
CapabilityRepository

同时:

Capability Change
    ↓
LearningRepository
    ↓
Capability Change History

因此当前能力与能力变化历史同时存在:

Capabilityt+ΔC→Capabilityt+1Capability_t + \Delta C \rightarrow Capability_{t+1}

并记录:

History(Ct,Ct+1)History(C_t,C_{t+1})


226.22 知识变化完整流程

知识变化:

Actual Result
    ↓
Feedback
    ↓
Memory
    ↓
Experience
    ↓
LearningEngine
    ↓
Knowledge Change Candidate
    ↓
UpdateEngine
    ↓
Verification
    ↓
KnowledgeRepository

同时:

Knowledge Change
    ↓
LearningRepository
    ↓
Knowledge Change History

因此:

Kt+ΔK→Kt+1K_t+\Delta K\rightarrow K_{t+1}

同时:

KH=(Kt,Kt+1,ΔK,R,V,T)KH=(K_t,K_{t+1},\Delta K,R,V,T)

被保存。


226.23 LearningRepository与UpdateEngine边界

必须严格区分:

LearningEngine

发现变化
计算学习结果
形成Update Candidate

LearningRepository

保存Learning
保存Learning Candidate
保存Change History
查询Learning

UpdateEngine

验证变化
检查条件
检查规则
计算正式Update

CapabilityRepository

保存Current Capability

KnowledgeRepository

保存Current Knowledge

因此:

LearningEngine≠LearningRepositoryLearningEngine \neq LearningRepository LearningRepository≠UpdateEngineLearningRepository \neq UpdateEngine UpdateEngine≠CapabilityRepositoryUpdateEngine \neq CapabilityRepository UpdateEngine≠KnowledgeRepositoryUpdateEngine \neq KnowledgeRepository


226.24 一个完整学习案例

假设:

Method-M1
Condition:
Resource >= 1

实际执行:

Resource = 1
Action-A2
requires Resource = 2

执行失败:

Execution
↓
Failure

反馈:

Expected:
Success

Actual:
Failed

诊断:

Cause:
Resource Insufficient

修复:

Resource
1 → 2

重新执行:

Success

验证:

Passed

LearningEngine发现:

Method-M1
原条件:
Resource >= 1

实际成功条件:
Resource >= 2

形成:

Learning L-001

LearningRepository保存:

Before:
Resource >= 1

New:
Resource >= 2

然后:

Update Candidate
↓
UpdateEngine
↓
Verification
↓
Update U-001

LearningRepository继续保存:

Update U-001

最后:

MethodRepository

保存新的Method。

同时:

KnowledgeRepository

可以保存:

Method-M1 requires Resource >= 2

最终形成:

LearningRepository
        ↓
Learning Record
        ↓
Update Candidate
        ↓
UpdateEngine
        ↓
┌─────────────────────┐
│ MethodRepository    │
│ KnowledgeRepository │
│ CapabilityRepository│
└─────────────────────┘

226.25 最小变化原则

LearningRepository保存的变化应该保持最小化。

例如:

原Capability:

Type:
process

Condition:
Resource >= 1

State:
available

Range:
0-100

如果实际只证明:

Range:
0-80

那么更新候选应该是:

Range:
0-100
→
0-80

而不是同时修改:

Type
Condition
State
Range
Verification

因此:

ΔCactual={ProvenChanges}\Delta C_{actual} = \{ProvenChanges\}

而不是:

ΔC={AllFields}\Delta C = \{AllFields\}

同样:

ΔK={VerifiedKnowledgeChanges}\Delta K = \{VerifiedKnowledgeChanges\}

这保证学习不会造成无依据的大规模结构变化。


226.26 当前值与历史值

LearningRepository必须保存:

Before
After
Reason
Verification
Time

而不能只保存:

After

因为:

After

只能回答:

现在变成什么?

而:

Before + After + Reason

才能回答:

为什么发生变化?

因此:

ChangeRecord=Before+After+Reason+Verification+TimeChangeRecord = Before + After + Reason + Verification + Time

这是ICAI可追溯学习的重要基础。


226.27 学习状态

Learning记录可以使用:

candidate
evaluating
verified
applied
rejected
outdated
conflicted
archived

例如:

candidate
    ↓
evaluating
    ↓
verified
    ↓
applied

如果验证失败:

evaluating
    ↓
rejected

如果后来发现依据已经失效:

verified
    ↓
outdated

LearningRepository负责保存这些状态。

状态合法转换由StateEngine负责计算和验证。


226.28 Update状态

Update记录可以使用:

candidate
validated
applying
applied
verified
failed
rejected
rolled_back
archived

但:

Update = applied

不能自动代表:

Update = verified

所以:

Applied≠VerifiedApplied \neq Verified

正确流程:

Candidate
↓
Validated
↓
Applied
↓
Verification
↓
Verified

226.29 学习历史不能删除

学习历史可能成为未来经验的重要事实来源。

例如:

Learning L-001
Resource >= 1
→
Resource >= 2

未来又发现:

Resource >= 3

不能直接覆盖成:

Resource >= 3

而应该保留:

L-001
1 → 2

L-002
2 → 3

这样才能形成:

L1→L2→L3L_1\rightarrow L_2\rightarrow L_3

这也是ExperienceEngine和LearningEngine分析认知变化过程的重要数据。


226.30 LearningRepository参与的完整闭环

最终完整闭环:

Goal
 ↓
Capability
 ↓
Method
 ↓
Decision
 ↓
Behavior
 ↓
Action
 ↓
Execution
 ↓
Result
 ↓
Feedback
 ↓
History
 ↓
Memory
 ↓
Experience
 ↓
LearningEngine
 ↓
LearningRepository
 ↓
Update Candidate
 ↓
UpdateEngine
 ↓
Verification
 ↓
Update Result
 ↓
LearningRepository
 ↓
Capability / Knowledge / Method Update
 ↓
CapabilityRepository
KnowledgeRepository
MethodRepository
 ↓
New Cognitive State

形成:

Feedback→Memory→Experience→Learning→Update→Capability/Knowledge/MethodFeedback \rightarrow Memory \rightarrow Experience \rightarrow Learning \rightarrow Update \rightarrow Capability/Knowledge/Method


226.31 Repository层完整结构

至此,ICAI Repository体系进一步形成:

IndividualRepository
ObjectRepository
StateRepository
RelationRepository
KnowledgeRepository
GoalRepository
CapabilityRepository
MethodRepository
DecisionRepository
BehaviorActionRepository
MemoryExperienceRepository
RiskConflictRepository
LearningRepository

其中:

KnowledgeRepository
    ↓
Current Knowledge
CapabilityRepository
    ↓
Current Capability
LearningRepository
    ↓
Learning Record
    ↓
Update Record
    ↓
Capability Change History
    ↓
Knowledge Change History

这样避免了Repository之间职责重叠。


226.32 最终架构

ICAI当前形成:

Service→Engine→DomainObject→Repository→MySQL\boxed{ Service \rightarrow Engine \rightarrow DomainObject \rightarrow Repository \rightarrow MySQL }

学习部分进一步细化为:

Feedback→Memory→Experience→LearningEngine→LearningRepository→UpdateEngine→Repository\boxed{ Feedback \rightarrow Memory \rightarrow Experience \rightarrow LearningEngine \rightarrow LearningRepository \rightarrow UpdateEngine \rightarrow Repository }

能力变化:

Learning→ΔC→UpdateEngine→CapabilityRepository\boxed{ Learning \rightarrow \Delta C \rightarrow UpdateEngine \rightarrow CapabilityRepository }

知识变化:

Learning→ΔK→UpdateEngine→KnowledgeRepository\boxed{ Learning \rightarrow \Delta K \rightarrow UpdateEngine \rightarrow KnowledgeRepository }

其中LearningRepository承担:

Learning+UpdateRecord+CapabilityChange+KnowledgeChange+History+Query\boxed{ Learning + UpdateRecord + CapabilityChange + KnowledgeChange + History + Query }

而不承担:

学习计算
知识推理
能力计算
正式更新计算
状态转换计算
最终决策
经验形成

226.33 本章总结

第226章建立了ICAI的LearningRepository。

其核心不是简单地保存一个“学习结果”,而是保存学习过程所产生的认知变化及其与正式更新之间的可追溯关系

四个核心对象必须明确区分:

LearningLearning

表示通过反馈、历史、记忆、经验和验证产生的学习结果;

UpdateUpdate

表示经过验证并正式应用的结构变化;

ΔC\Delta C

表示能力变化记录;

ΔK\Delta K

表示知识变化记录。

因此:

Learning≠UpdateLearning \neq Update ΔC≠Capability\Delta C \neq Capability ΔK≠Knowledge\Delta K \neq Knowledge

最终形成:

LearningEngine
    ↓
Learning
    ↓
LearningRepository
    ↓
Update Candidate
    ↓
UpdateEngine
    ↓
Verified Update
    ↓
CapabilityRepository
KnowledgeRepository
MethodRepository
    ↓
New Cognitive Structure

LearningRepository的最终定义为:

LearningRepository=LearningPersistence+UpdatePersistence+CapabilityChangeHistory+KnowledgeChangeHistory+Query+History\boxed{ LearningRepository = LearningPersistence + UpdatePersistence + CapabilityChangeHistory + KnowledgeChangeHistory + Query + History }

由此,ICAI的学习系统不再是简单的“数据训练”,而是:

实际事实→反馈→记忆→经验→学习→变化候选→验证→正式更新→新的知识/能力/方法结构\boxed{ 实际事实 \rightarrow 反馈 \rightarrow 记忆 \rightarrow 经验 \rightarrow 学习 \rightarrow 变化候选 \rightarrow 验证 \rightarrow 正式更新 \rightarrow 新的知识/能力/方法结构 }

整个过程均可以通过Domain Object、Engine、Service、Repository、MySQL形成可追踪的确定性工程闭环,并保持学习计算、更新计算和数据持久化之间的明确边界。

Leave a Reply

Your email address will not be published. Required fields are marked *