1use std::{
2 collections::HashMap,
3 mem,
4 ops::{Index, IndexMut, Range, RangeInclusive},
5};
6
7use super::symbol_db::SymbolDB;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14#[repr(u8)]
15pub enum Tag {
16 Ref,
18 Arg,
20 Func,
22 Tup,
24 Set,
26 Lis,
28 ELis,
30 Con,
32 Int,
34 Flt,
36 Str,
38 Stri,
40}
41
42impl std::fmt::Display for Tag {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 write!(f, "{self:?}")
45 }
46}
47
48pub type Cell = (Tag, usize);
50
51use fsize::fsize;
52pub const _CON_PTR: usize = isize::MAX as usize;
53pub const _FALSE: Cell = (Tag::Con, _CON_PTR);
54pub const _TRUE: Cell = (Tag::Con, _CON_PTR + 1);
55pub const EMPTY_LIS: Cell = (Tag::ELis, 0);
56
57pub trait Heap: IndexMut<usize, Output = Cell> + Index<Range<usize>, Output = [Cell]> {
63 fn heap_push(&mut self, cell: Cell) -> usize;
64
65 fn heap_len(&self) -> usize;
66
67 fn truncate(&mut self, len: usize);
68
69 fn get_id(&self) -> usize {
70 0
71 }
72
73 fn _set_arg(&mut self, value: usize) -> usize {
74 self.heap_push((Tag::Arg, value));
76 return self.heap_len() - 1;
77 }
78
79 fn set_const(&mut self, id: usize) -> usize {
80 let h = self.heap_len();
81 self.heap_push((Tag::Con, id));
82 h
83 }
84
85 fn set_ref(&mut self, ref_addr: Option<usize>) -> usize {
86 let addr = match ref_addr {
88 Some(a) => a,
89 None => self.heap_len(),
90 };
91 self.heap_push((Tag::Ref, addr));
92 return self.heap_len() - 1;
93 }
94
95 fn deref_addr(&self, mut addr: usize) -> usize {
96 loop {
97 match self[addr] {
98 (Tag::Ref, pointer) if addr == pointer => return pointer,
99 (Tag::Ref, pointer) => addr = pointer,
100 _ => return addr,
102 }
103 }
104 }
105
106 fn bind(&mut self, binding: &[(usize, usize)]) {
110 for (src, target) in binding {
111 let pointer = &mut self[*src].1;
113 if *pointer != *src {
114 panic!("Tried to reset bound ref: {} \n Binding: {binding:?}", src)
115 }
116 *pointer = *target;
117 }
118 }
119
120 fn unbind(&mut self, binding: &[(usize, usize)]) {
124 for (src, _target) in binding {
125 if let (Tag::Ref, pointer) = &mut self[*src] {
126 *pointer = *src;
127 }
128 }
129 }
130
131 fn str_symbol_arity(&self, mut addr: usize) -> (usize, usize) {
133 addr = self.deref_addr(addr);
134 if let (Tag::Str, pointer) = self[addr] {
135 addr = pointer
136 }
137 if let (Tag::Func, arity) = self[addr] {
138 match self[self.deref_addr(addr + 1)] {
139 (Tag::Arg | Tag::Ref, _) => (0, arity - 1),
140 (Tag::Con, id) => (id, arity - 1),
141 _ => panic!("Functor of structure not constant of variable"),
142 }
143 } else if let (Tag::Con, symbol) = self[addr] {
144 (symbol, 0)
145 } else {
146 panic!(
147 "No str arity for {}, {:?}",
148 self.term_string(addr),
149 self[addr]
150 )
151 }
152 }
153
154 fn term_vars(&self, mut addr: usize, args: bool) -> Vec<usize> {
158 addr = self.deref_addr(addr);
159 match self[addr].0 {
160 Tag::Arg if args => vec![addr],
161 Tag::Ref if !args => vec![addr],
162 Tag::Lis => [
163 self.term_vars(self[addr].1, args),
164 self.term_vars(self[addr].1 + 1, args),
165 ]
166 .concat(),
167 Tag::Func => self
168 .str_iterator(addr)
169 .map(|addr| self.term_vars(addr, args))
170 .collect::<Vec<Vec<usize>>>()
171 .concat(),
172 _ => vec![],
173 }
174 }
175
176 fn str_iterator(&self, addr: usize) -> RangeInclusive<usize> {
178 addr + 1..=addr + self[addr].1
179 }
180
181 fn _normalise_args(&mut self, addr: usize, args: &[usize]) {
182 match self[addr] {
183 (Tag::Str, pointer) => self._normalise_args(pointer, args),
184 (Tag::Func, _) => {
185 for i in self.str_iterator(addr) {
186 self._normalise_args(i, args)
187 }
188 }
189 (Tag::Tup, _) => unimplemented!("_normalise_args for Tup"),
190 (Tag::Set, _) => unimplemented!("_normalise_args for Set"),
191 (Tag::Lis, pointer) => {
192 self._normalise_args(pointer, args);
193 self._normalise_args(pointer + 1, args);
194 }
195 (Tag::Arg, value) => self[addr].1 = args.iter().position(|i| value == *i).unwrap(),
196 _ => (),
197 }
198 }
199
200 fn _copy_complex(&mut self, other: &impl Heap, mut addr: usize, update_addr: &mut usize) {
201 addr = other.deref_addr(addr);
202 match other[addr] {
203 (Tag::Str, pointer) => *update_addr = self._copy_term(other, pointer),
204 (Tag::Lis, _) => *update_addr = self._copy_term(other, addr),
205 _ => (),
206 }
207 }
208
209 fn _copy_simple(&mut self, other: &impl Heap, mut addr: usize, update_addr: &usize) {
210 addr = other.deref_addr(addr);
211 match other[addr] {
212 (Tag::Lis, _) => self.heap_push((Tag::Lis, *update_addr)),
213 (Tag::Str, _) => self.heap_push((Tag::Str, *update_addr)),
214 (Tag::Ref, _) => self.heap_push((Tag::Ref, self.heap_len())),
215 (_, _) => self.heap_push(other[addr]),
216 };
217 }
218
219 fn _copy_term(&mut self, other: &impl Heap, addr: usize) -> usize {
220 let addr = other.deref_addr(addr);
222 match other[addr] {
223 (Tag::Str, mut pointer) => {
224 pointer = self._copy_term(other, pointer);
225 self.heap_push((Tag::Str, pointer));
226 self.heap_len() - 1
227 }
228 (Tag::Func, arity) => {
229 let mut update_addr: Vec<usize> = vec![0; arity];
230 for (i, a) in other.str_iterator(addr).enumerate() {
231 self._copy_complex(other, a, &mut update_addr[i])
232 }
233 let h = self.heap_len();
234 self.heap_push((Tag::Func, arity));
235 for (i, a) in other.str_iterator(addr).enumerate() {
236 self._copy_simple(other, a, &update_addr[i]);
237 }
238 h
239 }
240 (Tag::Lis, pointer) => {
241 let mut update_addr: Vec<usize> = vec![0; 2];
242 self._copy_complex(other, pointer, &mut update_addr[0]);
243 self._copy_complex(other, pointer + 1, &mut update_addr[1]);
244
245 let h = self.heap_len();
246 self._copy_simple(other, pointer, &mut update_addr[0]);
247 self._copy_simple(other, pointer + 1, &mut update_addr[1]);
248 h
249 }
250 (Tag::Tup, _len) => unimplemented!("_copy_term for Tup"),
251 (Tag::Set, _len) => unimplemented!("_copy_term for Set"),
252 (Tag::Ref, _pointer) => panic!(),
253 (Tag::Arg | Tag::Con | Tag::Int | Tag::Flt | Tag::Stri | Tag::ELis, _) => {
254 self.heap_push(other[addr]);
255 self.heap_len() - 1
256 }
257 }
258 }
259
260 fn copy_term_with_ref_map(
266 &mut self,
267 other: &impl Heap,
268 addr: usize,
269 ref_map: &mut HashMap<usize, usize>,
270 ) -> usize {
271 let addr = other.deref_addr(addr);
272 match other[addr] {
273 (Tag::Str, pointer) => {
274 let new_ptr = self.copy_term_with_ref_map(other, pointer, ref_map);
275 self.heap_push((Tag::Str, new_ptr));
276 self.heap_len() - 1
277 }
278 (Tag::Func | Tag::Tup | Tag::Set, length) => {
279 let mut pre: Vec<Option<Cell>> = Vec::with_capacity(length);
281 for i in 1..=length {
282 pre.push(self._copy_ref_map_complex(other, addr + i, ref_map));
283 }
284 let h = self.heap_len();
286 self.heap_push((other[addr].0, length));
287 for (i, pre_cell) in pre.into_iter().enumerate() {
288 match pre_cell {
289 Some(cell) => { self.heap_push(cell); }
290 None => self._copy_ref_map_simple(other, addr + 1 + i, ref_map),
291 }
292 }
293 h
294 }
295 (Tag::Lis, pointer) => {
296 let head = self._copy_ref_map_complex(other, pointer, ref_map);
297 let tail = self._copy_ref_map_complex(other, pointer + 1, ref_map);
298 let h = self.heap_len();
299 match head {
300 Some(cell) => { self.heap_push(cell); }
301 None => self._copy_ref_map_simple(other, pointer, ref_map),
302 }
303 match tail {
304 Some(cell) => { self.heap_push(cell); }
305 None => self._copy_ref_map_simple(other, pointer + 1, ref_map),
306 }
307 h
308 }
309 (Tag::Ref, r) if r == addr => {
310 if let Some(&mapped) = ref_map.get(&addr) {
312 mapped
313 } else {
314 let new_addr = self.heap_len();
315 self.heap_push((Tag::Ref, new_addr));
316 ref_map.insert(addr, new_addr);
317 new_addr
318 }
319 }
320 (Tag::Arg | Tag::Con | Tag::Int | Tag::Flt | Tag::Stri | Tag::ELis, _) => {
321 self.heap_push(other[addr]);
322 self.heap_len() - 1
323 }
324 (tag, val) => panic!("copy_term_with_ref_map: unhandled ({tag:?}, {val})"),
325 }
326 }
327
328 fn _copy_ref_map_complex(
331 &mut self,
332 other: &impl Heap,
333 addr: usize,
334 ref_map: &mut HashMap<usize, usize>,
335 ) -> Option<Cell> {
336 let addr = other.deref_addr(addr);
337 match other[addr] {
338 (Tag::Func | Tag::Tup | Tag::Set, _) => {
339 Some((Tag::Str, self.copy_term_with_ref_map(other, addr, ref_map)))
340 }
341 (Tag::Str, ptr) => {
342 Some((Tag::Str, self.copy_term_with_ref_map(other, ptr, ref_map)))
343 }
344 (Tag::Lis, _) => {
345 Some((Tag::Lis, self.copy_term_with_ref_map(other, addr, ref_map)))
346 }
347 _ => None,
348 }
349 }
350
351 fn _copy_ref_map_simple(
354 &mut self,
355 other: &impl Heap,
356 addr: usize,
357 ref_map: &mut HashMap<usize, usize>,
358 ) {
359 let addr = other.deref_addr(addr);
360 match other[addr] {
361 (Tag::Ref, r) if r == addr => {
362 if let Some(&mapped) = ref_map.get(&addr) {
363 self.heap_push((Tag::Ref, mapped));
364 } else {
365 let new_addr = self.heap_len();
366 self.heap_push((Tag::Ref, new_addr));
367 ref_map.insert(addr, new_addr);
368 }
369 }
370 cell => { self.heap_push(cell); }
371 }
372 }
373
374 fn _term_equal(&self, mut addr1: usize, mut addr2: usize) -> bool {
375 addr1 = self.deref_addr(addr1);
376 addr2 = self.deref_addr(addr2);
377 match (self[addr1], self[addr2]) {
378 (EMPTY_LIS, EMPTY_LIS) => true,
379 (EMPTY_LIS, _) => false,
380 (_, EMPTY_LIS) => false,
381 ((Tag::Func, a1), (Tag::Func, a2)) if a1 == a2 => self
382 .str_iterator(addr1)
383 .zip(self.str_iterator(addr2))
384 .all(|(addr1, addr2)| self._term_equal(addr1, addr2)),
385 ((Tag::Lis, p1), (Tag::Lis, p2)) => {
386 self._term_equal(p1, p2) && self._term_equal(p1 + 1, p2 + 1)
387 }
388 ((Tag::Str, p1), (Tag::Str, p2)) => self._term_equal(p1, p2),
389 ((Tag::Tup, _len1), (Tag::Tup, _len2)) => unimplemented!("_term_equal for Tup"),
390 ((Tag::Set, _len1), (Tag::Set, _len2)) => unimplemented!("_term_equal for Set"),
391 ((Tag::Stri, i1), (Tag::Stri, i2)) => {
392 SymbolDB::get_string(i1) == SymbolDB::get_string(i2)
393 }
394
395 _ => self[addr1] == self[addr2],
396 }
397 }
398
399 fn contains_args(&self, mut addr: usize) -> bool {
400 addr = self.deref_addr(addr);
401 match self[addr] {
402 (Tag::Arg, _) => true,
403 (Tag::Lis, ptr) => self.contains_args(ptr) || self.contains_args(ptr + 1),
404 (Tag::Str, ptr) => self.contains_args(ptr),
405 (Tag::Func | Tag::Set | Tag::Tup, length) => {
406 (addr + 1..addr + 1 + length).any(|addr| self.contains_args(addr))
407 }
408 _ => false,
409 }
410 }
411
412 fn _print_heap(&self) {
414 let w = 6;
415 for i in 0..self.heap_len() {
416 let (tag, value) = self[i];
417 match tag {
418 Tag::Con => {
419 println!("[{i:3}]|{tag:w$}|{:w$}|", SymbolDB::get_const(value))
420 }
421 Tag::Lis => {
422 if value == _CON_PTR {
423 println!("[{i:3}]|{tag:w$}|{:w$}|", "[]")
424 } else {
425 println!("[{i:3}]|{tag:w$}|{value:w$}|")
426 }
427 }
428 Tag::Ref | Tag::Arg => {
429 println!("[{i:3}]|{tag:w$?}|{value:w$}|:({})", self.term_string(i))
430 }
431 Tag::Int => {
432 let value: isize = unsafe { mem::transmute_copy(&value) };
433 println!("[{i:3}]|{tag:w$?}|{value:w$}|")
434 }
435 Tag::Flt => {
436 let value: fsize = unsafe { mem::transmute_copy(&value) };
437 println!("[{i:3}]|{tag:w$?}|{value:w$}|")
438 }
439 Tag::Tup => unimplemented!("_print_heap for Tup"),
440 Tag::Set => unimplemented!("_print_heap for Set"),
441 Tag::Stri => unimplemented!("_print_heap for Stri"),
442 _ => println!("[{i:3}]|{tag:w$?}|{value:w$}|"),
443 };
444 println!("{:-<w$}--------{:-<w$}", "", "");
445 }
446 }
447
448 fn list_string(&self, addr: usize) -> String {
450 let mut buffer = "[".to_string();
451 let mut pointer = self[addr].1;
452
453 loop {
454 buffer += &self.term_string(pointer);
455
456 match self[pointer + 1].0 {
457 Tag::Lis => {
458 buffer += ",";
459 pointer = self[pointer + 1].1
460 }
461 Tag::ELis => break,
462 _ => {
463 buffer += "|";
464 buffer += &self.term_string(pointer + 1);
465 break;
466 }
467 }
468 }
469 buffer += "]";
470 buffer
471 }
472
473 fn func_string(&self, addr: usize) -> String {
475 let mut buf = "".to_string();
476 let mut first = true;
477 for i in self.str_iterator(addr) {
478 buf += &self.term_string(i);
479 buf += if first { "(" } else { "," };
480 if first {
481 first = false
482 }
483 }
484 buf.pop();
485 buf += ")";
486 buf
487 }
488
489 fn tuple_string(&self, addr: usize) -> String {
491 let mut buf = String::from("(");
492 for i in 1..self[addr].1 + 1 {
493 buf += &self.term_string(addr + i);
494 buf += ",";
495 }
496 buf.pop();
497 buf += ")";
498 buf
499 }
500
501 fn set_string(&self, addr: usize) -> String {
503 let mut buf = String::from("{");
504 for i in 1..self[addr].1 + 1 {
505 buf += &self.term_string(addr + i);
506 buf += ",";
507 }
508 buf.pop();
509 buf += "}";
510 buf
511 }
512
513 fn term_string(&self, addr: usize) -> String {
515 let addr = self.deref_addr(addr);
517 match self[addr].0 {
518 Tag::Con => SymbolDB::get_const(self[addr].1).to_string(),
519 Tag::Func => self.func_string(addr),
520 Tag::Lis => self.list_string(addr),
521 Tag::ELis => "[]".into(),
522 Tag::Arg => match SymbolDB::get_var(addr, self.get_id()) {
523 Some(symbol) => symbol.to_string(),
524 None => format!("Arg_{}", self[addr].1),
525 },
526 Tag::Ref => match SymbolDB::get_var(self.deref_addr(addr), self.get_id()).to_owned() {
527 Some(symbol) => symbol.to_string(),
528 None => format!("Ref_{}", self[addr].1),
529 },
530 Tag::Int => {
531 let value: isize = unsafe { mem::transmute_copy(&self[addr].1) };
532 format!("{value}")
533 }
534 Tag::Flt => {
535 let value: fsize = unsafe { mem::transmute_copy(&self[addr].1) };
536 format!("{value}")
537 }
538 Tag::Tup => self.tuple_string(addr),
539 Tag::Set => self.set_string(addr),
540 Tag::Str => self.term_string(self[addr].1),
541 Tag::Stri => SymbolDB::get_string(self[addr].1).to_string(),
542 }
543 }
544}
545
546impl Heap for Vec<Cell> {
547 fn heap_push(&mut self, cell: Cell) -> usize {
548 let i = self.len();
549 self.push(cell);
550 i
551 }
552
553 fn heap_len(&self) -> usize {
554 self.len()
555 }
556
557 fn truncate(&mut self, len: usize) {
558 self.resize(len, (Tag::Ref,0));
559 }
560}
561
562#[cfg(test)]
563mod tests {
564 use std::sync::Arc;
565
566 use crate::heap::query_heap::QueryHeap;
567
568 use super::{
569 super::symbol_db::SymbolDB,
570 {Cell, Heap, Tag, EMPTY_LIS},
571 };
572
573 #[test]
574 fn encode_argument_variable() {
575 let prog_cells = Arc::new(Vec::<Cell>::new());
576 let mut heap = QueryHeap::new(prog_cells, None);
577
578 let addr1 = heap._set_arg(0);
579 let addr2 = heap._set_arg(1);
580
581 assert_eq!(heap.term_string(addr1), "Arg_0");
582 assert_eq!(heap.term_string(addr2), "Arg_1");
583 }
584
585 #[test]
586 fn encode_ref_variable() {
587 let prog_cells = Arc::new(Vec::<Cell>::new());
588 let mut heap = QueryHeap::new(prog_cells, None);
589
590 let addr1 = heap.set_ref(None);
591 let addr2 = heap.set_ref(Some(addr1));
592
593 assert_eq!(heap.term_string(addr1), "Ref_0");
594 assert_eq!(heap.term_string(addr2), "Ref_0");
595 }
596
597 #[test]
598 fn encode_constant() {
599 let prog_cells = Arc::new(Vec::<Cell>::new());
600 let mut heap = QueryHeap::new(prog_cells, None);
601
602 let a = SymbolDB::set_const("a".into());
603 let b = SymbolDB::set_const("b".into());
604
605 let addr1 = heap.set_const(a);
606 let addr2 = heap.set_const(b);
607
608 assert_eq!(heap.term_string(addr1), "a");
609 assert_eq!(heap.term_string(addr2), "b");
610 }
611
612 #[test]
613 fn encode_functor() {
614 let p = SymbolDB::set_const("p".into());
615 let f = SymbolDB::set_const("f".into());
616 let a = SymbolDB::set_const("a".into());
617
618 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
619 heap.cells.extend(vec![
620 (Tag::Str, 1),
621 (Tag::Func, 3),
622 (Tag::Con, p),
623 (Tag::Arg, 0),
624 (Tag::Con, a),
625 ]);
626
627 assert_eq!(heap.term_string(0), "p(Arg_0,a)");
628
629 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
630 heap.cells.extend(vec![
631 (Tag::Str, 1),
632 (Tag::Func, 3),
633 (Tag::Con, p),
634 (Tag::Str, 5),
635 (Tag::Con, a),
636 (Tag::Func, 2),
637 (Tag::Con, f),
638 (Tag::Ref, 7),
639 ]);
640 assert_eq!(heap.term_string(0), "p(f(Ref_7),a)");
641
642 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
643 heap.cells.extend(vec![
644 (Tag::Str, 1),
645 (Tag::Func, 3),
646 (Tag::Con, p),
647 (Tag::Str, 5),
648 (Tag::Con, a),
649 (Tag::Tup, 2),
650 (Tag::Con, f),
651 (Tag::Ref, 7),
652 ]);
653 assert_eq!(heap.term_string(0), "p((f,Ref_7),a)");
654
655 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
656 heap.cells.extend(vec![
657 (Tag::Str, 1),
658 (Tag::Func, 3),
659 (Tag::Con, p),
660 (Tag::Str, 5),
661 (Tag::Con, a),
662 (Tag::Set, 2),
663 (Tag::Con, f),
664 (Tag::Ref, 7),
665 ]);
666
667 assert_eq!(heap.term_string(0), "p({f,Ref_7},a)");
668
669 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
670 heap.cells.extend(vec![
671 (Tag::Str, 1),
672 (Tag::Func, 3),
673 (Tag::Con, p),
674 (Tag::Lis, 5),
675 (Tag::Con, a),
676 (Tag::Con, f),
677 (Tag::Lis, 7),
678 (Tag::Ref, 7),
679 EMPTY_LIS,
680 ]);
681 assert_eq!(heap.term_string(0), "p([f,Ref_7],a)");
682 }
683
684 #[test]
685 fn encode_tuple() {
686 let f = SymbolDB::set_const("f".into());
687 let a = SymbolDB::set_const("a".into());
688
689 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
690 heap.cells.extend(vec![(Tag::Str, 1), (Tag::Tup, 2), (Tag::Arg, 0), (Tag::Con, a)]);
691 assert_eq!(heap.term_string(0), "(Arg_0,a)");
692
693 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
694 heap.cells.extend(vec![
695 (Tag::Str, 1),
696 (Tag::Tup, 2),
697 (Tag::Str, 4),
698 (Tag::Con, a),
699 (Tag::Func, 2),
700 (Tag::Con, f),
701 (Tag::Ref, 6),
702 ]);
703 assert_eq!(heap.term_string(0), "(f(Ref_6),a)");
704
705 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
706 heap.cells.extend(vec![
707 (Tag::Str, 1),
708 (Tag::Tup, 2),
709 (Tag::Str, 4),
710 (Tag::Con, a),
711 (Tag::Tup, 2),
712 (Tag::Con, f),
713 (Tag::Ref, 6),
714 ]);
715 assert_eq!(heap.term_string(0), "((f,Ref_6),a)");
716
717 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
718 heap.cells.extend(vec![
719 (Tag::Str, 1),
720 (Tag::Tup, 2),
721 (Tag::Str, 4),
722 (Tag::Con, a),
723 (Tag::Set, 2),
724 (Tag::Con, f),
725 (Tag::Ref, 6),
726 ]);
727 assert_eq!(heap.term_string(0), "({f,Ref_6},a)");
728
729 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
730 heap.cells.extend(vec![
731 (Tag::Str, 1),
732 (Tag::Tup, 2),
733 (Tag::Lis, 4),
734 (Tag::Con, a),
735 (Tag::Con, f),
736 (Tag::Lis, 6),
737 (Tag::Ref, 6),
738 EMPTY_LIS,
739 ]);
740 assert_eq!(heap.term_string(0), "([f,Ref_6],a)");
741 }
742
743 #[test]
744 fn encode_list() {
745 let f = SymbolDB::set_const("f".into());
746 let a = SymbolDB::set_const("a".into());
747
748 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
749 heap.cells.extend(vec![
750 (Tag::Lis, 1),
751 (Tag::Arg, 0),
752 (Tag::Lis, 3),
753 (Tag::Con, a),
754 EMPTY_LIS,
755 ]);
756 assert_eq!(heap.term_string(0), "[Arg_0,a]");
757
758 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
759 heap.cells.extend(vec![
760 (Tag::Lis, 1),
761 (Tag::Str, 5),
762 (Tag::Lis, 3),
763 (Tag::Con, a),
764 EMPTY_LIS,
765 (Tag::Func, 2),
766 (Tag::Con, f),
767 (Tag::Ref, 7),
768 ]);
769 assert_eq!(heap.term_string(0), "[f(Ref_7),a]");
770
771 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
772 heap.cells.extend(vec![
773 (Tag::Lis, 1),
774 (Tag::Str, 5),
775 (Tag::Lis, 3),
776 (Tag::Con, a),
777 EMPTY_LIS,
778 (Tag::Tup, 2),
779 (Tag::Con, f),
780 (Tag::Ref, 7),
781 ]);
782 assert_eq!(heap.term_string(0), "[(f,Ref_7),a]");
783
784 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
785 heap.cells.extend(vec![
786 (Tag::Lis, 1),
787 (Tag::Str, 5),
788 (Tag::Lis, 3),
789 (Tag::Con, a),
790 EMPTY_LIS,
791 (Tag::Set, 2),
792 (Tag::Con, f),
793 (Tag::Ref, 7),
794 ]);
795 assert_eq!(heap.term_string(0), "[{f,Ref_7},a]");
796
797 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
798 heap.cells.extend(vec![
799 (Tag::Lis, 1),
800 (Tag::Lis, 5),
801 (Tag::Lis, 3),
802 (Tag::Con, a),
803 EMPTY_LIS,
804 (Tag::Con, f),
805 (Tag::Lis, 7),
806 (Tag::Ref, 7),
807 EMPTY_LIS,
808 ]);
809 assert_eq!(heap.term_string(0), "[[f,Ref_7],a]");
810 }
811
812 #[test]
813 fn encode_set() {
814 let f = SymbolDB::set_const("f".into());
815 let a = SymbolDB::set_const("a".into());
816
817 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
818 heap.cells.extend(vec![(Tag::Str, 1), (Tag::Set, 2), (Tag::Arg, 0), (Tag::Con, a)]);
819 assert_eq!(heap.term_string(0), "{Arg_0,a}");
820
821 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
822 heap.cells.extend(vec![
823 (Tag::Str, 1),
824 (Tag::Set, 2),
825 (Tag::Str, 4),
826 (Tag::Con, a),
827 (Tag::Func, 2),
828 (Tag::Con, f),
829 (Tag::Ref, 6),
830 ]);
831 assert_eq!(heap.term_string(0), "{f(Ref_6),a}");
832
833 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
834 heap.cells.extend(vec![
835 (Tag::Str, 1),
836 (Tag::Set, 2),
837 (Tag::Str, 4),
838 (Tag::Con, a),
839 (Tag::Tup, 2),
840 (Tag::Con, f),
841 (Tag::Ref, 6),
842 ]);
843 assert_eq!(heap.term_string(0), "{(f,Ref_6),a}");
844
845 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
846 heap.cells.extend(vec![
847 (Tag::Str, 1),
848 (Tag::Set, 2),
849 (Tag::Str, 4),
850 (Tag::Con, a),
851 (Tag::Set, 2),
852 (Tag::Con, f),
853 (Tag::Ref, 6),
854 ]);
855 assert_eq!(heap.term_string(0), "{{f,Ref_6},a}");
856
857 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
858 heap.cells.extend(vec![
859 (Tag::Str, 1),
860 (Tag::Set, 2),
861 (Tag::Lis, 4),
862 (Tag::Con, a),
863 (Tag::Con, f),
864 (Tag::Lis, 6),
865 (Tag::Ref, 6),
866 EMPTY_LIS,
867 ]);
868 assert_eq!(heap.term_string(0), "{[f,Ref_6],a}");
869 }
870
871 #[test]
872 fn dereference() {
873 let f = SymbolDB::set_const("f".into());
874 let a = SymbolDB::set_const("a".into());
875
876 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
877 heap.cells.extend(vec![(Tag::Ref, 1), (Tag::Ref, 2), (Tag::Ref, 3), (Tag::Ref, 3)]);
878 assert_eq!(heap.term_string(0), "Ref_3");
879
880 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
881 heap.cells.extend(vec![(Tag::Ref, 1), (Tag::Ref, 2), (Tag::Ref, 3), (Tag::Arg, 0)]);
882 assert_eq!(heap.term_string(0), "Arg_0");
883
884 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
885 heap.cells.extend(vec![(Tag::Ref, 1), (Tag::Ref, 2), (Tag::Ref, 3), (Tag::Con, a)]);
886 assert_eq!(heap.term_string(0), "a");
887
888 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
889 heap.cells.extend(vec![
890 (Tag::Ref, 1),
891 (Tag::Ref, 2),
892 (Tag::Ref, 3),
893 (Tag::Str, 4),
894 (Tag::Func, 3),
895 (Tag::Con, f),
896 (Tag::Con, a),
897 (Tag::Ref, 7),
898 ]);
899 assert_eq!(heap.term_string(0), "f(a,Ref_7)");
900
901 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
902 heap.cells.extend(vec![
903 (Tag::Ref, 1),
904 (Tag::Ref, 2),
905 (Tag::Ref, 3),
906 (Tag::Str, 4),
907 (Tag::Tup, 2),
908 (Tag::Con, a),
909 (Tag::Ref, 6),
910 ]);
911 assert_eq!(heap.term_string(0), "(a,Ref_6)");
912
913 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
914 heap.cells.extend(vec![
915 (Tag::Ref, 1),
916 (Tag::Ref, 2),
917 (Tag::Ref, 3),
918 (Tag::Str, 4),
919 (Tag::Set, 2),
920 (Tag::Con, a),
921 (Tag::Ref, 6),
922 ]);
923 assert_eq!(heap.term_string(0), "{a,Ref_6}");
924
925 let mut heap = QueryHeap::new(Arc::new(vec![]), None);
926 heap.cells.extend(vec![
927 (Tag::Ref, 1),
928 (Tag::Ref, 2),
929 (Tag::Ref, 3),
930 (Tag::Lis, 4),
931 (Tag::Con, a),
932 (Tag::Lis, 6),
933 (Tag::Ref, 6),
934 EMPTY_LIS,
935 ]);
936 assert_eq!(heap.term_string(0), "[a,Ref_6]");
937 }
938}