diff options
author | JSDurand <mmemmew@gmail.com> | 2023-08-01 11:47:44 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2023-08-01 11:47:44 +0800 |
commit | 81854107bcf0b4480cfb11e8af7fec6894240c0c (patch) | |
tree | db85df073d1f5201545aa463ef34307d763e7095 /chain/src/item/default/splone.rs | |
parent | ca56b918b48cc08d8a43660a5e6f82c946fad8a0 (diff) |
Fix some bugs
Some bugs are fixed:
1. If a non-terminal expansion can be reduced immediately, previously
an extra node would be created that had no parents. Now this strange
behaviour is corrected.
2. When performing reductions, a leaf non-terminal node would
previously be regarded as completed. Now we will first try to
complete that node, and then determine if the completion is
successful, and finally determine the completedness according to the
result.
Of course some more tests are still pending, before I can confirm that
no more bugs lurk around.
Diffstat (limited to 'chain/src/item/default/splone.rs')
-rw-r--r-- | chain/src/item/default/splone.rs | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/chain/src/item/default/splone.rs b/chain/src/item/default/splone.rs index 2ac3d73..9da156a 100644 --- a/chain/src/item/default/splone.rs +++ b/chain/src/item/default/splone.rs @@ -125,6 +125,10 @@ impl DefaultForest<ForestLabel<GrammarLabel>> { let new_label = self.create_new_label(node, end, edge_index, None)?; + // if node == 15 { + // dbg!(end, new_label, node_label); + // } + let new_label = match new_label { Eon::Nex(label) => label, Eon::Ex(existing) => { @@ -374,7 +378,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> { /// /// 1. Copy the old label. /// - /// 2. Set the end to `pos`. + /// 2. Set the end to `end`. /// /// 3. Pack the label. /// @@ -412,9 +416,24 @@ impl DefaultForest<ForestLabel<GrammarLabel>> { copied_label.set_end_option(end); - let label = ForestLabel::new(copied_label, ForestLabelType::Packed); + let packed_label = ForestLabel::new(copied_label, ForestLabelType::Packed); + let plain_label = ForestLabel::new(copied_label, ForestLabelType::Plain); + + let root = if let Some(root) = self.root() { + root + } else { + return Ok(Eon::Nex(plain_label)); + }; + + let packed_query = self.query_label(packed_label); + + // We ignore nodes without parents which are not roots. + if matches!(packed_query, Some(packed) if packed == root || + self.parents_of(packed)?.len() > 0) + { + // this is safe because of the 'if' guard + let packed = packed_query.unwrap(); - if let Some(packed) = self.query_label(label) { for child in self.children_of(packed)? { let child_degree = self.degree(child)?; @@ -457,9 +476,13 @@ impl DefaultForest<ForestLabel<GrammarLabel>> { Ok(Eon::Nex(cloned_label)) } else { - let plain_label = ForestLabel::new(copied_label, ForestLabelType::Plain); + let plain_query = self.query_label(plain_label); + + if matches!(plain_query, Some(plain) if plain == root || + self.parents_of(plain)?.len() > 0) + { + let existing = plain_query.unwrap(); - if let Some(existing) = self.query_label(plain_label) { let existing_degree = self.degree(existing)?; if self.has_same_children(existing, node, existing_degree, edge_index + 1)? { @@ -622,7 +645,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> { for parent in parents { let mut parent_label = self .vertex_label(parent)? - .ok_or_else(|| Error::NodeNoLabel(parent))? + .ok_or(Error::NodeNoLabel(parent))? .label(); #[cfg(debug_assertions)] @@ -803,7 +826,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> { for rule_parent in rule_parents { let mut rule_parent_label = self .vertex_label(rule_parent)? - .ok_or_else(|| Error::NodeNoLabel(rule_parent))? + .ok_or(Error::NodeNoLabel(rule_parent))? .label(); #[cfg(debug_assertions)] |