]> Repositorios git - scryer-prolog.git/commitdiff
follow marked variables to end in eager_stackful_iter (#2100, #2101)
authorMark <[email protected]>
Tue, 10 Oct 2023 22:02:38 +0000 (16:02 -0600)
committerMark <[email protected]>
Tue, 10 Oct 2023 22:03:12 +0000 (16:03 -0600)
src/heap_iter.rs
src/tests/term_variables.pl

index 02d87ace9a867987791f26ddf7d7ebe2649fc229..032ce6bd497f5bb489356ac5aa8b4e939474d48f 100644 (file)
@@ -56,18 +56,29 @@ impl<'a> EagerStackfulPreOrderHeapIter<'a> {
         }
     }
 
+    #[inline]
+    fn is_self_ref_var(&self, value: HeapCellValue) -> bool {
+        if value.is_var() {
+            let h = value.get_value() as usize;
+
+            if self.heap[h].is_var() && self.heap[h].get_value() as usize == h {
+                return true;
+            }
+        }
+
+        false
+    }
+
     fn follow(&mut self) -> Option<HeapCellValue> {
         while let Some(value) = self.iter_stack.pop() {
             if value.get_mark_bit() == self.mark_phase {
-                if value.is_var() {
-                    let h = value.get_value() as usize;
-
-                    if self.heap[h].is_var() && self.heap[h].get_value() as usize == h {
-                        return Some(unmark_cell_bits!(value));
-                    }
+                // follow marked variables to their end. only marked
+                // non-variables are ignored.
+                if self.is_self_ref_var(value) {
+                    return Some(unmark_cell_bits!(value));
+                } else if !value.is_var() {
+                    continue;
                 }
-
-                continue;
             }
 
             read_heap_cell!(value,
@@ -90,7 +101,7 @@ impl<'a> EagerStackfulPreOrderHeapIter<'a> {
                     let var_value = self.heap[h];
                     self.heap[h].set_mark_bit(self.mark_phase);
 
-                    if !(var_value.is_var() && var_value.get_value() as usize == h) {
+                    if !(self.heap[h].is_var() && self.heap[h].get_value() as usize == h) {
                         self.iter_stack.push(var_value);
                         continue;
                     }
index 01dde0d1a4e752443a647aa036e3d0e69f1ddb3d..dce49c83654e3f339852a722908d6a438d9d9c4a 100644 (file)
@@ -43,12 +43,34 @@ test("term_variables#2097", (
     T = [[[A|B]|A]|A], Vs == [A,B]
 )).
 
+test("term_variables#2100", (
+    termt2(T), term_variables(T,Vs),
+    T = [[T|_B]|_A], Vs == [_A,_B]
+)).
+
+test("term_variables#2101", (
+    termt3(T), term_variables(T,Vs),
+    T = [[[[A|B]|A]|A]|A], Vs == [A, B]
+)).
+
 termt(T) :-
    T = [T1|T2],
    T1 = [T3|A],
    T3 = [A|_],
    T2 = A.
 
+termt2(T) :-
+   T = [T1|_B],
+   T1 = [T|_A].
+
+termt3(T) :-
+   T = [T1|T0],
+   T1 = [T2|T3],
+   T2 = [T4|A],
+   T4 = [A|_],
+   T3 = A,
+   T0 = A.
+
 main :-
     findall(test(Name, Goal), test(Name, Goal), Tests),
     run_tests(Tests, Failed),