1use std::{
2 borrow::Cow,
3 ops::{Index, IndexMut},
4};
5
6#[cfg(feature = "mem_dbg")]
7use mem_dbg::{MemDbg, MemSize};
8
9use crate::{BoxSlice, IString, NonMaxU32, StringTable, TiVec};
10
11use super::{PatternIdx, ProofIdx, QuantIdx, TermIdx};
12
13#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[derive(Debug)]
17pub struct Quantifier {
18 pub kind: QuantKind,
19 pub num_vars: NonMaxU32,
20 pub term: TermIdx,
21 pub vars: Option<VarNames>,
22}
23
24impl Quantifier {
25 pub fn is_lambda(&self) -> bool {
26 matches!(self.kind, QuantKind::Lambda(_))
27 }
28}
29
30#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33#[derive(Debug, Clone, PartialEq, Eq, Hash)]
34pub enum QuantKind {
35 Lambda(BoxSlice<ProofIdx>),
36 NamedQuant(IString),
37 UnnamedQuant {
39 name: IString,
40 id: usize,
41 },
42}
43
44impl QuantKind {
45 pub(crate) fn parse(strings: &mut StringTable, value: &str) -> Self {
46 match QuantKindParse::parse(value) {
47 QuantKindParse::Named(name) => Self::NamedQuant(IString(strings.get_or_intern(name))),
48 QuantKindParse::Unnamed { name, id } => Self::UnnamedQuant {
49 name: IString(strings.get_or_intern(name)),
50 id,
51 },
52 }
53 }
54
55 pub fn parse_existing(strings: &StringTable, value: &str) -> Option<Self> {
56 match QuantKindParse::parse(value) {
57 QuantKindParse::Named(name) => Some(Self::NamedQuant(IString(strings.get(name)?))),
58 QuantKindParse::Unnamed { name, id } => Some(Self::UnnamedQuant {
59 name: IString(strings.get(name)?),
60 id,
61 }),
62 }
63 }
64
65 pub fn user_name(&self) -> Option<IString> {
66 match self {
67 Self::NamedQuant(name) => Some(*name),
68 _ => None,
69 }
70 }
71
72 pub fn name<'a>(&self, strings: &'a StringTable) -> Option<Cow<'a, str>> {
73 match self {
74 Self::NamedQuant(name) => Some(Cow::Borrowed(&strings[**name])),
75 Self::UnnamedQuant { name, id } => {
76 Some(Cow::Owned(format!("{}!{id}", &strings[**name])))
77 }
78 Self::Lambda(_) => None,
79 }
80 }
81}
82
83enum QuantKindParse<'a> {
84 Named(&'a str),
85 Unnamed { name: &'a str, id: usize },
86}
87
88impl<'a> QuantKindParse<'a> {
89 fn parse(value: &'a str) -> Self {
93 let mut split = value.split('!');
94 let name = split.next().expect(value);
95 split
96 .next()
97 .and_then(|id| id.parse::<usize>().ok())
98 .map_or(Self::Named(value), |id| Self::Unnamed { name, id })
99 }
100}
101
102#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
103#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
104#[derive(Debug)]
105pub enum VarNames {
106 TypeOnly(BoxSlice<IString>),
107 NameAndType(Box<[(IString, IString)]>),
108}
109impl VarNames {
110 pub fn get_type<'a>(
111 strings: &'a StringTable,
112 this: Option<&Self>,
113 idx: usize,
114 ) -> Option<&'a str> {
115 this.as_ref().map(|this| {
116 let ty = match this {
117 Self::TypeOnly(names) => names[idx],
118 Self::NameAndType(names) => names[idx].1,
119 };
120 &strings[*ty]
121 })
122 }
123
124 pub fn is_empty(&self) -> bool {
125 self.len() == 0
126 }
127 pub fn len(&self) -> usize {
128 match self {
129 Self::TypeOnly(names) => names.len(),
130 Self::NameAndType(names) => names.len(),
131 }
132 }
133}
134
135#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
136#[cfg_attr(feature = "mem_dbg", copy_type)]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
139pub struct QuantPat {
140 pub quant: QuantIdx,
141 pub pat: Option<PatternIdx>,
142}
143
144#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
145#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
146#[derive(Debug, Clone)]
147pub struct QuantPatVec<T>(pub TiVec<QuantIdx, PatVec<T>>);
148
149#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
150#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
151#[derive(Debug, Clone)]
152pub struct PatVec<T> {
153 pub(crate) mbqi: T,
154 pub(crate) pats: TiVec<PatternIdx, T>,
155}
156
157impl<T> Index<QuantPat> for QuantPatVec<T> {
158 type Output = T;
159 fn index(&self, index: QuantPat) -> &Self::Output {
160 &self.0[index.quant][index.pat]
161 }
162}
163
164impl<T> IndexMut<QuantPat> for QuantPatVec<T> {
165 fn index_mut(&mut self, index: QuantPat) -> &mut Self::Output {
166 &mut self.0[index.quant][index.pat]
167 }
168}
169
170impl<T> QuantPatVec<T> {
171 pub fn iter_enumerated(&self) -> impl Iterator<Item = (QuantPat, &T)> {
172 let quants = self.0.iter_enumerated();
173 quants.flat_map(move |(quant, data)| {
174 data.iter_enumerated()
175 .map(move |(pat, data)| (QuantPat { quant, pat }, data))
176 })
177 }
178}
179
180impl<T> Index<Option<PatternIdx>> for PatVec<T> {
181 type Output = T;
182 fn index(&self, index: Option<PatternIdx>) -> &Self::Output {
183 if let Some(pattern) = index {
184 &self.pats[pattern]
185 } else {
186 &self.mbqi
187 }
188 }
189}
190
191impl<T> IndexMut<Option<PatternIdx>> for PatVec<T> {
192 fn index_mut(&mut self, index: Option<PatternIdx>) -> &mut Self::Output {
193 if let Some(pattern) = index {
194 &mut self.pats[pattern]
195 } else {
196 &mut self.mbqi
197 }
198 }
199}
200
201impl<T> PatVec<T> {
202 pub fn iter_enumerated(&self) -> impl Iterator<Item = (Option<PatternIdx>, &T)> {
203 let mbqi = core::iter::once((None, &self.mbqi));
204 let pats = self.pats.iter_enumerated();
205 let pats = pats.map(|(pat, data)| (Some(pat), data));
206 mbqi.chain(pats)
207 }
208}