summaryrefslogtreecommitdiff
path: root/chain/src/item/mod.rs
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2023-02-12 12:07:34 +0800
committerJSDurand <mmemmew@gmail.com>2023-02-12 12:07:34 +0800
commit987c84f3454c687cca0efe0d471fcf00e052ecab (patch)
tree04b9cf073a12adfb5d07ae308c3809e88cf4ebd2 /chain/src/item/mod.rs
parent265ff8f87dc7392fdf701f811eb2bf54d7bc6678 (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.rs56
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;