1use core::num::{NonZeroU32, NonZeroUsize};
2
3use num::Num;
4
5use crate::{
6 items::*,
7 parsers::z3::{VersionInfo, Z3LogParser},
8 BigRational, BoxSlice, Error as E, IString, NonMaxU32, Result, StringTable,
9};
10
11use super::{inter_line::LineKind, smt2::EventLog, terms::Terms, Z3Parser};
12
13impl Default for Z3Parser {
14 fn default() -> Self {
15 let mut strings = StringTable::with_hasher(fxhash::FxBuildHasher::default());
16 Self {
17 version_info: VersionInfo::default(),
18 push_count: 0,
19 terms: Terms::default(),
20 synth_terms: Default::default(),
21 quantifiers: Default::default(),
22 insts: Default::default(),
23 egraph: Default::default(),
25 stack: Default::default(),
26 lits: Default::default(),
27 events: EventLog::new(&mut strings),
28 comm: Default::default(),
29 strings,
30 }
31 }
32}
33
34impl Z3Parser {
35 pub(super) fn incremental_mode(&self) -> bool {
36 self.push_count > 0
37 }
38
39 fn parse_new_full_id(&mut self, id: Option<&str>) -> Result<TermId> {
40 let full_id = id.ok_or(E::UnexpectedNewline)?;
41 TermId::parse(&mut self.strings, full_id)
42 }
43
44 fn parse_existing_app(&mut self, id: &str) -> Result<TermIdx> {
45 self.terms
46 .app_terms
47 .parse_existing_id(&mut self.strings, id)
48 }
49
50 fn parse_existing_proof(&mut self, id: &str) -> Result<ProofIdx> {
51 self.terms
52 .proof_terms
53 .parse_existing_id(&mut self.strings, id)
54 }
55
56 fn parse_existing_enode(&mut self, id: &str) -> Result<ENodeIdx> {
57 let idx = self.parse_existing_app(id)?;
58 self.get_existing_enode(idx)
59 }
60
61 fn get_existing_enode(&mut self, idx: TermIdx) -> Result<ENodeIdx> {
62 let res = self.egraph.get_enode(idx, &self.stack);
63 let can_error =
64 self.version_info.is_ge_version(4, 8, 9) && self.version_info.is_le_version(4, 11, 2);
65 if can_error && res.is_err() {
66 self.egraph
70 .new_enode(ENodeBlame::Unknown, idx, NonMaxU32::ZERO, &self.stack)?;
71 self.events.new_enode();
72 return self.egraph.get_enode(idx, &self.stack);
73 }
74 res
75 }
76
77 fn new_term(
78 &mut self,
79 id: TermId,
80 kind: TermKind,
81 child_ids: BoxSlice<TermIdx>,
82 ) -> Result<TermIdx> {
83 let term = Term::new(id, kind, child_ids, |tidx| &self[tidx]);
84 self.terms.app_terms.new_term(term)
85 }
86
87 fn parse_z3_generation<'a>(l: &mut impl Iterator<Item = &'a str>) -> Result<Option<NonMaxU32>> {
88 if let Some(gen) = l.next() {
89 let gen = gen.parse::<NonMaxU32>().map_err(E::InvalidGeneration)?;
90 Ok(Some(gen))
91 } else {
92 Ok(None)
93 }
94 }
95
96 fn map<T, U>(l: impl Iterator<Item = T>, f: impl FnMut(T) -> Result<U>) -> Result<BoxSlice<U>> {
97 l.map(f).collect()
98 }
99 fn gobble_var_names_list<'a>(&mut self, l: impl Iterator<Item = &'a str>) -> Result<VarNames> {
100 let mut t = Self::gobble_tuples::<true>(l);
101 let (first, second) = t.next().ok_or(E::UnexpectedEnd)??;
104 if first.is_empty() {
105 let first = self.mk_string(second);
106 let tuples = t.map(|t| match t? {
107 ("", second) => self.mk_string(second),
108 _ => Err(E::VarNamesListInconsistent),
109 });
110 let types = [first].into_iter().chain(tuples);
111 Ok(VarNames::TypeOnly(types.collect::<Result<_>>()?))
112 } else {
113 fn strip_bars(
114 strings: &mut StringTable,
115 (first, second): (&str, &str),
116 ) -> Result<(IString, IString)> {
117 let first = first
118 .strip_prefix('|')
119 .ok_or(E::VarNamesNoBar)?
120 .strip_suffix('|')
121 .ok_or(E::VarNamesNoBar)?;
122 let second = second
123 .strip_prefix('|')
124 .ok_or(E::VarNamesNoBar)?
125 .strip_suffix('|')
126 .ok_or(E::VarNamesNoBar)?;
127 Ok((
128 IString(strings.get_or_intern(first)),
129 IString(strings.get_or_intern(second)),
130 ))
131 }
132 let first = strip_bars(&mut self.strings, (first, second));
133 let tuples = t.map(|t| strip_bars(&mut self.strings, t?));
134 let names_and_types = [first].into_iter().chain(tuples);
135 Ok(VarNames::NameAndType(
136 names_and_types.collect::<Result<_>>()?,
137 ))
138 }
139 }
140 fn gobble_tuples<'a, const FORMS_EQUAL: bool>(
149 mut l: impl Iterator<Item = &'a str>,
150 ) -> impl Iterator<Item = Result<(&'a str, &'a str)>> {
151 let mut spaces = None;
152 let mut gobble = move || {
153 let Some(first) = l.next() else {
154 return Ok(None);
155 };
156 let (first, second) = if first.ends_with(')') {
157 let spaces = *spaces.get_or_insert(0);
158 if FORMS_EQUAL && spaces != 0 {
159 return Err(E::UnequalTupleForms(spaces, 0));
160 }
161 let mut l = first.split(';');
162 (
163 l.next().ok_or(E::UnexpectedNewline)?,
164 l.next().ok_or(E::UnexpectedNewline)?,
165 )
166 } else {
167 let middle = l.next().ok_or(E::UnexpectedNewline)?;
168 if middle != ";" {
169 let spaces = *spaces.get_or_insert(1);
170 if FORMS_EQUAL && spaces != 1 {
171 return Err(E::UnequalTupleForms(spaces, 1));
172 }
173 (first, middle)
174 } else {
175 let spaces = *spaces.get_or_insert(2);
176 if FORMS_EQUAL && spaces != 2 {
177 return Err(E::UnequalTupleForms(spaces, 2));
178 }
179 let second = l.next().ok_or(E::UnexpectedNewline)?;
180 (first, second)
181 }
182 };
183 let t = (
184 first.strip_prefix('(').ok_or(E::TupleMissingParens)?,
185 second.strip_suffix(')').ok_or(E::TupleMissingParens)?,
186 );
187 Ok(Some(t))
188 };
189 let inverted_gobble = move |_| gobble().map_or_else(|err| Some(Err(err)), |ok| ok.map(Ok));
190 std::iter::repeat(()).map_while(inverted_gobble)
191 }
192 fn append_trans_equality_tuples<'a>(
193 &mut self,
194 l: impl Iterator<Item = &'a str>,
195 mut f: impl FnMut((ENodeIdx, ENodeIdx)) -> Result<()>,
196 ) -> Result<()> {
197 for t in Self::gobble_tuples::<true>(l) {
198 let (from, to) = t?;
199 let from = self.parse_existing_enode(from)?;
200 let to = self.parse_existing_enode(to)?;
201 f((from, to))?;
202 }
203 Ok(())
204 }
205
206 fn iter_until_eq<'a, 's>(
209 l: &'a mut impl Iterator<Item = &'s str>,
210 end: &'a str,
211 ) -> impl Iterator<Item = &'s str> + 'a {
212 l.take_while(move |elem| *elem != end)
213 }
214 fn expect_completed<'s>(mut l: impl Iterator<Item = &'s str>) -> Result<()> {
215 l.next()
216 .map_or(Ok(()), |more| Err(E::ExpectedNewline(more.to_string())))
217 }
218
219 fn mk_string(&mut self, s: &str) -> Result<IString> {
220 Ok(IString(self.strings.try_get_or_intern(s)?))
221 }
222
223 fn quant_or_lamda(
224 &mut self,
225 full_id: TermId,
226 child_ids: BoxSlice<TermIdx>,
227 num_vars: NonMaxU32,
228 kind: QuantKind,
229 ) -> Result<()> {
230 let qidx = self.quantifiers.next_key();
231 let tidx = self.new_term(full_id, TermKind::Quant(qidx), child_ids)?;
232 let q = Quantifier {
233 num_vars,
234 term: tidx,
235 kind,
236 vars: None,
237 };
238 self.quantifiers.raw.try_reserve(1)?;
239 let qidx2 = self.quantifiers.push_and_get_key(q);
240 debug_assert_eq!(qidx, qidx2);
241 Ok(())
242 }
243
244 fn parse_arith(meaning: &str) -> Result<BigRational> {
245 let (rest, num) = Self::parse_arith_inner(meaning)?;
246 debug_assert!(rest.is_empty());
247 Ok(num.into())
248 }
249 fn parse_arith_inner(meaning: &str) -> Result<(&str, num::BigRational)> {
250 let Some(meaning) = meaning.strip_prefix('(') else {
251 let end = meaning
253 .bytes()
254 .position(|b| !b.is_ascii_digit())
255 .unwrap_or(meaning.len());
256 assert_ne!(end, 0);
257 let value = meaning[..end]
258 .parse::<num::BigUint>()
259 .map_err(E::ParseBigUintError)?;
260 let value = num::BigRational::from(num::BigInt::from(value));
261 return Ok((&meaning[end..], value));
262 };
263 let error = || E::ParseError(meaning.to_owned());
264 let space = meaning.bytes().position(|b| b == b' ').ok_or_else(error)?;
265 let (op, mut rest) = (&meaning[..space], &meaning[space..]);
266 let mut arguments = Vec::new();
267 while let Some(r) = rest.strip_prefix(' ') {
268 let (r, num) = Self::parse_arith_inner(r)?;
269 arguments.push(num);
270 rest = r;
271 }
272 rest = rest.strip_prefix(')').ok_or_else(error)?;
273 match op {
274 "+" => Ok((rest, arguments.into_iter().sum())),
275 "-" if arguments.len() == 1 => Ok((rest, -arguments.into_iter().next().unwrap())),
276 "-" if arguments.len() == 2 => {
277 let mut args = arguments.into_iter();
278 Ok((rest, args.next().unwrap() - args.next().unwrap()))
279 }
280 "*" => Ok((rest, arguments.into_iter().product())),
281 "/" if arguments.len() == 2 => {
282 let mut args = arguments.into_iter();
283 Ok((rest, args.next().unwrap() / args.next().unwrap()))
284 }
285 _ => Err(error()),
286 }
287 }
288
289 fn parse_literal<'a>(
290 &mut self,
291 l: &mut impl Iterator<Item = &'a str>,
292 ) -> Result<Option<(Assignment, Option<ENodeIdx>)>> {
293 let Some(lit) = l.next() else {
294 return Ok(None);
295 };
296 let (lit, value) = match lit {
297 "true" | "false" => return Err(E::BoolLiteral),
299 "(not" => {
300 let lit = l.next().ok_or(E::UnexpectedNewline)?;
301 let lit = lit.strip_suffix(')').ok_or(E::TupleMissingParens)?;
302 (lit, false)
303 }
304 _ => (lit, true),
305 };
306 let literal = self.parse_existing_app(lit)?;
307 let enode = self.get_existing_enode(literal).ok();
308 Ok(Some((Assignment { literal, value }, enode)))
309 }
310
311 fn parse_bool_literal<'a>(
320 version_info: &VersionInfo,
321 l: &mut impl Iterator<Item = &'a str>,
322 ) -> Result<Option<(Option<NonZeroU32>, bool)>> {
323 let Some(lit) = l.next() else {
324 return Ok(None);
325 };
326 match lit {
327 "" => {
328 debug_assert_eq!(l.next().filter(|n| !n.is_empty()), None);
329 return Ok(None);
330 }
331 "true" => return Ok(Some((None, true))),
332 "false" => return Ok(Some((None, false))),
333 _ => (),
334 };
335
336 let new_mode = version_info.is_ge_version(4, 8, 10);
337 let (lit, value) = if new_mode {
338 let noneg = lit.strip_prefix('-');
339 (noneg.unwrap_or(lit), noneg.is_none())
340 } else {
341 let (lit, value) = if lit == "(not" {
342 let lit = l.next().ok_or(E::UnexpectedNewline)?;
343 let lit = lit.strip_suffix(')').ok_or(E::TupleMissingParens)?;
344 (lit, false)
345 } else {
346 (lit, true)
347 };
348 (lit.strip_prefix('p').ok_or(E::BoolLiteralNotP)?, value)
349 };
350 let bool_lit = lit.parse::<NonZeroU32>().map_err(E::InvalidBoolLiteral)?;
351 Ok(Some((Some(bool_lit), value)))
352 }
353}
354
355impl Z3LogParser for Z3Parser {
356 fn newline(&mut self) {
357 self.comm.newline();
358 }
359
360 fn version_info<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
361 let solver = l.next().ok_or(E::UnexpectedNewline)?.to_string();
362 let version = l.next().ok_or(E::UnexpectedNewline)?;
363 Self::expect_completed(l)?;
365 let version = semver::Version::parse(version)?;
366 eprintln!("{solver} {version}");
367 self.version_info = VersionInfo::Present { solver, version };
368 Ok(())
369 }
370
371 fn mk_quant<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
372 let full_id = self.parse_new_full_id(l.next())?;
373 let (quant_name, num_vars) = self.parse_qid(&mut l)?;
374 let quant_name = QuantKind::parse(&mut self.strings, &quant_name);
375 let child_ids = Self::map(l, |id| self.parse_existing_app(id))?;
376 debug_assert!(!child_ids.is_empty());
377 let child_id_names = || {
378 child_ids[..child_ids.len() - 1]
379 .iter()
380 .map(|&id| self[id].app_name().map(|name| &self[name]))
381 };
382 debug_assert!(
383 child_id_names().all(|name| name.is_some_and(|name| name == "pattern")),
384 "Expected all but last child to be \"pattern\" but found {:?}",
385 child_id_names().collect::<Vec<_>>()
386 );
387 self.quant_or_lamda(full_id, child_ids, num_vars, quant_name)
388 }
389
390 fn mk_lambda<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
391 let full_id = self.parse_new_full_id(l.next())?;
392 let lambda = l.next().ok_or(E::UnexpectedNewline)?;
393 self.check_lambda_name(lambda)?;
394 let num_vars = l.next().ok_or(E::UnexpectedNewline)?;
395 let num_vars = num_vars
396 .parse::<NonMaxU32>()
397 .map_err(E::InvalidQVarInteger)?;
398 let child_ids = Self::map(l, |id| self.parse_existing_proof(id))?;
399 let kind = QuantKind::Lambda(child_ids);
400 self.quant_or_lamda(full_id, Default::default(), num_vars, kind)
401 }
402
403 fn mk_var<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
404 let full_id = self.parse_new_full_id(l.next())?;
405 let kind = l.next().ok_or(E::UnexpectedNewline)?;
406 let kind = TermKind::parse_var(kind)?;
407 Self::expect_completed(l)?;
409 self.new_term(full_id, kind, Default::default())?;
410 Ok(())
411 }
412
413 fn mk_app<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
414 let id_str = l.next().ok_or(E::UnexpectedNewline)?;
415 let mut id = TermId::parse(&mut self.strings, id_str)?;
416 let (name, child) = self.parse_app_name(&mut l)?;
417 debug_assert!(id_str != "#1" || name == "true");
418 debug_assert!(id_str != "#2" || name == "false");
419 self.terms
420 .check_get_model(&mut id, &name, &mut self.strings);
421 let name = self.mk_string(&name)?;
422 let child = child.into_iter().map(Ok);
423 let child_ids = child.chain(l.map(|id| TermId::parse(&mut self.strings, id)));
424 let child_ids = Self::map(child_ids, |id| self.terms.parse_app_child_id(id?))?;
425 let tidx = self.new_term(id, TermKind::App(name), child_ids)?;
426 self.events
427 .new_term(tidx, &self.terms[tidx], &self.strings)?;
428 Ok(())
429 }
430
431 fn mk_proof<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
432 let full_id = self.parse_new_full_id(l.next())?;
433 let name = l.next().ok_or(E::UnexpectedNewline)?;
434 let kind = match name.parse() {
435 Ok(kind) => kind,
436 Err(_) => {
437 debug_assert!(false, "Unknown proof step kind {name:?}");
438 ProofStepKind::OTHER(self.mk_string(name)?)
439 }
440 };
441 let mut next = l.next().ok_or(E::UnexpectedNewline)?;
442 let mut prerequisites = Vec::new();
443 for n in l {
444 let curr = next;
445 next = n;
446
447 let prereq = self.parse_existing_proof(curr)?;
448 prerequisites.push(prereq);
449 }
450 let result = self.parse_existing_app(next)?;
451
452 let proof_step = ProofStep {
453 id: full_id,
454 kind,
455 result,
456 prerequisites: prerequisites.into(),
457 frame: self.stack.active_frame(),
458 };
459 let proof_idx = self.terms.proof_terms.new_term(proof_step)?;
460 self.egraph
461 .new_proof(result, proof_idx, &self.terms, &self.stack)?;
462 self.events.new_proof_step(
463 proof_idx,
464 &self.terms[proof_idx],
465 &self.terms,
466 &self.strings,
467 )
468 }
469
470 fn attach_meaning<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
471 let id = l.next().ok_or(E::UnexpectedNewline)?;
472 let theory = l.next().ok_or(E::UnexpectedNewline)?;
473 let value = l.collect::<Vec<_>>().join(" ");
474 let meaning = match theory {
475 "arith" => {
476 let num = Self::parse_arith(&value)?;
477 Meaning::Arith(Box::new(num))
478 }
479 "bv" => {
480 let (value, bits) = if let Some(data) = value.strip_prefix("#x") {
481 let value = num::BigUint::from_str_radix(data, 16);
482 (value, data.len() as u32 * 4)
483 } else if let Some(data) = value.strip_prefix("#b") {
484 let value = num::BigUint::from_str_radix(data, 2);
485 (value, data.len() as u32)
486 } else {
487 return Err(E::ParseError(value));
488 };
489 let value = BitVec {
490 value: value.map_err(E::ParseBigUintError)?.into(),
491 bits,
492 };
493 Meaning::BitVec(Box::new(value))
494 }
495 theory => {
496 let theory = self.mk_string(theory)?;
497 let value = self.mk_string(&value)?;
498 Meaning::Unknown { theory, value }
499 }
500 };
501 let idx = self.parse_existing_app(id)?;
502 let idx = self.terms.new_meaning(idx, meaning)?;
503 let meaning = self.terms.meaning(idx).unwrap();
504 self.events.new_meaning(idx, meaning, &self.strings)
505 }
506
507 fn attach_var_names<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
508 let id = l.next().ok_or(E::UnexpectedNewline)?;
509 let var_names = self.gobble_var_names_list(l)?;
510 let tidx = self.parse_existing_app(id)?;
511 let qidx = self.terms.quant(tidx)?;
512 let quant = &mut self.quantifiers[qidx];
513 debug_assert_eq!(quant.num_vars.get() as usize, var_names.len());
514 debug_assert!(quant.vars.is_none());
515 quant.vars = Some(var_names);
516 Ok(())
517 }
518
519 fn attach_enode<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
520 let id = l.next().ok_or(E::UnexpectedNewline)?;
521 let idx = self.parse_existing_app(id);
522 let Ok(idx) = idx else {
523 if self.version_info.is_version(4, 8, 7) {
524 return Ok(());
526 } else {
527 return idx.map(|_| ());
528 }
529 };
530 let z3_gen = Self::parse_z3_generation(&mut l)?.ok_or(E::UnexpectedNewline)?;
531 Self::expect_completed(l)?;
533
534 debug_assert!(self[idx].app_name().is_some());
535 let iidx = self.active_inst(idx)?;
536 let blame = self.egraph.get_blame(idx, iidx, &self.terms, &self.stack);
537 let enode = self.egraph.new_enode(blame, idx, z3_gen, &self.stack)?;
538 self.events.new_enode();
539 if let Some(a) = self.insts.active_inst() {
540 a.yields.try_reserve(1)?;
542 a.yields.push(enode);
543 let idx = a.idx;
544 debug_assert!(self.insts.insts[idx]
545 .kind
546 .z3_generation()
547 .is_none_or(|g| g == z3_gen));
548 }
549 Ok(())
550 }
551
552 fn eq_expl<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
553 let from = self.parse_existing_enode(l.next().ok_or(E::UnexpectedNewline)?)?;
554 let kind = l.next().ok_or(E::UnexpectedNewline)?;
555 let eq_expl = {
556 let mut kind_dependent_info = Self::iter_until_eq(l.by_ref(), ";");
557 match kind {
558 "root" => EqualityExpl::Root { id: from },
559 "lit" => {
560 let eq = kind_dependent_info.next().ok_or(E::UnexpectedEnd)?;
561 let eq = self.parse_existing_enode(eq)?;
562 Self::expect_completed(kind_dependent_info)?;
563 let to = self.parse_existing_enode(l.next().ok_or(E::UnexpectedNewline)?)?;
564
565 let eq = self.lits.get_assign(self[eq].owner, &self.stack);
566 let eq = eq.ok_or(E::UnknownEqLit)?;
567 EqualityExpl::Literal { from, eq, to }
571 }
572 "cg" => {
573 let mut arg_eqs = Vec::new();
574 for t in Self::gobble_tuples::<true>(kind_dependent_info) {
575 let (from, to) = t?;
576 let from = self.parse_existing_enode(from)?;
577 let to = self.parse_existing_enode(to)?;
578 arg_eqs.push((from, to));
579 }
580 let to = self.parse_existing_enode(l.next().ok_or(E::UnexpectedNewline)?)?;
581 EqualityExpl::Congruence {
582 from,
583 arg_eqs: arg_eqs.into_boxed_slice(),
584 to,
585 uses: Vec::new(),
586 }
587 }
588 "th" => {
589 let theory = kind_dependent_info.next().ok_or(E::UnexpectedEnd)?;
590 let theory = TheoryKind::from_name(theory, &mut self.strings);
591 Self::expect_completed(kind_dependent_info)?;
592 let to = self.parse_existing_enode(l.next().ok_or(E::UnexpectedNewline)?)?;
593 EqualityExpl::Theory { from, theory, to }
594 }
595 "ax" => {
596 Self::expect_completed(kind_dependent_info)?;
597 let to = self.parse_existing_enode(l.next().ok_or(E::UnexpectedNewline)?)?;
598 EqualityExpl::Axiom { from, to }
599 }
600 kind => {
601 let args = kind_dependent_info
602 .map(|s| self.mk_string(s))
603 .collect::<Result<_>>()?;
604 let to = self.parse_existing_enode(l.next().ok_or(E::UnexpectedNewline)?)?;
605 EqualityExpl::Unknown {
606 kind: self.mk_string(kind)?,
607 from,
608 args,
609 to,
610 }
611 }
612 }
613 };
614 Self::expect_completed(l)?;
616
617 self.egraph.new_given_equality(from, eq_expl, &self.stack)?;
618 Ok(())
619 }
620
621 fn new_match<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
622 let fingerprint = l.next().ok_or(E::UnexpectedNewline)?;
623 let fingerprint = Fingerprint::parse(fingerprint)?;
624 let idx = l.next().ok_or(E::UnexpectedNewline)?;
625 let idx = self.parse_existing_app(idx)?;
626 let quant = self.terms.quant(idx)?;
627 let pattern = l.next().ok_or(E::UnexpectedNewline)?;
628 let pattern = self.parse_existing_app(pattern)?;
629 let pattern = self
630 .patterns(quant)
631 .ok_or(E::NewMatchOnLambda(quant))?
632 .position(|p| *p == pattern)
633 .ok_or(E::UnknownPatternIdx(pattern))?;
634 let bound_terms = Self::iter_until_eq(&mut l, ";");
635 let is_axiom = fingerprint.is_zero();
636
637 let kind = if is_axiom {
638 let bound_terms = bound_terms
639 .map(|id| self.parse_existing_app(id))
640 .collect::<Result<BoxSlice<_>>>()?;
641 debug_assert!(bound_terms
642 .iter()
643 .all(|&b| !self[b].has_var().unwrap_or(true)));
644 MatchKind::Axiom {
645 axiom: quant,
646 pattern,
647 bound_terms,
648 }
649 } else {
650 let bound_terms = bound_terms
651 .map(|id| self.parse_existing_enode(id))
652 .collect::<Result<BoxSlice<_>>>()?;
653 debug_assert!(bound_terms
654 .iter()
655 .all(|&b| !self[self[b].owner].has_var().unwrap_or(true)));
656 MatchKind::Quantifier {
657 quant,
658 pattern,
659 bound_terms,
660 }
661 };
662 let mut blamed = Vec::new();
663 let mut next = l.next();
664 while let Some(word) = next.take() {
665 let enode = self.parse_existing_enode(word)?;
666 let l = l.by_ref().take_while(|s| {
668 let cond = s.as_bytes().first().is_some_and(|f| *f == b'(')
669 || s.as_bytes().last().is_some_and(|l| *l == b')');
670 if !cond {
671 next = Some(*s);
672 }
673 cond
674 });
675 let mut equalities = Vec::new();
676 self.append_trans_equality_tuples(l, |eq| {
677 equalities.try_reserve(1)?;
678 equalities.push(eq);
679 Ok(())
680 })?;
681
682 blamed.try_reserve(1)?;
683 blamed.push((blamed.len(), enode, equalities));
684 }
685
686 let pat = kind.quant_pat().unwrap();
687 let pat = self.get_pattern(pat).unwrap();
688 let (_correct_order, blamed) = self.make_blamed(&kind, blamed, pat)?;
689
690 let match_ = Match {
691 kind,
692 blamed,
693 frame: self.stack.active_frame(),
694 };
695 debug_assert_eq!(match_.pattern_matches().count(), self[pat].child_ids.len());
696 debug_assert!(match_
697 .pattern_matches()
698 .zip(self[pat].child_ids.iter())
699 .all(|(m, s)| self.check_match(&match_.kind, m, *s)));
700 self.insts.new_match(fingerprint, match_)?;
701 Ok(())
702 }
703
704 fn inst_discovered<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
705 let method = l.next().ok_or(E::UnexpectedNewline)?;
706 let fingerprint = Fingerprint::parse(l.next().ok_or(E::UnexpectedNewline)?)?;
707
708 let (kind, blamed) = match method {
709 "theory-solving" => {
710 debug_assert!(
711 fingerprint.is_zero(),
712 "Theory solving should have zero fingerprint"
713 );
714 let axiom_id = l.next().ok_or(E::UnexpectedNewline)?;
715 let axiom_id = TermId::parse(&mut self.strings, axiom_id)?;
716
717 let bound_terms = Self::iter_until_eq(&mut l, ";")
718 .map(|id| self.parse_existing_app(id))
719 .collect::<Result<_>>()?;
720
721 let mut blamed = Vec::new();
722 let mut rewrite_of = None;
723 for word in l.by_ref() {
724 let term = self.parse_existing_app(word)?;
725 if let Ok(enode) = self.get_existing_enode(term) {
726 if let Some(rewrite_of) = rewrite_of {
727 return Err(E::NonRewriteAxiomInvalidEnode(rewrite_of));
728 }
729 blamed.try_reserve(1)?;
730 blamed.push(Blame {
732 coupling: Coupling::Exact,
733 enode,
734 equalities: Default::default(),
735 });
736 } else {
737 if let Some(rewrite_of) = rewrite_of {
738 return Err(E::RewriteAxiomMultipleTerms1(rewrite_of));
739 }
740 if !blamed.is_empty() {
741 return Err(E::RewriteAxiomMultipleTerms2(blamed));
742 }
743 rewrite_of = Some(term);
744 }
745 }
746
747 let kind = MatchKind::TheorySolving {
748 axiom_id,
749 bound_terms,
750 rewrite_of,
751 };
752 (kind, blamed)
753 }
754 "MBQI" => {
755 let quant = self.parse_existing_app(l.next().ok_or(E::UnexpectedNewline)?)?;
756 let quant = self.terms.quant(quant)?;
757 let bound_terms = l
758 .map(|id| self.parse_existing_enode(id))
759 .collect::<Result<_>>()?;
760 let kind = MatchKind::MBQI { quant, bound_terms };
761 (kind, Vec::new())
762 }
763 _ => return Err(E::UnknownInstMethod(method.to_string())),
764 };
765 let match_ = Match {
766 kind,
767 blamed: blamed.into(),
768 frame: self.stack.active_frame(),
769 };
770 self.insts.new_match(fingerprint, match_)?;
771 Ok(())
772 }
773
774 fn instance<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
775 let fingerprint = l.next().ok_or(E::UnexpectedNewline)?;
776 let fingerprint = Fingerprint::parse(fingerprint)?;
777 let mut proof = Self::iter_until_eq(&mut l, ";");
778 let proof_str = proof.next();
779 Self::expect_completed(proof)?;
780 let z3_generation = Self::parse_z3_generation(&mut l)?;
781 let kind = if let Some(z3_generation) = z3_generation {
782 debug_assert!(!fingerprint.is_zero());
783 let proof = if let Some(proof) = proof_str {
784 let proof = self.parse_existing_proof(proof)?;
785 InstProofLink::HasProof(proof)
786 } else {
787 let last_term = self.terms.last_term_from_instance(&self.strings);
788 InstProofLink::ProofsDisabled(last_term)
789 };
790 InstantiationKind::NonAxiom {
791 fingerprint,
792 z3_generation,
793 proof,
794 }
795 } else {
796 debug_assert!(fingerprint.is_zero());
797 let proof = proof_str.expect("Axiom instantiations should have an associated term");
801 let body = self.parse_existing_app(proof)?;
802 InstantiationKind::Axiom { body }
803 };
804 let match_ = self
805 .insts
806 .get_match(fingerprint)
807 .ok_or(E::UnknownFingerprint(fingerprint))?;
808 let inst = Instantiation {
809 match_,
810 kind,
811 yields_terms: Default::default(),
812 frame: self.stack.active_frame(),
813 };
814 let body = self.instance_body(kind.proof(), match_);
815 let can_duplicate = self.version_info.is_ge_version(4, 12, 0);
818 self.insts
819 .new_inst(fingerprint, inst, body, &self.stack, can_duplicate)?;
820 self.events.new_inst();
821 Ok(())
822 }
823
824 fn end_of_instance<'a>(&mut self, l: impl Iterator<Item = &'a str>) -> Result<()> {
825 self.insts.end_inst()?;
826 Self::expect_completed(l)
827 }
828
829 fn eof(&mut self) {
830 self.synth_terms.eof(self.terms().next_key());
831 self.events.new_eof();
832 }
833
834 fn assign<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
835 let created_by = self.insts.active_inst();
836 let iidx = created_by.as_ref().map(|a| a.idx);
837
838 let (assign, enode) = self.parse_literal(&mut l)?.ok_or(E::UnexpectedNewline)?;
839 let lit = self.lits.new_literal(assign, iidx, enode, &self.stack)?;
840 let mut justification = l.next().ok_or(E::UnexpectedNewline)?;
841 let decision = justification == "decision";
842 if decision {
843 let llk = self.comm.prev().last_line_kind;
844 if matches!(llk, LineKind::Push) && self.stack.new_decision() {
847 self.push_count -= 1;
848 self.events.undo_push();
849 }
850 self.lits.cdcl.new_decision(lit, &self.stack)?;
851 justification = l.next().ok_or(E::UnexpectedNewline)?;
852 debug_assert_eq!(justification, "axiom");
853 }
854 match justification {
856 "axiom" => {
859 Self::expect_completed(l)?;
860 let kind = if decision {
861 JustificationKind::Decision
862 } else {
863 JustificationKind::Axiom
864 };
865 self.lits.justification(lit, kind, core::iter::empty())?;
866 Ok(())
867 }
868 "bin" => {
870 let other = Self::parse_bool_literal(&self.version_info, &mut l)?
871 .ok_or(E::UnexpectedNewline)?;
872 Self::expect_completed(l)?;
873
874 let _j = self.lits.justification(
875 lit,
876 JustificationKind::Propagate,
877 [Ok(other)].into_iter(),
878 )?;
879 #[cfg(any())]
881 debug_assert_ne!(lit, j.blamed[0]);
882 self.lits.cdcl.new_propagate(lit, &self.stack)?;
883 Ok(())
884 }
885 "clause" => {
891 let _first = Self::parse_bool_literal(&self.version_info, &mut l)?
892 .ok_or(E::UnexpectedNewline)?;
893 let lits = core::iter::from_fn(|| {
895 Self::parse_bool_literal(&self.version_info, &mut l).transpose()
896 });
897 self.lits
898 .justification(lit, JustificationKind::Propagate, lits)?;
899
900 #[cfg(any())]
902 let c0 = self.lits.literal_to_term(first, false)?;
903 #[cfg(any())]
904 if lit != c0 {
905 eprintln!(
906 "Unexpected clause literal: {lit} != {c0} ({first:?}) / {:?}",
907 self.lits.lit_stack
908 );
909 return Err(E::UnexpectedEnd);
910 }
911 #[cfg(any())]
912 debug_assert_eq!(lit, c0, "{first:?}");
913 self.lits.cdcl.new_propagate(lit, &self.stack)?;
914 Ok(())
915 }
916 "justification" => {
917 let theory_id = l.next().ok_or(E::UnexpectedNewline)?;
918 let theory_id = theory_id
919 .strip_suffix(':')
920 .ok_or(E::MissingColonJustification)?;
921 let theory_id = theory_id.parse::<i32>().map_err(E::InvalidTheoryId)?;
922 let theory = TheoryKind::from_id(theory_id);
923
924 let lits = core::iter::from_fn(|| {
925 Self::parse_bool_literal(&self.version_info, &mut l).transpose()
926 });
927 self.lits
928 .justification(lit, JustificationKind::Theory(theory), lits)?;
929 Ok(())
930 }
931 _ => Err(E::UnknownJustification(justification.to_string())),
932 }
933 }
934
935 fn decide_and_or<'a>(&mut self, _l: impl Iterator<Item = &'a str>) -> Result<()> {
936 self.comm.curr().last_line_kind = LineKind::DecideAndOr;
937 Ok(())
938 }
939
940 fn conflict<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
941 self.comm.curr().last_line_kind = LineKind::Conflict;
942
943 let mut cut = Vec::new();
944 while let Some((assignment, _)) = self.parse_literal(&mut l)? {
945 cut.try_reserve(1)?;
946 cut.push(assignment);
947 }
948 let frame = self.stack.active_frame();
949 debug_assert!(self.lits.curr_to_root_unique());
950 self.lits.cdcl.new_conflict(cut.into_boxed_slice(), frame);
951 Ok(())
954 }
955
956 fn push<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
957 self.comm.curr().last_line_kind = LineKind::Push;
958
959 let scope = l.next().ok_or(E::UnexpectedNewline)?;
960 let scope = scope.parse::<usize>().map_err(E::InvalidFrameInteger)?;
961 Self::expect_completed(l)?;
963
964 let from_cdcl = matches!(self.comm.prev().last_line_kind, LineKind::DecideAndOr);
965 let from_cdcl = from_cdcl || self.stack.is_speculative();
966 self.stack.new_frame(scope, from_cdcl)?;
967 if !from_cdcl {
968 self.push_count += 1;
969 }
970 self.events.new_push(from_cdcl)?;
971 Ok(())
972 }
973
974 fn pop<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
975 let num = l.next().ok_or(E::UnexpectedNewline)?;
976 let num = num
977 .parse::<NonZeroUsize>()
978 .map_err(E::InvalidFrameInteger)?;
979 let scope = l.next().ok_or(E::UnexpectedNewline)?;
980 let scope = scope.parse::<usize>().map_err(E::InvalidFrameInteger)?;
981 Self::expect_completed(l)?;
983
984 let conflict = matches!(self.comm.prev().last_line_kind, LineKind::Conflict);
985 debug_assert_eq!(conflict, self.lits.cdcl.has_conflict());
986 let from_cdcl = self.stack.pop_frames(num, scope, conflict)?;
987 if conflict {
989 self.lits.cdcl.backtrack(&self.stack)?;
990 }
991 self.events.new_pop(num, from_cdcl)
992 }
993
994 fn begin_check<'a>(&mut self, mut l: impl Iterator<Item = &'a str>) -> Result<()> {
995 let scope = l.next().ok_or(E::UnexpectedNewline)?;
996 let scope = scope.parse::<usize>().map_err(E::InvalidFrameInteger)?;
997 self.stack.ensure_height(scope)?;
998 self.lits
999 .cdcl
1000 .begin_check(self.incremental_mode(), &self.stack)?;
1001 self.events.new_begin_check()
1002 }
1003}