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