Production,产生式规则。
在开源框架,对应的代码如下:
pub fn add_production(&mut self, production: Production) {
let log = self.log.new(o!("production_id" => production.id.0));
trace!(log, "add production"; "production" => ?production);
if production.conditions.is_empty() {
error!(log, "production has no conditions");
return;
}
//dummy node是整个网络的root节点。获取dummy node id,以遍历整个网络
// rete网络参考《Production Matching for Large Learning Systems》第10页。
let mut current_node_id = self.dummy_node_id;
//每个产生式规则,if conditions then actoion。
// 每个产生式规则,有一个或者多个condtion,逐个condition遍历,加入网络
for i in 0..production.conditions.len() {
//处理第N个条件
let condition = production.conditions[i];
trace!(log, "add condition"; "condition" => ?condition);
// build or share alpha memory
// 从condition生成alpha test
let alpha_test = AlphaTest::from(condition);
// Returns either an existing id or generates a new one.
// 如果alpha test的id是已存的,返回id,如果不存在,生成新id,以便创建新alpha memory
let alpha_memory_id = self
.alpha_tests
.get(&alpha_test)
.cloned()
.unwrap_or_else(|| AlphaMemoryId(self.id_generator.next()));
// If we need a new alpha memory, create it.
// 如果没有alpha memory,创建一个
if !self.alpha_network.contains_key(&alpha_memory_id) {
// Collect the WMEs that should already be in this
// memory.
// 创造一个alpha memory,需要将符合这个alpha test的wme找出来,存储到alpha memory
let wmes = self
.wme_alpha_memories
.iter_mut()
.filter(|(wme, _)| alpha_test.matches(wme))
.map(|(wme, alpha_memories)| {
// Keep track of which alpha memories contain
// this WME.
alpha_memories.push(alpha_memory_id);
*wme
})
.collect();
// 创建 alpha memory
let memory = AlphaMemory {
id: alpha_memory_id,
wmes,
successors: vec![],
test: alpha_test,
};
trace!(log, "created alpha memory";
"test" => %alpha_test,
"id" => ?memory.id,
"wmes" => memory.wmes.len());
// 把alpha test添加到alpha_tests,做记录
self.alpha_tests.insert(alpha_test, memory.id);
// 把alpha memroy添加到 alpha network网络
self.alpha_network.insert(memory.id, memory);
observe!(
log,
Trace::AddedAlphaMemory {
id: alpha_memory_id.0,
test: trace::AlphaMemoryTest {
id: alpha_test.0[0],
attribute: alpha_test.0[1],
value: alpha_test.0[2],
}
}
);
}
//获取 alpha memory,以备后续操作
let alpha_memory = &self.alpha_network[&alpha_memory_id];
// get join tests from condition
// NOTE: This does not handle intra-condition tests.
// todo 这一步比较复杂难解要再考虑考虑
let tests: Vec = condition
.variables() //把condition里的varialbe拿出来处理,一个condition最多有3个variable,最少0个,返回序号和Option值
.filter_map(|(alpha_field, variable_id)| {//注意上一步Item = (usize, VariableID)
production.conditions[0..i]//当前是第i个conditon,取从0到第i-1个condition做处理
.iter()//获取iterator遍历这i个
.rev()// rev之后,反转,也就是说,第0个变成最后一个,第i-1个变成第0个
.enumerate()//枚举出来,有序号。实际上需要就变成了distance,下一步用的到
.find_map(|(distance, prev_condition)| {
prev_condition
.variables()
.find(|(_, var)| *var == variable_id)
.map(|(i, _)| (i, distance))
})
.map(|(beta_field, beta_condition_offset)| JoinNodeTest {
alpha_field,
beta_field,
beta_condition_offset,
})
})
.collect();
// build or share join node
current_node_id = self
.beta_network
.neighbors(current_node_id)
.find(|id| match self.beta_network[*id] {
ReteNode::Join {
alpha_memory: join_amem,
tests: ref join_tests,
} if join_amem == alpha_memory.id && *join_tests == tests => true,
_ => false,
})
.unwrap_or_else(|| {
// If we couldn't find a node to share, create
// one.
let new_node = ReteNode::Join {
alpha_memory: alpha_memory_id,
tests,
};
let id = self.beta_network.add_node(new_node);
self.beta_network.add_edge(current_node_id, id, ());
trace!(log, "create join node"; "id" => ?id);
observe!(
log,
Trace::AddedNode {
id: id.index(),
parent_id: current_node_id.index(),
kind: trace::NodeKind::Join,
children: vec![],
alpha_node_id: Some(alpha_memory_id.0),
}
);
// link to alpha memory
self.alpha_network
.get_mut(&alpha_memory_id)
.unwrap()
.successors
.push(id);
id
});
// build or share beta memory
// 有id,返回id,没有id,创建一个beta节点,返回新id
current_node_id = if i + 1 < production.conditions.len() {
self.beta_network
.neighbors(current_node_id)
.find(|id| match self.beta_network[*id] {
ReteNode::Beta { .. } => true,
_ => false,
})
.unwrap_or_else(|| {
// If we couldn't find a node to share, create
// one.
let new_node = ReteNode::Beta { tokens: vec![] };
let id = self.beta_network.add_node(new_node);
self.beta_network.add_edge(current_node_id, id, ());
trace!(log, "create beta memory"; "id" => ?id);
observe!(
log,
Trace::AddedNode {
id: id.index(),
parent_id: current_node_id.index(),
kind: trace::NodeKind::Beta,
children: vec![],
alpha_node_id: None,
}
);
self.activate_new_node(log.clone(), current_node_id, id);
id
})
} else {
current_node_id
};
}
// Build new production node
// 创建p节点,p节点也就是 产生式规则 节点,一个节点对应一条规则
let new_node = ReteNode::P {
production: production.id,
activations: vec![],
};
let id = self.beta_network.add_node(new_node);
trace!(log, "create p node"; "id" => ?id);
self.beta_network.add_edge(current_node_id, id, ());
self.productions.insert(production.id, id);
trace!(log, "new p node"; "id" => ?id);
observe!(
log,
Trace::AddedNode {
id: id.index(),
parent_id: current_node_id.index(),
kind: trace::NodeKind::P,
children: vec![],
alpha_node_id: None,
}
);
observe!(
log,
Trace::AddedProduction {
id: production.id.0,
p_node_id: id.index(),
}
);
// 激活节点
if current_node_id != self.dummy_node_id {
self.activate_new_node(log.clone(), current_node_id, id);
}
}
这块代码比较复杂,先做一些注释,也比较难以测试。后续再继续分析。