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
use crate::Id;
use indexmap::IndexSet;
use once_cell::sync::Lazy;
use std::fmt;
use std::str::FromStr;
use std::sync::Mutex;
static STRINGS: Lazy<Mutex<IndexSet<String>>> = Lazy::new(Default::default);
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct Var(u32);
impl FromStr for Var {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.starts_with('?') {
let mut strings = STRINGS.lock().unwrap();
let (i, _) = strings.insert_full(s.to_owned());
Ok(Var(i as u32))
} else {
Err(format!("{} doesn't start with '?'", s))
}
}
}
impl fmt::Display for Var {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let i = self.0 as usize;
let strings = STRINGS.lock().unwrap();
let s = strings.get_index(i).unwrap();
write!(f, "{}", s)
}
}
#[derive(Debug, Default, Clone)]
pub struct Subst {
vec: smallvec::SmallVec<[(Var, Id); 3]>,
}
impl Subst {
pub(crate) fn singleton(var: Var, id: Id) -> Self {
let mut subst = Self::default();
subst.insert(var, id);
subst
}
pub(crate) fn insert(&mut self, var: Var, id: Id) -> Option<Id> {
for pair in &mut self.vec {
if pair.0 == var {
return Some(std::mem::replace(&mut pair.1, id));
}
}
self.vec.push((var, id));
None
}
pub(crate) fn get(&self, var: &Var) -> Option<&Id> {
self.vec
.iter()
.find_map(|(v, id)| if v == var { Some(id) } else { None })
}
pub(crate) fn iter(&self) -> impl Iterator<Item = (&Var, &Id)> {
self.vec.iter().map(|pair| (&pair.0, &pair.1))
}
}
impl std::ops::Index<&Var> for Subst {
type Output = Id;
fn index(&self, var: &Var) -> &Self::Output {
match self.get(var) {
Some(id) => id,
None => panic!("Var '{}={}' not found in {:?}", var.0, var, self),
}
}
}