1use crate::bug;
6use crate::representation::{Representation, get_repr_rule};
7
8use super::comprehension::Comprehension;
9use super::serde::RcRefCellAsId;
10use std::cell::RefCell;
11use std::collections::BTreeSet;
12use std::collections::btree_map::Entry;
13use std::collections::{BTreeMap, VecDeque};
14use std::rc::Rc;
15use std::sync::atomic::{AtomicU32, Ordering};
16
17use super::declaration::{DeclarationPtr, serde::DeclarationPtrFull};
18use super::serde::{DefaultWithId, HasId, ObjId};
19use super::types::Typeable;
20use itertools::{Itertools as _, izip};
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<(_,DeclarationPtrFull)>")]
83 table: BTreeMap<Name, DeclarationPtr>,
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<DeclarationPtr> {
120 self.table.get(name).cloned()
121 }
122
123 pub fn lookup(&self, name: &Name) -> Option<DeclarationPtr> {
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: DeclarationPtr) -> 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: DeclarationPtr) {
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 self.lookup(name)?.domain()
174 } else {
175 self.lookup(name)?.domain()
176 }
177 }
178
179 pub fn resolve_domain(&self, name: &Name) -> Option<Domain> {
183 self.domain(name).map(|domain| domain.resolve(self))
184 }
185
186 pub fn into_iter_local(self) -> LocalIntoIter {
188 LocalIntoIter {
189 inner: self.table.into_iter(),
190 }
191 }
192
193 pub fn extend(&mut self, other: SymbolTable) {
196 if other.table.keys().count() > self.table.keys().count() {
197 let new_vars = other.table.keys().collect::<BTreeSet<_>>();
198 let old_vars = self.table.keys().collect::<BTreeSet<_>>();
199
200 for added_var in new_vars.difference(&old_vars) {
201 let mut next_var = self.next_machine_name.borrow_mut();
202 if let Name::Machine(m) = *added_var {
203 if *m >= *next_var {
204 *next_var = *m + 1;
205 }
206 }
207 }
208 }
209
210 self.table.extend(other.table);
211 }
212
213 pub fn gensym(&mut self, domain: &Domain) -> DeclarationPtr {
216 let num = *self.next_machine_name.borrow();
217 *(self.next_machine_name.borrow_mut()) += 1;
218 let decl = DeclarationPtr::new_var(Name::Machine(num), domain.clone());
219 self.insert(decl.clone());
220 decl
221 }
222
223 pub fn parent_mut_unchecked(&mut self) -> &mut Option<Rc<RefCell<SymbolTable>>> {
227 &mut self.parent
228 }
229
230 pub fn get_representation(
236 &self,
237 name: &Name,
238 representation: &[&str],
239 ) -> Option<Vec<Box<dyn Representation>>> {
240 let decl = self.lookup(name)?;
252 let var = &decl.as_var()?;
253
254 var.representations
255 .iter()
256 .find(|x| &x.iter().map(|r| r.repr_name()).collect_vec()[..] == representation)
257 .cloned()
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 mut decl = self.lookup(name)?;
293
294 if let Some(var) = decl.as_var() {
295 if let Some(existing_reprs) = var
296 .representations
297 .iter()
298 .find(|x| &x.iter().map(|r| r.repr_name()).collect_vec()[..] == representation)
299 .cloned()
300 {
301 return Some(existing_reprs); }
303 }
304 if representation.len() != 1 {
308 bug!("nested representations not implemented")
309 }
310 let repr_name_str = representation[0];
311 let repr_init_fn = get_repr_rule(repr_name_str)?;
312
313 let reprs = vec![repr_init_fn(name, self)?];
314
315 let mut var = decl.as_var_mut()?;
317
318 for repr_instance in &reprs {
319 repr_instance
320 .declaration_down()
321 .ok()?
322 .into_iter()
323 .for_each(|x| self.update_insert(x));
324 }
325
326 var.representations.push(reprs.clone());
327
328 Some(reprs)
329 }
330}
331
332impl IntoIterator for SymbolTable {
333 type Item = (Name, DeclarationPtr);
334
335 type IntoIter = IntoIter;
336
337 fn into_iter(self) -> Self::IntoIter {
339 IntoIter {
340 inner: self.table.into_iter(),
341 parent: self.parent,
342 }
343 }
344}
345
346pub struct LocalIntoIter {
348 inner: std::collections::btree_map::IntoIter<Name, DeclarationPtr>,
350}
351
352impl Iterator for LocalIntoIter {
353 type Item = (Name, DeclarationPtr);
354
355 fn next(&mut self) -> Option<Self::Item> {
356 self.inner.next()
357 }
358}
359
360pub struct IntoIter {
362 inner: std::collections::btree_map::IntoIter<Name, DeclarationPtr>,
364
365 parent: Option<Rc<RefCell<SymbolTable>>>,
367}
368
369impl Iterator for IntoIter {
370 type Item = (Name, DeclarationPtr);
371
372 fn next(&mut self) -> Option<Self::Item> {
373 let mut val = self.inner.next();
374
375 while val.is_none() {
379 let parent = self.parent.clone()?;
380 let parent_ref = (*parent).borrow();
381 self.parent.clone_from(&parent_ref.parent);
382 self.inner = parent_ref.table.clone().into_iter();
383
384 val = self.inner.next();
385 }
386
387 val
388 }
389}
390
391impl HasId for SymbolTable {
392 fn id(&self) -> ObjId {
393 self.id
394 }
395}
396
397impl DefaultWithId for SymbolTable {
398 fn default_with_id(id: ObjId) -> Self {
399 Self {
400 table: BTreeMap::new(),
401 id,
402 parent: None,
403 next_machine_name: RefCell::new(0),
404 }
405 }
406}
407
408impl Clone for SymbolTable {
409 fn clone(&self) -> Self {
410 Self {
411 table: self.table.clone(),
412 id: ID_COUNTER.with(|x| x.fetch_add(1, Ordering::Relaxed)),
413 parent: self.parent.clone(),
414 next_machine_name: self.next_machine_name.clone(),
415 }
416 }
417}
418
419impl Default for SymbolTable {
420 fn default() -> Self {
421 Self::new_inner(None)
422 }
423}
424
425impl Uniplate for SymbolTable {
426 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
427 let self2 = self.clone();
429 (Tree::Zero, Box::new(move |_| self2.clone()))
430 }
431}
432
433impl Biplate<Expression> for SymbolTable {
434 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
435 let (child_trees, ctxs): (VecDeque<_>, Vec<_>) = self
436 .table
437 .values()
438 .map(Biplate::<Expression>::biplate)
439 .unzip();
440
441 let tree = Tree::Many(child_trees);
442
443 let self2 = self.clone();
444 let ctx = Box::new(move |tree| {
445 let Tree::Many(exprs) = tree else {
446 panic!("unexpected children structure");
447 };
448
449 let mut self3 = self2.clone();
450 let self3_iter = self3.table.iter_mut();
451 for (ctx, tree, (_, decl)) in izip!(&ctxs, exprs, self3_iter) {
452 *decl = ctx(tree)
455 }
456
457 self3
458 });
459
460 (tree, ctx)
461 }
462}
463
464impl Biplate<Comprehension> for SymbolTable {
465 fn biplate(
466 &self,
467 ) -> (
468 Tree<Comprehension>,
469 Box<dyn Fn(Tree<Comprehension>) -> Self>,
470 ) {
471 let (expr_tree, expr_ctx) = <SymbolTable as Biplate<Expression>>::biplate(self);
472
473 let (exprs, recons_expr_tree) = expr_tree.list();
474
475 let (comprehension_tree, comprehension_ctx) =
476 <VecDeque<Expression> as Biplate<Comprehension>>::biplate(&exprs);
477
478 let ctx = Box::new(move |x| {
479 let exprs = comprehension_ctx(x);
481
482 let expr_tree = recons_expr_tree(exprs);
484
485 expr_ctx(expr_tree)
487 });
488
489 (comprehension_tree, ctx)
490 }
491}
492
493impl Biplate<SubModel> for SymbolTable {
494 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
496 let (expr_tree, expr_ctx) = <SymbolTable as Biplate<Expression>>::biplate(self);
497
498 let (exprs, recons_expr_tree) = expr_tree.list();
499
500 let (submodel_tree, submodel_ctx) =
501 <VecDeque<Expression> as Biplate<SubModel>>::biplate(&exprs);
502
503 let ctx = Box::new(move |x| {
504 let exprs = submodel_ctx(x);
506
507 let expr_tree = recons_expr_tree(exprs);
509
510 expr_ctx(expr_tree)
512 });
513 (submodel_tree, ctx)
514 }
515}