1use super::repr::{
2 ApplyResult, ClauseId, ExprId, ExprKind, ExprView, TermDeepView, TermElem, TermId, TermStorage,
3 TermStorageLen, TermView, TermViewMut, UniqueTermArray,
4};
5use crate::{
6 Map,
7 parse::{
8 GlobalCx, VAR_PREFIX,
9 repr::{Expr, Predicate, Term},
10 text::Name,
11 },
12};
13use indexmap::IndexMap;
14use std::{
15 borrow::Borrow,
16 collections::VecDeque,
17 fmt::{self, Write},
18 hash::Hash,
19 iter,
20 ops::{self, Range},
21};
22
23pub(crate) type ClauseMap = IndexMap<Predicate<Int>, Vec<ClauseId>>;
24
25#[derive(Debug)]
26pub(crate) struct Prover {
27 uni_op: UnificationOperator,
28
29 nodes: Vec<Node>,
31
32 assignments: Vec<usize>,
38
39 query: ExprId,
41
42 query_vars: Vec<TermId>,
46
47 queue: VecDeque<usize>,
49
50 temp_var_buf: Map<TermId, TermId>,
55
56 temp_var_int: u32,
59}
60
61impl Prover {
62 pub(crate) fn new() -> Self {
63 Self {
64 uni_op: UnificationOperator::new(),
65 nodes: Vec::new(),
66 assignments: Vec::new(),
67 query: ExprId(0),
68 query_vars: Vec::new(),
69 queue: VecDeque::new(),
70 temp_var_buf: Map::default(),
71 temp_var_int: 0,
72 }
73 }
74
75 fn clear(&mut self) {
76 self.uni_op.clear();
77 self.nodes.clear();
78 self.assignments.clear();
79 self.query_vars.clear();
80 self.queue.clear();
81 }
82
83 pub(crate) fn prove<'a, 'cx>(
84 &'a mut self,
85 query: Expr<Name<'cx>>,
86 clause_map: &'a ClauseMap,
87 stor: &'a mut TermStorage<Int>,
88 nimap: &'a mut NameIntMap<'cx>,
89 ) -> ProveCx<'a, 'cx> {
90 self.clear();
91
92 let old_nimap_state = nimap.state();
93 let query = query.map(&mut |name| nimap.name_to_int(name));
94
95 let old_stor_len = stor.len();
96 self.query = stor.insert_expr(query);
97
98 stor.get_expr(self.query)
99 .with_term(&mut |term: TermView<'_, Int>| {
100 term.with_variable(&mut |term| self.query_vars.push(term.id));
101 });
102
103 self.nodes.push(Node {
104 kind: NodeKind::Expr(self.query),
105 uni_delta: 0..0,
106 parent: self.nodes.len(),
107 });
108 self.queue.push_back(0);
109
110 ProveCx::new(self, clause_map, stor, nimap, old_stor_len, old_nimap_state)
111 }
112
113 fn evaluate_node(
120 &mut self,
121 node_index: usize,
122 clause_map: &ClauseMap,
123 stor: &mut TermStorage<Int>,
124 ) -> Option<bool> {
125 let node = self.nodes[node_index].clone();
126 let node_expr = match node.kind {
127 NodeKind::Expr(expr_id) => expr_id,
128 NodeKind::Leaf(eval) => {
129 self.find_assignment(node_index);
130 return Some(eval);
131 }
132 };
133
134 let predicate = stor.get_expr(node_expr).leftmost_term().predicate();
135 let similar_clauses = if let Some(v) = clause_map.get(&predicate) {
136 v.as_slice()
137 } else {
138 &[]
139 };
140
141 let old_len = self.nodes.len();
142 for clause in similar_clauses {
143 let head = stor.get_term(clause.head);
144
145 if !stor.get_expr(node_expr).is_unifiable(head) {
146 continue;
147 }
148
149 let clause = Self::convert_var_into_temp(
150 *clause,
151 stor,
152 &mut self.temp_var_buf,
153 &mut self.temp_var_int,
154 );
155 if let Some(new_node) = self.unify_node_with_clause(node_index, clause, stor) {
156 self.nodes.push(new_node);
157 self.queue.push_back(self.nodes.len() - 1);
158 }
159 }
160
161 let expr = stor.get_expr(node_expr);
168 let eval = self.nodes.len() > old_len;
169 let mut need_apply = None;
170
171 let lost_possibility = match assume_leftmost_term(expr, eval) {
172 AssumeResult::Incomplete { lost } => lost,
173 AssumeResult::Complete { lost, .. } => lost,
174 };
175 if lost_possibility {
176 need_apply = Some(!eval);
177 } else if !eval {
178 need_apply = Some(false);
179 }
180
181 if let Some(to) = need_apply {
182 let mut expr = stor.get_expr_mut(node_expr);
183 let kind = match expr.apply_to_leftmost_term(to) {
184 ApplyResult::Expr => NodeKind::Expr(expr.id()),
185 ApplyResult::Complete(eval) => NodeKind::Leaf(eval),
186 };
187 self.nodes.push(Node {
188 kind,
189 uni_delta: 0..0,
190 parent: node_index,
191 });
192 self.queue.push_back(self.nodes.len() - 1);
193 }
194
195 return None;
196
197 enum AssumeResult {
200 Incomplete {
203 lost: bool,
206 },
207
208 Complete {
211 eval: bool,
213 lost: bool,
214 },
215 }
216
217 fn assume_leftmost_term(expr: ExprView<'_, Int>, to: bool) -> AssumeResult {
218 match expr.as_kind() {
219 ExprKind::Term(_) => AssumeResult::Complete {
220 eval: to,
221 lost: false,
222 },
223 ExprKind::Not(inner) => match assume_leftmost_term(inner, to) {
224 res @ AssumeResult::Incomplete { .. } => res,
225 AssumeResult::Complete { eval, lost } => {
226 AssumeResult::Complete { eval: !eval, lost }
227 }
228 },
229 ExprKind::And(mut args) => {
230 match assume_leftmost_term(args.next().unwrap(), to) {
234 res @ AssumeResult::Incomplete { .. } => res,
235 AssumeResult::Complete { eval, lost } => {
236 if !eval {
237 AssumeResult::Complete { eval: false, lost }
238 } else {
239 AssumeResult::Incomplete { lost }
240 }
241 }
242 }
243 }
244 ExprKind::Or(mut args) => {
245 match assume_leftmost_term(args.next().unwrap(), to) {
249 res @ AssumeResult::Incomplete { .. } => res,
250 AssumeResult::Complete { eval, lost } => {
251 if eval {
252 let right_var = args.any(|arg| arg.contains_variable());
253 AssumeResult::Complete {
254 eval: true,
255 lost: lost | right_var,
256 }
257 } else {
258 AssumeResult::Incomplete { lost }
259 }
260 }
261 }
262 }
263 }
264 }
265 }
266
267 fn convert_var_into_temp(
278 mut clause_id: ClauseId,
279 stor: &mut TermStorage<Int>,
280 temp_var_buf: &mut Map<TermId, TermId>,
281 temp_var_int: &mut u32,
282 ) -> ClauseId {
283 debug_assert!(temp_var_buf.is_empty());
284
285 let mut f = |terms: &mut UniqueTermArray<Int>, term_id: TermId| {
286 let term = terms.get_mut(term_id);
287 if term.is_variable() {
288 let src = term.id();
289
290 temp_var_buf.entry(src).or_insert_with(|| {
291 let temp_term = Term {
292 functor: Int::temporary(*temp_var_int),
293 args: [].into(),
294 };
295 *temp_var_int += 1;
296 terms.insert(temp_term)
297 });
298 }
299 };
300
301 stor.get_term_mut(clause_id.head).with_terminal(&mut f);
302
303 if let Some(body) = clause_id.body {
304 stor.get_expr_mut(body).with_terminal(&mut f);
305 }
306
307 for (src, dst) in temp_var_buf.drain() {
308 let mut head = stor.get_term_mut(clause_id.head);
309 head.replace(src, dst);
310 clause_id.head = head.id();
311
312 if let Some(body) = clause_id.body {
313 let mut body = stor.get_expr_mut(body);
314 body.replace_term(src, dst);
315 clause_id.body = Some(body.id());
316 }
317 }
318
319 clause_id
320 }
321
322 fn unify_node_with_clause(
323 &mut self,
324 node_index: usize,
325 clause: ClauseId,
326 stor: &mut TermStorage<Int>,
327 ) -> Option<Node> {
328 debug_assert!(self.uni_op.ops.is_empty());
329
330 let NodeKind::Expr(node_expr) = self.nodes[node_index].kind else {
331 unreachable!()
332 };
333
334 if !stor
335 .get_expr(node_expr)
336 .leftmost_term()
337 .unify(stor.get_term(clause.head), &mut |op| {
338 self.uni_op.push_op(op)
339 })
340 {
341 return None;
342 }
343 let (node_expr, clause, uni_delta) = self.uni_op.consume_ops(stor, node_expr, clause);
344
345 if let Some(body) = clause.body {
346 let mut lhs = stor.get_expr_mut(node_expr);
347 lhs.replace_leftmost_term(body);
348 return Some(Node {
349 kind: NodeKind::Expr(lhs.id()),
350 uni_delta,
351 parent: node_index,
352 });
353 }
354
355 let mut lhs = stor.get_expr_mut(node_expr);
356 let kind = match lhs.apply_to_leftmost_term(true) {
357 ApplyResult::Expr => NodeKind::Expr(lhs.id()),
358 ApplyResult::Complete(eval) => NodeKind::Leaf(eval),
359 };
360 Some(Node {
361 kind,
362 uni_delta,
363 parent: node_index,
364 })
365 }
366
367 fn find_assignment(&mut self, node_index: usize) {
371 self.assignments.clear();
373
374 let mut cur_index = node_index;
375 loop {
376 let node = &self.nodes[cur_index];
377 let range = node.uni_delta.clone();
378
379 for (from, to) in self.uni_op.get_record(range).iter().cloned() {
380 let (from, to) = (from.0, to.0);
381
382 for i in self.assignments.len()..=from.max(to) {
383 self.assignments.push(i);
384 }
385
386 let root_from = find(&mut self.assignments, from);
387 let root_to = find(&mut self.assignments, to);
388 self.assignments[root_from] = root_to;
389 }
390
391 if node.parent == cur_index {
392 break;
393 }
394 cur_index = node.parent;
395 }
396
397 return;
398
399 fn find(buf: &mut [usize], i: usize) -> usize {
402 if buf[i] == i {
403 i
404 } else {
405 let root = find(buf, buf[i]);
406 buf[i] = root;
407 root
408 }
409 }
410 }
411}
412
413#[derive(Debug)]
414struct UnificationOperator {
415 ops: Vec<UnifyOp>,
416
417 record: Vec<(TermId, TermId)>,
422}
423
424impl UnificationOperator {
425 const fn new() -> Self {
426 Self {
427 ops: Vec::new(),
428 record: Vec::new(),
429 }
430 }
431
432 fn clear(&mut self) {
433 self.ops.clear();
434 self.record.clear();
435 }
436
437 fn push_op(&mut self, op: UnifyOp) {
438 self.ops.push(op);
439 }
440
441 #[must_use]
442 fn consume_ops(
443 &mut self,
444 stor: &mut TermStorage<Int>,
445 mut left: ExprId,
446 mut right: ClauseId,
447 ) -> (ExprId, ClauseId, Range<usize>) {
448 let record_start = self.record.len();
449
450 for op in self.ops.drain(..) {
451 match op {
452 UnifyOp::Left { from, to } => {
453 let mut expr = stor.get_expr_mut(left);
454 expr.replace_term(from, to);
455 left = expr.id();
456
457 self.record.push((from, to));
458 }
459 UnifyOp::Right { from, to } => {
460 if let Some(right_body) = right.body {
461 let mut expr = stor.get_expr_mut(right_body);
462 expr.replace_term(from, to);
463 right.body = Some(expr.id());
464
465 self.record.push((from, to));
466 }
467 }
468 }
469 }
470
471 (left, right, record_start..self.record.len())
472 }
473
474 fn get_record(&self, range: Range<usize>) -> &[(TermId, TermId)] {
475 &self.record[range]
476 }
477}
478
479#[derive(Debug, Clone)]
480struct Node {
481 kind: NodeKind,
482 uni_delta: Range<usize>,
483 parent: usize,
484}
485
486#[derive(Debug, Clone, Copy)]
487enum NodeKind {
488 Expr(ExprId),
491
492 Leaf(bool),
494}
495
496#[derive(Debug)]
497enum UnifyOp {
498 Left { from: TermId, to: TermId },
499 Right { from: TermId, to: TermId },
500}
501
502pub struct ProveCx<'a, 'cx> {
503 prover: &'a mut Prover,
504 clause_map: &'a ClauseMap,
505 stor: &'a mut TermStorage<Int>,
506 nimap: &'a mut NameIntMap<'cx>,
507 old_stor_len: TermStorageLen,
508 old_nimap_state: NameIntMapState,
509}
510
511impl<'a, 'cx> ProveCx<'a, 'cx> {
512 fn new(
513 prover: &'a mut Prover,
514 clause_map: &'a ClauseMap,
515 stor: &'a mut TermStorage<Int>,
516 nimap: &'a mut NameIntMap<'cx>,
517 old_stor_len: TermStorageLen,
518 old_nimap_state: NameIntMapState,
519 ) -> Self {
520 Self {
521 prover,
522 clause_map,
523 stor,
524 nimap,
525 old_stor_len,
526 old_nimap_state,
527 }
528 }
529
530 pub fn prove_next(&mut self) -> Option<EvalView<'_, 'cx>> {
531 while let Some(node_index) = self.prover.queue.pop_front() {
532 if let Some(proof_result) =
533 self.prover
534 .evaluate_node(node_index, self.clause_map, self.stor)
535 {
536 if proof_result {
538 return Some(EvalView {
539 query_vars: &self.prover.query_vars,
540 terms: &self.stor.terms.buf,
541 assignments: &self.prover.assignments,
542 int2name: &self.nimap.int2name,
543 start: 0,
544 end: self.prover.query_vars.len(),
545 });
546 }
547 }
548 }
549 None
550 }
551
552 pub fn is_true(mut self) -> bool {
553 self.prove_next().is_some()
554 }
555}
556
557impl Drop for ProveCx<'_, '_> {
558 fn drop(&mut self) {
559 self.stor.truncate(self.old_stor_len.clone());
560 self.nimap.revert(self.old_nimap_state.clone());
561 }
562}
563
564pub struct EvalView<'a, 'cx> {
565 query_vars: &'a [TermId],
566 terms: &'a [TermElem<Int>],
567 assignments: &'a [usize],
568 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
569 start: usize,
571 end: usize,
573}
574
575impl EvalView<'_, '_> {
576 const fn len(&self) -> usize {
577 self.end - self.start
578 }
579}
580
581impl<'a, 'cx> Iterator for EvalView<'a, 'cx> {
582 type Item = Assignment<'a, 'cx>;
583
584 fn next(&mut self) -> Option<Self::Item> {
585 if self.start < self.end {
586 let from = self.query_vars[self.start];
587 self.start += 1;
588
589 Some(Assignment {
590 buf: self.terms,
591 from,
592 assignments: self.assignments,
593 int2name: self.int2name,
594 })
595 } else {
596 None
597 }
598 }
599
600 fn size_hint(&self) -> (usize, Option<usize>) {
601 let len = <Self>::len(self);
602 (len, Some(len))
603 }
604}
605
606impl ExactSizeIterator for EvalView<'_, '_> {
607 fn len(&self) -> usize {
608 <Self>::len(self)
609 }
610}
611
612impl iter::FusedIterator for EvalView<'_, '_> {}
613
614pub struct Assignment<'a, 'cx> {
615 buf: &'a [TermElem<Int>],
616 from: TermId,
617 assignments: &'a [usize],
618 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
619}
620
621impl<'a, 'cx> Assignment<'a, 'cx> {
622 pub fn lhs(&self) -> Term<Name<'cx>> {
626 Self::term_view_to_term(self.lhs_view(), self.int2name)
627 }
628
629 pub fn rhs(&self) -> Term<Name<'cx>> {
633 Self::term_deep_view_to_term(self.rhs_view(), self.int2name)
634 }
635
636 pub fn get_lhs_variable(&self) -> &Name<'cx> {
640 let int = self.lhs_view().get_contained_variable().unwrap();
641 self.int2name.get(&int).unwrap()
642 }
643
644 fn term_view_to_term(
645 view: TermView<'_, Int>,
646 int2name: &IdxMap<'cx, Int, Name<'cx>>,
647 ) -> Term<Name<'cx>> {
648 let functor = view.functor();
649 let args = view.args();
650
651 let functor = if let Some(name) = int2name.get(functor) {
652 name.clone()
653 } else {
654 let mut debug_string = String::new();
655 write!(&mut debug_string, "{:?}", functor).unwrap();
656 Name::create(int2name.gcx(), &debug_string)
657 };
658
659 let args = args
660 .into_iter()
661 .map(|arg| Self::term_view_to_term(arg, int2name))
662 .collect();
663
664 Term { functor, args }
665 }
666
667 fn term_deep_view_to_term(
668 view: TermDeepView<'_, Int>,
669 int2name: &IdxMap<'cx, Int, Name<'cx>>,
670 ) -> Term<Name<'cx>> {
671 let functor = view.functor();
672 let args = view.args();
673
674 let functor = if let Some(name) = int2name.get(functor) {
675 name.clone()
676 } else {
677 let mut debug_string = String::new();
678 write!(&mut debug_string, "{:?}", functor).unwrap();
679 Name::create(int2name.gcx(), &debug_string)
680 };
681
682 let args = args
683 .into_iter()
684 .map(|arg| Self::term_deep_view_to_term(arg, int2name))
685 .collect();
686
687 Term { functor, args }
688 }
689
690 const fn lhs_view(&self) -> TermView<'_, Int> {
691 TermView {
692 buf: self.buf,
693 id: self.from,
694 }
695 }
696
697 const fn rhs_view(&self) -> TermDeepView<'_, Int> {
698 TermDeepView {
699 buf: self.buf,
700 links: self.assignments,
701 id: self.from,
702 }
703 }
704}
705
706impl fmt::Display for Assignment<'_, '_> {
707 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
708 let view = format::NamedTermView::new(self.lhs_view(), self.int2name);
709 fmt::Display::fmt(&view, f)?;
710
711 f.write_str(" = ")?;
712
713 let view = format::NamedTermDeepView::new(self.rhs_view(), self.int2name);
714 fmt::Display::fmt(&view, f)
715 }
716}
717
718impl fmt::Debug for Assignment<'_, '_> {
719 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
720 let lhs = format::NamedTermView::new(self.lhs_view(), self.int2name);
721 let rhs = format::NamedTermDeepView::new(self.rhs_view(), self.int2name);
722
723 f.debug_struct("Assignment")
724 .field("lhs", &lhs)
725 .field("rhs", &rhs)
726 .finish()
727 }
728}
729
730impl ExprView<'_, Int> {
731 fn is_unifiable(&self, other: TermView<'_, Int>) -> bool {
732 match self.as_kind() {
733 ExprKind::Term(term) => term.is_unifiable(other),
734 ExprKind::Not(inner) => inner.is_unifiable(other),
735 ExprKind::And(mut args) | ExprKind::Or(mut args) => {
736 args.next().unwrap().is_unifiable(other)
737 }
738 }
739 }
740
741 fn contains_variable(&self) -> bool {
742 match self.as_kind() {
743 ExprKind::Term(term) => term.contains_variable(),
744 ExprKind::Not(inner) => inner.contains_variable(),
745 ExprKind::And(mut args) | ExprKind::Or(mut args) => {
746 args.any(|arg| arg.contains_variable())
747 }
748 }
749 }
750}
751
752impl TermView<'_, Int> {
753 fn unify<F: FnMut(UnifyOp)>(self, other: Self, f: &mut F) -> bool {
754 if self.is_variable() {
755 f(UnifyOp::Left {
756 from: self.id,
757 to: other.id,
758 });
759 true
760 } else if other.is_variable() {
761 f(UnifyOp::Right {
762 from: other.id,
763 to: self.id,
764 });
765 true
766 } else if self.functor() == other.functor() {
767 let zip = self.args().zip(other.args());
768 if self.arity() == other.arity() && zip.clone().all(|(l, r)| l.is_unifiable(r)) {
770 for (l, r) in zip {
771 l.unify(r, f);
772 }
773 true
774 } else {
775 false
776 }
777 } else {
778 false
779 }
780 }
781
782 fn is_unifiable(&self, other: Self) -> bool {
783 if self.is_variable() || other.is_variable() {
784 true
785 } else if self.functor() == other.functor() {
786 if self.arity() == other.arity() {
787 self.args()
788 .zip(other.args())
789 .all(|(l, r)| l.is_unifiable(r))
790 } else {
791 false
792 }
793 } else {
794 false
795 }
796 }
797
798 fn is_variable(&self) -> bool {
802 self.arity() == 0 && self.functor().is_variable()
803 }
804
805 fn contains_variable(&self) -> bool {
809 self.is_variable() || self.args().any(|arg| arg.contains_variable())
810 }
811
812 fn get_contained_variable(&self) -> Option<Int> {
813 if self.is_variable() {
814 Some(*self.functor())
815 } else {
816 self.args().find_map(|arg| arg.get_contained_variable())
817 }
818 }
819
820 fn with_variable<F: FnMut(&Self)>(&self, f: &mut F) {
821 if self.is_variable() {
822 f(self);
823 } else {
824 for arg in self.args() {
825 arg.with_variable(f);
826 }
827 }
828 }
829}
830
831impl TermViewMut<'_, Int> {
832 fn is_variable(&self) -> bool {
833 self.arity() == 0 && self.functor().is_variable()
834 }
835}
836
837#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
838pub struct Int(u32);
839
840impl Int {
841 const VAR_FLAG: u32 = 0x1 << 31;
842 const TEMPORARY_FLAG: u32 = 0x1 << 30;
843
844 pub(crate) fn from_text(s: &Name, mut index: u32) -> Self {
845 if s.is_variable() {
846 index |= Self::VAR_FLAG;
847 }
848 Self(index)
849 }
850
851 pub(crate) const fn temporary(int: u32) -> Self {
852 Self(int | Self::VAR_FLAG | Self::TEMPORARY_FLAG)
853 }
854
855 pub(crate) const fn is_variable(self) -> bool {
856 (Self::VAR_FLAG & self.0) == Self::VAR_FLAG
857 }
858
859 pub(crate) const fn is_temporary_variable(self) -> bool {
860 let mask: u32 = Self::VAR_FLAG | Self::TEMPORARY_FLAG;
861 (mask & self.0) == mask
862 }
863}
864
865impl fmt::Debug for Int {
866 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
867 let mask: u32 = Self::VAR_FLAG | Self::TEMPORARY_FLAG;
868 let index = !mask & self.0;
869
870 if self.is_variable() {
871 f.write_char(VAR_PREFIX)?;
872 }
873 if self.is_temporary_variable() {
874 f.write_char('#')?;
875 }
876 index.fmt(f)
877 }
878}
879
880impl ops::AddAssign<u32> for Int {
881 fn add_assign(&mut self, rhs: u32) {
882 self.0 += rhs;
883 }
884}
885
886#[derive(Debug)]
889pub(crate) struct NameIntMap<'cx> {
890 pub(crate) name2int: IdxMap<'cx, Name<'cx>, Int>,
891 pub(crate) int2name: IdxMap<'cx, Int, Name<'cx>>,
892 next_int: u32,
893}
894
895impl<'cx> NameIntMap<'cx> {
896 pub(crate) fn new(gcx: GlobalCx<'cx>) -> Self {
897 Self {
898 name2int: IdxMap::new(gcx),
899 int2name: IdxMap::new(gcx),
900 next_int: 0,
901 }
902 }
903
904 pub(crate) fn name_to_int(&mut self, name: Name<'cx>) -> Int {
905 if let Some(int) = self.name2int.get(&name) {
906 *int
907 } else {
908 let int = Int::from_text(&name, self.next_int);
909
910 self.name2int.insert(name.clone(), int);
911 self.int2name.insert(int, name);
912
913 self.next_int += 1;
914 int
915 }
916 }
917
918 pub(crate) fn state(&self) -> NameIntMapState {
919 NameIntMapState {
920 name2int_len: self.name2int.len(),
921 int2name_len: self.int2name.len(),
922 next_int: self.next_int,
923 }
924 }
925
926 pub(crate) fn revert(
927 &mut self,
928 NameIntMapState {
929 name2int_len,
930 int2name_len,
931 next_int,
932 }: NameIntMapState,
933 ) {
934 self.name2int.truncate(name2int_len);
935 self.int2name.truncate(int2name_len);
936 self.next_int = next_int;
937 }
938}
939
940#[derive(Debug)]
941pub(crate) struct IdxMap<'cx, K, V> {
942 map: IndexMap<K, V>,
943 pub(crate) gcx: GlobalCx<'cx>,
944}
945
946impl<'cx, K, V> IdxMap<'cx, K, V> {
947 pub(crate) fn new(gcx: GlobalCx<'cx>) -> Self {
948 Self {
949 map: IndexMap::default(),
950 gcx,
951 }
952 }
953
954 pub(crate) fn gcx(&self) -> &GlobalCx<'cx> {
955 &self.gcx
956 }
957
958 pub(crate) fn len(&self) -> usize {
959 self.map.len()
960 }
961
962 pub(crate) fn truncate(&mut self, len: usize) {
963 self.map.truncate(len);
964 }
965
966 pub(crate) fn get<Q>(&self, key: &Q) -> Option<&V>
967 where
968 K: Borrow<Q>,
969 Q: Hash + Eq + ?Sized,
970 {
971 self.map.get(key)
972 }
973
974 pub(crate) fn insert(&mut self, key: K, value: V) -> Option<V>
975 where
976 K: Hash + Eq,
977 {
978 self.map.insert(key, value)
979 }
980}
981
982#[derive(Debug, Clone, PartialEq, Eq)]
983pub(crate) struct NameIntMapState {
984 name2int_len: usize,
985 int2name_len: usize,
986 next_int: u32,
987}
988
989pub(crate) mod format {
990 use super::*;
991
992 pub struct NamedTermView<'a, 'cx> {
993 view: TermView<'a, Int>,
994 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
995 }
996
997 impl<'a, 'cx> NamedTermView<'a, 'cx> {
998 pub(crate) const fn new(
999 view: TermView<'a, Int>,
1000 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
1001 ) -> Self {
1002 Self { view, int2name }
1003 }
1004
1005 pub fn is(&self, term: &Term<Name<'cx>>) -> bool {
1006 let functor = self.view.functor();
1007 let Some(functor) = self.int2name.get(functor) else {
1008 return false;
1009 };
1010
1011 if functor != &term.functor {
1012 return false;
1013 }
1014
1015 self.args().zip(&term.args).all(|(l, r)| l.is(r))
1016 }
1017
1018 pub fn contains(&self, term: &Term<Name<'cx>>) -> bool {
1019 if self.is(term) {
1020 return true;
1021 }
1022
1023 self.args().any(|arg| arg.contains(term))
1024 }
1025
1026 fn args(&self) -> impl Iterator<Item = Self> {
1027 self.view.args().map(|arg| Self {
1028 view: arg,
1029 int2name: self.int2name,
1030 })
1031 }
1032 }
1033
1034 impl fmt::Display for NamedTermView<'_, '_> {
1035 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1036 let Self { view, int2name } = self;
1037
1038 let functor = view.functor();
1039 let args = view.args();
1040 let num_args = args.len();
1041
1042 write_int(functor, int2name, f)?;
1043
1044 if num_args > 0 {
1045 f.write_char('(')?;
1046 for (i, arg) in args.enumerate() {
1047 fmt::Display::fmt(&Self::new(arg, int2name), f)?;
1048 if i + 1 < num_args {
1049 f.write_str(", ")?;
1050 }
1051 }
1052 f.write_char(')')?;
1053 }
1054 Ok(())
1055 }
1056 }
1057
1058 impl fmt::Debug for NamedTermView<'_, '_> {
1059 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1060 let Self { view, int2name } = self;
1061
1062 let functor = view.functor();
1063 let args = view.args();
1064 let num_args = args.len();
1065
1066 if num_args == 0 {
1067 write_int(functor, int2name, f)
1068 } else {
1069 let mut d = if let Some(name) = int2name.get(functor) {
1070 f.debug_tuple(name)
1071 } else {
1072 let mut debug_string = String::new();
1073 write!(&mut debug_string, "{:?}", functor)?;
1074 f.debug_tuple(&debug_string)
1075 };
1076
1077 for arg in args {
1078 d.field(&Self::new(arg, int2name));
1079 }
1080 d.finish()
1081 }
1082 }
1083 }
1084
1085 pub(crate) struct NamedTermDeepView<'a, 'cx> {
1086 view: TermDeepView<'a, Int>,
1087 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
1088 }
1089
1090 impl<'a, 'cx> NamedTermDeepView<'a, 'cx> {
1091 pub(crate) const fn new(
1092 view: TermDeepView<'a, Int>,
1093 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
1094 ) -> Self {
1095 Self { view, int2name }
1096 }
1097 }
1098
1099 impl fmt::Display for NamedTermDeepView<'_, '_> {
1100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1101 let Self { view, int2name } = self;
1102
1103 let functor = view.functor();
1104 let args = view.args();
1105 let num_args = args.len();
1106
1107 write_int(functor, int2name, f)?;
1108
1109 if num_args > 0 {
1110 f.write_char('(')?;
1111 for (i, arg) in args.enumerate() {
1112 fmt::Display::fmt(&Self::new(arg, int2name), f)?;
1113 if i + 1 < num_args {
1114 f.write_str(", ")?;
1115 }
1116 }
1117 f.write_char(')')?;
1118 }
1119 Ok(())
1120 }
1121 }
1122
1123 impl fmt::Debug for NamedTermDeepView<'_, '_> {
1124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1125 let Self { view, int2name } = self;
1126
1127 let functor = view.functor();
1128 let args = view.args();
1129 let num_args = args.len();
1130
1131 if num_args == 0 {
1132 write_int(functor, int2name, f)
1133 } else {
1134 let mut d = if let Some(name) = int2name.get(functor) {
1135 f.debug_tuple(name)
1136 } else {
1137 let mut debug_string = String::new();
1138 write!(&mut debug_string, "{:?}", functor)?;
1139 f.debug_tuple(&debug_string)
1140 };
1141
1142 for arg in args {
1143 d.field(&Self::new(arg, int2name));
1144 }
1145 d.finish()
1146 }
1147 }
1148 }
1149
1150 pub struct NamedExprView<'a, 'cx> {
1151 view: ExprView<'a, Int>,
1152 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
1153 }
1154
1155 impl<'a, 'cx> NamedExprView<'a, 'cx> {
1156 pub(crate) const fn new(
1157 view: ExprView<'a, Int>,
1158 int2name: &'a IdxMap<'cx, Int, Name<'cx>>,
1159 ) -> Self {
1160 Self { view, int2name }
1161 }
1162
1163 pub fn contains_term(&self, term: &Term<Name<'cx>>) -> bool {
1164 match self.view.as_kind() {
1165 ExprKind::Term(view) => NamedTermView {
1166 view,
1167 int2name: self.int2name,
1168 }
1169 .contains(term),
1170 ExprKind::Not(view) => NamedExprView {
1171 view,
1172 int2name: self.int2name,
1173 }
1174 .contains_term(term),
1175 ExprKind::And(args) | ExprKind::Or(args) => args.into_iter().any(|view| {
1176 NamedExprView {
1177 view,
1178 int2name: self.int2name,
1179 }
1180 .contains_term(term)
1181 }),
1182 }
1183 }
1184 }
1185
1186 impl fmt::Display for NamedExprView<'_, '_> {
1187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1188 let Self { view, int2name } = self;
1189
1190 match view.as_kind() {
1191 ExprKind::Term(term) => fmt::Display::fmt(
1192 &NamedTermView {
1193 view: term,
1194 int2name,
1195 },
1196 f,
1197 )?,
1198 ExprKind::Not(inner) => {
1199 f.write_str("\\+ ")?;
1200 if matches!(inner.as_kind(), ExprKind::And(_) | ExprKind::Or(_)) {
1201 f.write_char('(')?;
1202 fmt::Display::fmt(&Self::new(inner, int2name), f)?;
1203 f.write_char(')')?;
1204 } else {
1205 fmt::Display::fmt(&Self::new(inner, int2name), f)?;
1206 }
1207 }
1208 ExprKind::And(args) => {
1209 let num_args = args.len();
1210 for (i, arg) in args.enumerate() {
1211 if matches!(arg.as_kind(), ExprKind::Or(_)) {
1212 f.write_char('(')?;
1213 fmt::Display::fmt(&Self::new(arg, int2name), f)?;
1214 f.write_char(')')?;
1215 } else {
1216 fmt::Display::fmt(&Self::new(arg, int2name), f)?;
1217 }
1218 if i + 1 < num_args {
1219 f.write_str(", ")?;
1220 }
1221 }
1222 }
1223 ExprKind::Or(args) => {
1224 let num_args = args.len();
1225 for (i, arg) in args.enumerate() {
1226 fmt::Display::fmt(&Self::new(arg, int2name), f)?;
1227 if i + 1 < num_args {
1228 f.write_str("; ")?;
1229 }
1230 }
1231 }
1232 }
1233 Ok(())
1234 }
1235 }
1236
1237 impl fmt::Debug for NamedExprView<'_, '_> {
1238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1239 let Self { view, int2name } = self;
1240
1241 match view.as_kind() {
1242 ExprKind::Term(term) => fmt::Debug::fmt(&NamedTermView::new(term, int2name), f),
1243 ExprKind::Not(inner) => f
1244 .debug_tuple("Not")
1245 .field(&NamedExprView::new(inner, int2name))
1246 .finish(),
1247 ExprKind::And(args) => {
1248 let mut d = f.debug_tuple("And");
1249 for arg in args {
1250 d.field(&NamedExprView::new(arg, int2name));
1251 }
1252 d.finish()
1253 }
1254 ExprKind::Or(args) => {
1255 let mut d = f.debug_tuple("Or");
1256 for arg in args {
1257 d.field(&NamedExprView::new(arg, int2name));
1258 }
1259 d.finish()
1260 }
1261 }
1262 }
1263 }
1264
1265 fn write_int(
1266 int: &Int,
1267 map: &IdxMap<'_, Int, Name<'_>>,
1268 f: &mut fmt::Formatter<'_>,
1269 ) -> fmt::Result {
1270 if let Some(name) = map.get(int) {
1271 f.write_str(name)
1272 } else {
1273 fmt::Debug::fmt(int, f)
1274 }
1275 }
1276}