diff options
author | JSDurand <mmemmew@gmail.com> | 2023-02-12 12:07:34 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2023-02-12 12:07:34 +0800 |
commit | 987c84f3454c687cca0efe0d471fcf00e052ecab (patch) | |
tree | 04b9cf073a12adfb5d07ae308c3809e88cf4ebd2 /chain/src/item/mod.rs | |
parent | 265ff8f87dc7392fdf701f811eb2bf54d7bc6678 (diff) |
Added the functionality of split or clone.
I need more than the ability to clone nodes: I also need to split the
nodes. Now this seems to be correctly added.
Diffstat (limited to 'chain/src/item/mod.rs')
-rw-r--r-- | chain/src/item/mod.rs | 56 |
1 files changed, 38 insertions, 18 deletions
diff --git a/chain/src/item/mod.rs b/chain/src/item/mod.rs index c614802..284d640 100644 --- a/chain/src/item/mod.rs +++ b/chain/src/item/mod.rs @@ -5,16 +5,6 @@ //! More specifically, it implements the iten derivation forests for //! the machine. -// TODO: Implement an enumeration for Parent or Segment, perhaps -// called PaSe. - -// TODO: Move functions for handling forests, currently contained -// within the method derive to this module, and make them aware of the -// enumeration PaSe. - -// TODO: Implement the Item trait from semirings for the item -// derivation forest, and then we can easily execute items later on. - use graph::{error::Error as GError, GraphLabel, LabelGraph, Parent, ParentsGraph}; use core::borrow::Borrow; @@ -88,7 +78,7 @@ impl core::fmt::Display for ForestLabelType { match self { Self::Packed => write!(f, "packed"), Self::Plain => write!(f, "plain"), - Self::Cloned(index) => write!(f, "the {index}-th clone"), + Self::Cloned(index) => write!(f, "clone({index})"), } } } @@ -102,7 +92,11 @@ pub struct ForestLabel<T: GraphLabel> { impl<T: GraphLabel> core::fmt::Display for ForestLabel<T> { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - writeln!(f, "label: {}, status: {}", self.label, self.status) + if !matches!(self.status, ForestLabelType::Plain) { + write!(f, "{}, {}", self.label, self.status) + } else { + write!(f, "{}", self.label) + } } } @@ -128,6 +122,10 @@ impl core::fmt::Display for ForestLabelError { impl std::error::Error for ForestLabelError {} impl<T: GraphLabel> ForestLabel<T> { + fn new(label: T, status: ForestLabelType) -> Self { + Self { label, status } + } + /// Retrieve the label. pub fn label(&self) -> T { self.label @@ -135,7 +133,7 @@ impl<T: GraphLabel> ForestLabel<T> { /// Return true if and only if this node is packed. pub fn is_packed(&self) -> bool { - matches!(self.status, ForestLabelType::Packed) + self.status == ForestLabelType::Packed } /// Retrieve the optional clone index. @@ -146,12 +144,18 @@ impl<T: GraphLabel> ForestLabel<T> { } } + /// Return true if and only if this node is a plain node. + pub fn is_plain(&self) -> bool { + self.status == ForestLabelType::Plain + } + /// Try to clone a node. pub fn clone<F>(self, forest: &F) -> Result<Self, ForestLabelError> where - F: Forest<T>, + F: LabelGraph<ForestLabel<T>>, { if self.is_packed() { + dbg!(); Err(ForestLabelError::ClonePack) } else { let clone_index = if let Some(old_index) = self.clone_index() { @@ -221,6 +225,13 @@ pub trait Forest<T: GraphLabel>: ParentsGraph + LabelGraph<ForestLabel<T>> { /// label. fn new_leaf(label: T) -> Self; + /// Transform the label at the given node. + fn transform_label( + &mut self, + node_id: usize, + transform: impl FnOnce(T) -> T, + ) -> Result<(), Self::Error>; + /// Detect if the fragment is a prefix of the sub-forest rooted at /// `node_id`. fn is_prefix<F>(&self, node_id: usize, fragment: F) -> Result<bool, Self::Error> @@ -235,13 +246,22 @@ pub trait Forest<T: GraphLabel>: ParentsGraph + LabelGraph<ForestLabel<T>> { /// Clone a node by making a new node and making all the nodes /// that previously pointed to the old node now point to the new /// node, and the new node points to the old node. Return the - /// index of the new node. In addition, if the old node had - /// already been cloned, just return the index of its - /// representative. + /// index of the new node. However, if, and only if, + /// `no_new_clone` is `true`, do not make a new clone; instead + /// return the clone index that would be used if a new clone was + /// made. + /// + /// Also, `preserved_edges_num` many edges out of the old node + /// will be copied to be the children of the new node. /// /// The labels of the representing node and of the cloned node /// will be handled automatically. - fn clone_node(&mut self, node_id: usize) -> Result<usize, Self::Error>; + fn clone_node( + &mut self, + node_id: usize, + preserved_edges_num: usize, + no_new_clone: bool, + ) -> Result<usize, Self::Error>; } pub mod default; |