1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#![warn(missing_docs)]
//! This module implements the type of items for the chain-rule
//! machine.
//!
//! More specifically, it implements the iten derivation forests for
//! the machine.
use graph::{error::Error as GError, GraphLabel, LabelGraph, Parent, ParentsGraph};
use std::borrow::Borrow;
use forest::{Forest, ForestLabel, ForestLabelError, ForestLabelType};
/// A parent or a virtual segment.
///
/// # Parent
///
/// A parent is a node with an edge index, which represents a certain
/// edge.
///
/// # Virtual Segment
///
/// A virtual segment represents an expansion from a non-terminal by a
/// terminal. We do not directly add this segment when we encounter
/// this expansion at the start because this expansion might contain
/// multiple derivations some of which might not be used.
///
/// If we add the expansion immediately when we encounter it, we have
/// to later discern and delete those unwanted derivations. This is
/// asking for trouble, as I learned from experiences.
///
/// # Empty
///
/// Also this might be empty if it represents the root node.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub enum PaVi {
/// An edge from a node, as the n-th child, along with the
/// nth-child node number.
Parent(usize, usize, usize),
/// A virtual segment from a non-terminal by a terminal, rooted at
/// a node.
///
/// # Tuple elements
///
/// The contained tuple is of the form `(nt, t, node)` , which
/// means a virtually added node at the `node` representing the
/// expansion from the non-terminal `nt` by the terminal `t`.
Virtual(usize, usize, usize),
/// This is an empty segment that represents the root node. This
/// is a special case for the unit state of the chain-rule
/// machine.
#[default]
Empty,
}
impl std::fmt::Display for PaVi {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Parent(node, edge, child) => {
write!(f, "the {edge}-th edge from {node} to {child}")
}
Self::Virtual(nt, t, node) => write!(
f,
"a virtual node for non-terminal {nt} and terminal {t} at node {node}"
),
Self::Empty => write!(f, "empty segment at root"),
}
}
}
impl PaVi {
/// Get the Parent variant.
fn parent(self) -> Option<Parent> {
if let Self::Parent(node, edge, _) = self {
Some(Parent::new(node, edge))
} else {
None
}
}
fn is_virtual(self) -> bool {
matches!(self, Self::Virtual(_, _, _))
}
/// Is this an empty segment?
fn is_empty(self) -> bool {
self == Self::Empty
}
}
pub mod default;
pub mod genins;
pub use genins::generate_fragment;
pub mod reduction;
|