1use crate::bug;
6use crate::representation::{get_repr_rule, Representation};
7
8use super::comprehension::Comprehension;
9use super::serde::{RcRefCellAsId, RcRefCellAsInner};
10use std::cell::RefCell;
11use std::collections::btree_map::Entry;
12use std::collections::BTreeSet;
13use std::collections::{BTreeMap, VecDeque};
14use std::rc::Rc;
15use std::sync::atomic::{AtomicU32, Ordering};
16
17use super::declaration::Declaration;
18use super::serde::{DefaultWithId, HasId, ObjId};
19use super::types::Typeable;
20use itertools::{izip, Itertools as _};
21use serde::{Deserialize, Serialize};
22use serde_with::serde_as;
23use uniplate::Tree;
24use uniplate::{Biplate, Uniplate};
25
26use super::name::Name;
27use super::{Domain, Expression, ReturnType, SubModel};
28use derivative::Derivative;
29
30thread_local! {
39static ID_COUNTER: AtomicU32 = const { AtomicU32::new(0) };
40}
41
42#[derive(Derivative)]
77#[derivative(PartialEq)]
78#[derive(Debug, Eq)]
79#[serde_as]
80#[derive(Serialize, Deserialize)]
81pub struct SymbolTable {
82 #[serde_as(as = "Vec<(_,RcRefCellAsInner)>")]
83 table: BTreeMap<Name, Rc<Declaration>>,
84
85 #[derivative(PartialEq = "ignore")] id: ObjId,
88
89 #[serde_as(as = "Option<RcRefCellAsId>")]
90 parent: Option<Rc<RefCell<SymbolTable>>>,
91
92 next_machine_name: RefCell<i32>,
93}
94
95impl SymbolTable {
96 pub fn new() -> SymbolTable {
98 SymbolTable::new_inner(None)
99 }
100
101 pub fn with_parent(parent: Rc<RefCell<SymbolTable>>) -> SymbolTable {
103 SymbolTable::new_inner(Some(parent))
104 }
105
106 fn new_inner(parent: Option<Rc<RefCell<SymbolTable>>>) -> SymbolTable {
107 let id = ID_COUNTER.with(|x| x.fetch_add(1, Ordering::Relaxed));
108 SymbolTable {
109 id,
110 table: BTreeMap::new(),
111 next_machine_name: RefCell::new(0),
112 parent,
113 }
114 }
115
116 pub fn lookup_local(&self, name: &Name) -> Option<Rc<Declaration>> {
120 self.table.get(name).cloned()
121 }
122
123 pub fn lookup(&self, name: &Name) -> Option<Rc<Declaration>> {
127 self.lookup_local(name).or_else(|| {
128 self.parent
129 .as_ref()
130 .and_then(|parent| (*parent).borrow().lookup(name))
131 })
132 }
133
134 pub fn insert(&mut self, declaration: Rc<Declaration>) -> Option<()> {
138 let name = declaration.name().clone();
139 if let Entry::Vacant(e) = self.table.entry(name) {
140 e.insert(declaration);
141 Some(())
142 } else {
143 None
144 }
145 }
146
147 pub fn update_insert(&mut self, declaration: Rc<Declaration>) {
149 let name = declaration.name().clone();
150 self.table.insert(name, declaration);
151 }
152
153 pub fn return_type(&self, name: &Name) -> Option<ReturnType> {
155 self.lookup(name).and_then(|x| x.return_type())
156 }
157
158 pub fn return_type_local(&self, name: &Name) -> Option<ReturnType> {
160 self.lookup_local(name).and_then(|x| x.return_type())
161 }
162
163 pub fn domain(&self, name: &Name) -> Option<Domain> {
168 if let Name::WithRepresentation(name, _) = name {
173 let decl = self.lookup(name.as_ref())?;
174 decl.domain().cloned()
175 } else {
176 let decl = self.lookup(name)?;
177 decl.domain().cloned()
178 }
179 }
180
181 pub fn resolve_domain(&self, name: &Name) -> Option<Domain> {
185 self.domain(name).map(|domain| domain.resolve(self))
186 }
187
188 pub fn into_iter_local(self) -> LocalIntoIter {
190 LocalIntoIter {
191 inner: self.table.into_iter(),
192 }
193 }
194
195 pub fn extend(&mut self, other: SymbolTable) {
198 if other.table.keys().count() > self.table.keys().count() {
199 let new_vars = other.table.keys().collect::<BTreeSet<_>>();
200 let old_vars = self.table.keys().collect::<BTreeSet<_>>();
201
202 for added_var in new_vars.difference(&old_vars) {
203 let mut next_var = self.next_machine_name.borrow_mut();
204 if let Name::MachineName(m) = *added_var {
205 if *m >= *next_var {
206 *next_var = *m + 1;
207 }
208 }
209 }
210 }
211
212 self.table.extend(other.table);
213 }
214
215 pub fn gensym(&self) -> Name {
217 let num = *self.next_machine_name.borrow();
218 *(self.next_machine_name.borrow_mut()) += 1;
219 Name::MachineName(num) }
221
222 pub fn parent_mut_unchecked(&mut self) -> &mut Option<Rc<RefCell<SymbolTable>>> {
226 &mut self.parent
227 }
228
229 pub fn get_representation(
235 &self,
236 name: &Name,
237 representation: &[&str],
238 ) -> Option<Vec<Box<dyn Representation>>> {
239 let decl = self.lookup(name)?;
251 let var = decl.as_var()?;
252
253 var.representations
254 .iter()
255 .find(|x| &x.iter().map(|r| r.repr_name()).collect_vec()[..] == representation)
256 .cloned()
257 .clone()
258 }
259
260 pub fn representations_for(&self, name: &Name) -> Option<Vec<Vec<Box<dyn Representation>>>> {
266 let decl = self.lookup(name)?;
267 decl.as_var().map(|x| x.representations.clone())
268 }
269
270 pub fn get_or_add_representation(
287 &mut self,
288 name: &Name,
289 representation: &[&str],
290 ) -> Option<Vec<Box<dyn Representation>>> {
291 let decl = self.lookup(name)?;
292 let var = decl.as_var()?;
293
294 var.representations
295 .iter()
296 .find(|x| &x.iter().map(|r| r.repr_name()).collect_vec()[..] == representation)
297 .cloned()
298 .clone()
299 .or_else(|| {
300 let mut decl: Declaration = Rc::unwrap_or_clone(decl);
301 let var = decl.as_var_mut()?;
302
303 if representation.len() != 1 {
306 bug!("nested representations not implemented")
307 }
308
309 let repr_rule = get_repr_rule(representation[0])?;
310
311 let reprs = vec![repr_rule(name, self)?];
312 for repr in &reprs {
313 repr.declaration_down()
314 .ok()
315 .unwrap()
316 .iter()
317 .for_each(|x| self.update_insert(Rc::new(x.clone())));
318 }
319 var.representations.push(reprs.clone());
320
321 self.update_insert(Rc::new(decl));
322 Some(reprs)
323 })
324 }
325}
326
327impl IntoIterator for SymbolTable {
328 type Item = (Name, Rc<Declaration>);
329
330 type IntoIter = IntoIter;
331
332 fn into_iter(self) -> Self::IntoIter {
334 IntoIter {
335 inner: self.table.into_iter(),
336 parent: self.parent,
337 }
338 }
339}
340
341pub struct LocalIntoIter {
343 inner: std::collections::btree_map::IntoIter<Name, Rc<Declaration>>,
345}
346
347impl Iterator for LocalIntoIter {
348 type Item = (Name, Rc<Declaration>);
349
350 fn next(&mut self) -> Option<Self::Item> {
351 self.inner.next()
352 }
353}
354
355pub struct IntoIter {
357 inner: std::collections::btree_map::IntoIter<Name, Rc<Declaration>>,
359
360 parent: Option<Rc<RefCell<SymbolTable>>>,
362}
363
364impl Iterator for IntoIter {
365 type Item = (Name, Rc<Declaration>);
366
367 fn next(&mut self) -> Option<Self::Item> {
368 let mut val = self.inner.next();
369
370 while val.is_none() {
374 let parent = self.parent.clone()?;
375 let parent_ref = (*parent).borrow();
376 self.parent = parent_ref.parent.clone();
377 self.inner = parent_ref.table.clone().into_iter();
378
379 val = self.inner.next();
380 }
381
382 val
383 }
384}
385
386impl HasId for SymbolTable {
387 fn id(&self) -> ObjId {
388 self.id
389 }
390}
391
392impl DefaultWithId for SymbolTable {
393 fn default_with_id(id: ObjId) -> Self {
394 Self {
395 table: BTreeMap::new(),
396 id,
397 parent: None,
398 next_machine_name: RefCell::new(0),
399 }
400 }
401}
402
403impl Clone for SymbolTable {
404 fn clone(&self) -> Self {
405 Self {
406 table: self.table.clone(),
407 id: ID_COUNTER.with(|x| x.fetch_add(1, Ordering::Relaxed)),
408 parent: self.parent.clone(),
409 next_machine_name: self.next_machine_name.clone(),
410 }
411 }
412}
413
414impl Default for SymbolTable {
415 fn default() -> Self {
416 Self::new_inner(None)
417 }
418}
419
420impl Uniplate for SymbolTable {
421 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
422 let self2 = self.clone();
424 (Tree::Zero, Box::new(move |_| self2.clone()))
425 }
426}
427
428impl Biplate<Expression> for SymbolTable {
429 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
430 let (child_trees, ctxs): (VecDeque<_>, Vec<_>) = self
431 .table
432 .values()
433 .map(|decl| <Declaration as Biplate<Expression>>::biplate(decl.as_ref()))
434 .unzip();
435
436 let tree = Tree::Many(child_trees);
437
438 let self2 = self.clone();
439 let ctx = Box::new(move |tree| {
440 let Tree::Many(exprs) = tree else {
441 panic!("unexpected children structure");
442 };
443
444 let mut self3 = self2.clone();
445 let self3_iter = self3.table.iter_mut();
446 for (ctx, tree, (_, decl)) in izip!(&ctxs, exprs, self3_iter) {
447 *decl = Rc::new(ctx(tree));
450 }
451
452 self3
453 });
454
455 (tree, ctx)
456 }
457}
458
459impl Biplate<Comprehension> for SymbolTable {
460 fn biplate(
461 &self,
462 ) -> (
463 Tree<Comprehension>,
464 Box<dyn Fn(Tree<Comprehension>) -> Self>,
465 ) {
466 let (expr_tree, expr_ctx) = <SymbolTable as Biplate<Expression>>::biplate(self);
467 let (comprehension_tree, comprehension_ctx) =
468 <VecDeque<Expression> as Biplate<Comprehension>>::biplate(
469 &expr_tree.into_iter().collect(),
470 );
471
472 let ctx = Box::new(move |x| {
473 expr_ctx(Tree::Many(
474 comprehension_ctx(x).into_iter().map(Tree::One).collect(),
475 ))
476 });
477
478 (comprehension_tree, ctx)
479 }
480}
481
482impl Biplate<SubModel> for SymbolTable {
483 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
485 let (exprs, exprs_ctx) = <SymbolTable as Biplate<Expression>>::biplate(self);
486 let (submodel_tree, submodel_ctx) =
487 <VecDeque<Expression> as Biplate<SubModel>>::biplate(&exprs.into_iter().collect());
488
489 let ctx = Box::new(move |x| {
490 exprs_ctx(Tree::Many(
491 submodel_ctx(x).into_iter().map(Tree::One).collect(),
492 ))
493 });
494 (submodel_tree, ctx)
495 }
496}