lexigram_lib/grammar/origin.rs
1// Copyright (c) 2025 Redglyph (@gmail.com). All Rights Reserved.
2
3#![allow(unused)]
4
5use std::collections::HashMap;
6use std::hash::Hash;
7use std::marker::PhantomData;
8use crate::VarId;
9use crate::grammar::GrTree;
10
11#[derive(Clone, Debug)]
12/// Origin from a RuleTreeSet perspective: [Origin<(VarId, usize), FromRTS>](Origin), where
13/// `(VarId, usize)` identifies a node in the processed [RuleTreeSet](crate::grammar::RuleTreeSet):
14/// * [VarId] is the variable
15/// * `usize` is the node index in the [GrTree] of that variable
16///
17/// and associates it with a node `(VarId, usize)` of the original [RuleTreeSet](crate::grammar::RuleTreeSet)
18/// rules after normalization (but keeping the * and + ops).
19pub struct FromRTS;
20
21#[derive(Clone, Debug)]
22/// Origin from a ProdRuleSet perspective: [Origin<VarId, FromPRS>](Origin), where [VarId] identifies
23/// a children nonterminal in the processed [ProdRuleSet](crate::grammar::prs::ProdRuleSet):
24/// * [VarId] is the variable
25///
26/// and associates it with a node `(VarId, usize)` of the original
27/// [RuleTreeSet](crate::grammar::RuleTreeSet) rules after normalization (but keeping the * and + ops).
28///
29/// The alternatives of the ProdRuleSet store their own `(VarId, usize)` links to the original
30/// nodes because it's easier than to track the data when they're moved around.
31pub struct FromPRS;
32
33#[derive(Clone, Debug)]
34pub struct Origin<F, T> {
35 pub trees: Vec<GrTree>,
36 pub map: HashMap<F, (VarId, usize)>,
37 _phantom: PhantomData<T>,
38}
39
40impl<F, T> Origin<F, T> {
41 /// Creates a blank [`Origin`] object.
42 pub fn new() -> Self {
43 Origin {
44 trees: Vec::new(),
45 map: HashMap::new(),
46 _phantom: PhantomData,
47 }
48 }
49
50 /// Creates a blank [`Origin`] object with a tree capacity of `size`. Use this method when
51 /// you can't give the data in a form that suits the other constructors but when you know
52 /// the number of variables.
53 pub fn with_capacity(size: usize) -> Self {
54 Origin {
55 trees: Vec::with_capacity(size),
56 map: HashMap::new(),
57 _phantom: PhantomData,
58 }
59 }
60
61 /// Creates an [`Origin`] object with the given trees and mapping.
62 pub fn from_data(trees: Vec<GrTree>, map: HashMap<F, (VarId, usize)>) -> Self {
63 Origin { trees, map, _phantom: PhantomData }
64 }
65
66 /// Creates an [`Origin`] object with the given trees as mutable reference. It will
67 /// take the content from `trees` to create the object. After that, `trees` is empty.
68 ///
69 /// Use this method to create an [`Origin`] object from another generic form of the
70 /// same type; typically when creating an `Origin<(VarId, AltId), FromPRS>` from an
71 /// `Origin<(VarId, usize), FromRTS>` if you can't move the original.
72 pub fn from_trees_mut(trees: &mut Vec<GrTree>) -> Self {
73 let trees = std::mem::take(trees);
74 Self::from_data(trees, HashMap::new())
75 }
76
77 /// Sets the original [`tree`](GrTree) of nonterminal `var`.
78 pub fn set_tree(&mut self, var: VarId, tree: GrTree) {
79 let var = var as usize;
80 if self.trees.len() <= var {
81 self.trees.resize(var + 1, GrTree::new());
82 }
83 self.trees[var] = tree;
84 }
85
86 /// Gets the original [`GrTree`] of nonterminal `var`, if it exists.
87 pub fn get_tree(&self, var: VarId) -> Option<&GrTree> {
88 self.trees.get(var as usize)
89 }
90}
91
92impl<F, T> Default for Origin<F, T> {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98impl<F: Eq + Hash, T> Origin<F, T> {
99 /// Adds a connection between a `new` node and its `origin` in the original [`GrTree`].
100 ///
101 /// `new` is made up of a nonterminal index and its tree index.
102 pub fn add(&mut self, new: F, origin: (VarId, usize)) {
103 self.map.insert(new, origin);
104 }
105
106 /// Gets the original [`GrTree`] and node index, if they exist, from a `new` node.
107 ///
108 /// `new` is made up of a nonterminal index and its tree index.
109 pub fn get(&self, new: F) -> Option<(&GrTree, usize)> {
110 self.map.get(&new).cloned()
111 .map(|(v, node)| (&self.trees[v as usize], node))
112 }
113}