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::hash::{Hash, Hasher};
15use std::rc::Rc;
16use std::sync::atomic::{AtomicU32, Ordering};
17
18use super::declaration::{DeclarationPtr, serde::DeclarationPtrFull};
19use super::serde::{DefaultWithId, HasId, ObjId};
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::{DomainPtr, Expression, GroundDomain, Moo, ReturnType, SubModel, Typeable};
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 Hash for SymbolTable {
96 fn hash<H: Hasher>(&self, state: &mut H) {
97 self.id.hash(state);
98 }
99}
100
101impl SymbolTable {
102 pub fn new() -> SymbolTable {
104 SymbolTable::new_inner(None)
105 }
106
107 pub fn with_parent(parent: Rc<RefCell<SymbolTable>>) -> SymbolTable {
109 SymbolTable::new_inner(Some(parent))
110 }
111
112 fn new_inner(parent: Option<Rc<RefCell<SymbolTable>>>) -> SymbolTable {
113 let id = ID_COUNTER.with(|x| x.fetch_add(1, Ordering::Relaxed));
114 SymbolTable {
115 id,
116 table: BTreeMap::new(),
117 next_machine_name: RefCell::new(0),
118 parent,
119 }
120 }
121
122 pub fn lookup_local(&self, name: &Name) -> Option<DeclarationPtr> {
126 self.table.get(name).cloned()
127 }
128
129 pub fn lookup(&self, name: &Name) -> Option<DeclarationPtr> {
133 self.lookup_local(name).or_else(|| {
134 self.parent
135 .as_ref()
136 .and_then(|parent| (*parent).borrow().lookup(name))
137 })
138 }
139
140 pub fn insert(&mut self, declaration: DeclarationPtr) -> Option<()> {
144 let name = declaration.name().clone();
145 if let Entry::Vacant(e) = self.table.entry(name) {
146 e.insert(declaration);
147 Some(())
148 } else {
149 None
150 }
151 }
152
153 pub fn update_insert(&mut self, declaration: DeclarationPtr) {
155 let name = declaration.name().clone();
156 self.table.insert(name, declaration);
157 }
158
159 pub fn return_type(&self, name: &Name) -> Option<ReturnType> {
161 self.lookup(name).map(|x| x.return_type())
162 }
163
164 pub fn return_type_local(&self, name: &Name) -> Option<ReturnType> {
166 self.lookup_local(name).map(|x| x.return_type())
167 }
168
169 pub fn domain(&self, name: &Name) -> Option<DomainPtr> {
174 if let Name::WithRepresentation(name, _) = name {
175 self.lookup(name)?.domain()
176 } else {
177 self.lookup(name)?.domain()
178 }
179 }
180
181 pub fn resolve_domain(&self, name: &Name) -> Option<Moo<GroundDomain>> {
185 self.domain(name)?.resolve()
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::Machine(m) = *added_var
205 && *m >= *next_var
206 {
207 *next_var = *m + 1;
208 }
209 }
210 }
211
212 self.table.extend(other.table);
213 }
214
215 pub fn gensym(&mut self, domain: &DomainPtr) -> DeclarationPtr {
218 let num = *self.next_machine_name.borrow();
219 *(self.next_machine_name.borrow_mut()) += 1;
220 let decl = DeclarationPtr::new_var(Name::Machine(num), domain.clone());
221 self.insert(decl.clone());
222 decl
223 }
224
225 pub fn parent_mut_unchecked(&mut self) -> &mut Option<Rc<RefCell<SymbolTable>>> {
229 &mut self.parent
230 }
231
232 pub fn get_representation(
238 &self,
239 name: &Name,
240 representation: &[&str],
241 ) -> Option<Vec<Box<dyn Representation>>> {
242 let decl = self.lookup(name)?;
254 let var = &decl.as_var()?;
255
256 var.representations
257 .iter()
258 .find(|x| &x.iter().map(|r| r.repr_name()).collect_vec()[..] == representation)
259 .cloned()
260 }
261
262 pub fn representations_for(&self, name: &Name) -> Option<Vec<Vec<Box<dyn Representation>>>> {
268 let decl = self.lookup(name)?;
269 decl.as_var().map(|x| x.representations.clone())
270 }
271
272 pub fn get_or_add_representation(
289 &mut self,
290 name: &Name,
291 representation: &[&str],
292 ) -> Option<Vec<Box<dyn Representation>>> {
293 let mut decl = self.lookup(name)?;
295
296 if let Some(var) = decl.as_var()
297 && let Some(existing_reprs) = var
298 .representations
299 .iter()
300 .find(|x| &x.iter().map(|r| r.repr_name()).collect_vec()[..] == representation)
301 .cloned()
302 {
303 return Some(existing_reprs); }
305 if representation.len() != 1 {
309 bug!("nested representations not implemented")
310 }
311 let repr_name_str = representation[0];
312 let repr_init_fn = get_repr_rule(repr_name_str)?;
313
314 let reprs = vec![repr_init_fn(name, self)?];
315
316 let mut var = decl.as_var_mut()?;
318
319 for repr_instance in &reprs {
320 repr_instance
321 .declaration_down()
322 .ok()?
323 .into_iter()
324 .for_each(|x| self.update_insert(x));
325 }
326
327 var.representations.push(reprs.clone());
328
329 Some(reprs)
330 }
331}
332
333impl IntoIterator for SymbolTable {
334 type Item = (Name, DeclarationPtr);
335
336 type IntoIter = IntoIter;
337
338 fn into_iter(self) -> Self::IntoIter {
340 IntoIter {
341 inner: self.table.into_iter(),
342 parent: self.parent,
343 }
344 }
345}
346
347pub struct LocalIntoIter {
349 inner: std::collections::btree_map::IntoIter<Name, DeclarationPtr>,
351}
352
353impl Iterator for LocalIntoIter {
354 type Item = (Name, DeclarationPtr);
355
356 fn next(&mut self) -> Option<Self::Item> {
357 self.inner.next()
358 }
359}
360
361pub struct IntoIter {
363 inner: std::collections::btree_map::IntoIter<Name, DeclarationPtr>,
365
366 parent: Option<Rc<RefCell<SymbolTable>>>,
368}
369
370impl Iterator for IntoIter {
371 type Item = (Name, DeclarationPtr);
372
373 fn next(&mut self) -> Option<Self::Item> {
374 let mut val = self.inner.next();
375
376 while val.is_none() {
380 let parent = self.parent.clone()?;
381 let parent_ref = (*parent).borrow();
382 self.parent.clone_from(&parent_ref.parent);
383 self.inner = parent_ref.table.clone().into_iter();
384
385 val = self.inner.next();
386 }
387
388 val
389 }
390}
391
392impl HasId for SymbolTable {
393 fn id(&self) -> ObjId {
394 self.id
395 }
396}
397
398impl DefaultWithId for SymbolTable {
399 fn default_with_id(id: ObjId) -> Self {
400 Self {
401 table: BTreeMap::new(),
402 id,
403 parent: None,
404 next_machine_name: RefCell::new(0),
405 }
406 }
407}
408
409impl Clone for SymbolTable {
410 fn clone(&self) -> Self {
411 Self {
412 table: self.table.clone(),
413 id: ID_COUNTER.with(|x| x.fetch_add(1, Ordering::Relaxed)),
414 parent: self.parent.clone(),
415 next_machine_name: self.next_machine_name.clone(),
416 }
417 }
418}
419
420impl Default for SymbolTable {
421 fn default() -> Self {
422 Self::new_inner(None)
423 }
424}
425
426impl Uniplate for SymbolTable {
427 fn uniplate(&self) -> (Tree<Self>, Box<dyn Fn(Tree<Self>) -> Self>) {
428 let self2 = self.clone();
430 (Tree::Zero, Box::new(move |_| self2.clone()))
431 }
432}
433
434impl Biplate<Expression> for SymbolTable {
435 fn biplate(&self) -> (Tree<Expression>, Box<dyn Fn(Tree<Expression>) -> Self>) {
436 let (child_trees, ctxs): (VecDeque<_>, Vec<_>) = self
437 .table
438 .values()
439 .map(Biplate::<Expression>::biplate)
440 .unzip();
441
442 let tree = Tree::Many(child_trees);
443
444 let self2 = self.clone();
445 let ctx = Box::new(move |tree| {
446 let Tree::Many(exprs) = tree else {
447 panic!("unexpected children structure");
448 };
449
450 let mut self3 = self2.clone();
451 let self3_iter = self3.table.iter_mut();
452 for (ctx, tree, (_, decl)) in izip!(&ctxs, exprs, self3_iter) {
453 *decl = ctx(tree)
456 }
457
458 self3
459 });
460
461 (tree, ctx)
462 }
463}
464
465impl Biplate<Comprehension> for SymbolTable {
466 fn biplate(
467 &self,
468 ) -> (
469 Tree<Comprehension>,
470 Box<dyn Fn(Tree<Comprehension>) -> Self>,
471 ) {
472 let (expr_tree, expr_ctx) = <SymbolTable as Biplate<Expression>>::biplate(self);
473
474 let (exprs, recons_expr_tree) = expr_tree.list();
475
476 let (comprehension_tree, comprehension_ctx) =
477 <VecDeque<Expression> as Biplate<Comprehension>>::biplate(&exprs);
478
479 let ctx = Box::new(move |x| {
480 let exprs = comprehension_ctx(x);
482
483 let expr_tree = recons_expr_tree(exprs);
485
486 expr_ctx(expr_tree)
488 });
489
490 (comprehension_tree, ctx)
491 }
492}
493
494impl Biplate<SubModel> for SymbolTable {
495 fn biplate(&self) -> (Tree<SubModel>, Box<dyn Fn(Tree<SubModel>) -> Self>) {
497 let (expr_tree, expr_ctx) = <SymbolTable as Biplate<Expression>>::biplate(self);
498
499 let (exprs, recons_expr_tree) = expr_tree.list();
500
501 let (submodel_tree, submodel_ctx) =
502 <VecDeque<Expression> as Biplate<SubModel>>::biplate(&exprs);
503
504 let ctx = Box::new(move |x| {
505 let exprs = submodel_ctx(x);
507
508 let expr_tree = recons_expr_tree(exprs);
510
511 expr_ctx(expr_tree)
513 });
514 (submodel_tree, ctx)
515 }
516}