第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形成可追踪的确定性工程闭环,并保持学习计算、更新计算和数据持久化之间的明确边界。