]> Repositorios git - scryer-prolog.git/commitdiff
eliminate duplicates in term_variables/2, term_attributed_variables/2 (#481)
authorMark Thom <[email protected]>
Sun, 10 May 2020 19:43:39 +0000 (13:43 -0600)
committerMark Thom <[email protected]>
Sun, 10 May 2020 19:43:39 +0000 (13:43 -0600)
src/prolog/machine/attributed_variables.rs
src/prolog/machine/system_calls.rs

index b7e9ceee345ad82ed95be5440d81c8afff348b7a..3ca2ec2e20bd2e29aff6b04f013c483e805c9a8a 100644 (file)
@@ -1,6 +1,8 @@
 use crate::prolog::heap_iter::*;
 use crate::prolog::machine::*;
 
+use crate::indexmap::IndexSet;
+
 use std::cmp::Ordering;
 use std::vec::IntoIter;
 
@@ -141,12 +143,19 @@ impl MachineState {
 
     pub(super)
     fn attr_vars_of_term(&self, addr: Addr) -> Vec<Addr> {
+        let mut seen_set  = IndexSet::new();
         let mut seen_vars = vec![];
+
         let mut iter = self.acyclic_pre_order_iter(addr);
 
         while let Some(addr) = iter.next() {
             if let HeapCellValue::Addr(Addr::AttrVar(h)) = self.heap.index_addr(&addr).as_ref() {
+                if seen_set.contains(h) {
+                    continue;
+                }
+
                 seen_vars.push(addr);
+                seen_set.insert(*h);
 
                 let mut l = h + 1;
                 let mut list_elements = vec![];
index 47780568d1ef31f3995800e2f4a9195a77231876..b4857b59a8e73fe8f8efb3858a66e169b0109598 100644 (file)
@@ -18,6 +18,8 @@ use crate::prolog::ordered_float::OrderedFloat;
 use crate::prolog::read::readline;
 use crate::prolog::rug::Integer;
 
+use crate::indexmap::IndexSet;
+
 use crate::ref_thread_local::RefThreadLocal;
 
 use std::cmp;
@@ -4838,11 +4840,13 @@ impl MachineState {
             }
             &SystemClauseType::TermVariables => {
                 let a1 = self[temp_v!(1)];
+                let mut seen_set  = IndexSet::new();
                 let mut seen_vars = vec![];
 
                 for addr in self.acyclic_pre_order_iter(a1) {
-                    if addr.is_ref() {
+                    if addr.is_ref() && !seen_set.contains(&addr) {
                         seen_vars.push(addr);
+                        seen_set.insert(addr);
                     }
                 }