]> Repositorios git - scryer-prolog.git/commitdiff
add term_attributed_variables/2 (#422)
authorMark Thom <[email protected]>
Sun, 3 May 2020 00:46:29 +0000 (18:46 -0600)
committerMark Thom <[email protected]>
Sun, 3 May 2020 00:46:29 +0000 (18:46 -0600)
src/prolog/clause_types.rs
src/prolog/heap_iter.rs
src/prolog/lib/atts.pl
src/prolog/machine/attributed_variables.rs
src/prolog/machine/system_calls.rs

index 83e144ebda0309dbe8ad855e3aa6924d498d0bce..d05c8559e8abcecf0bfecb86b7859a26f53b6f8d 100644 (file)
@@ -255,6 +255,7 @@ pub enum SystemClauseType {
     SkipMaxList,
     Sleep,
     Succeed,
+    TermAttributedVariables,
     TermVariables,
     TruncateLiftedHeapTo,
     UnifyWithOccursCheck,
@@ -410,6 +411,7 @@ impl SystemClauseType {
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
             &SystemClauseType::Sleep => clause_name!("$sleep"),
             &SystemClauseType::Succeed => clause_name!("$succeed"),
+            &SystemClauseType::TermAttributedVariables => clause_name!("$term_attributed_variables"),
             &SystemClauseType::TermVariables => clause_name!("$term_variables"),
             &SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
             &SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
@@ -538,6 +540,7 @@ impl SystemClauseType {
             ("$sleep", 1) => Some(SystemClauseType::Sleep),
             ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
             ("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
+            ("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
             ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
             ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
             ("$unwind_environments", 0) => Some(SystemClauseType::UnwindEnvironments),
index c30918fb04c15628bd702f7b177b386a139e427e..de398ccbcc04478dcd22a2c1f153f2d92a74bfe6 100644 (file)
@@ -254,6 +254,14 @@ impl<'a> Deref for HCAcyclicIterator<'a> {
     }
 }
 
+impl<'b, 'a: 'b> MutStackHCIterator<'b> for HCAcyclicIterator<'a> {
+    type MutStack = &'b mut Vec<Addr>;
+
+    fn stack(&'b mut self) -> Self::MutStack {
+        self.iter.stack()
+    }
+}
+
 impl<'a> Iterator for HCAcyclicIterator<'a>
 {
     type Item = Addr;
index 7160ab24377ee4e8311aaf6787d4255a3e62ccba..fbf440d038c44a0a9017715a07e258ac370b6530 100644 (file)
@@ -1,9 +1,10 @@
 :- module(atts, [op(1199, fx, attribute), call_residue_vars/2,
-                '$absent_attr'/2, '$copy_attr_list'/2, '$get_attr'/2,
-                '$put_attr'/2, '$absent_from_list'/2,
-                '$get_from_list'/3, '$add_to_list'/3, '$del_attr'/3,
-                '$del_attr_step'/3, '$del_attr_buried'/4,
-                '$default_attr_list'/4]).
+                 term_attributed_variables/2,
+                        '$absent_attr'/2, '$copy_attr_list'/2, '$get_attr'/2,
+                        '$put_attr'/2, '$absent_from_list'/2,
+                        '$get_from_list'/3, '$add_to_list'/3, '$del_attr'/3,
+                        '$del_attr_step'/3, '$del_attr_buried'/4,
+                        '$default_attr_list'/4]).
 
 :- use_module(library(dcgs)).
 :- use_module(library(terms)).
@@ -159,3 +160,6 @@ call_residue_vars(Goal, Vars) :-
     '$get_attr_var_queue_delim'(B),
     call(Goal),
     '$get_attr_var_queue_beyond'(B, Vars).
+
+term_attributed_variables(Term, Vars) :-
+    '$term_attributed_variables'(Term, Vars).
index d853a5f83b72beec91cece6fb1ce70999967d8aa..6595ba538ed56222152976f476af7aa6ee65dc86 100644 (file)
@@ -1,5 +1,8 @@
+use crate::prolog::heap_iter::*;
 use crate::prolog::machine::*;
 
+use indexmap::IndexSet;
+
 use std::cmp::Ordering;
 use std::vec::IntoIter;
 
@@ -137,4 +140,30 @@ impl MachineState {
         self.b0 = self.b;
         self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
     }
+
+    pub(super)
+    fn attr_vars_of_term(&self, addr: Addr) -> IndexSet<Addr> {
+        let mut seen_vars = IndexSet::new();
+        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() {
+                seen_vars.insert(addr);
+
+                let mut l = h + 1;
+                let mut list_elements = vec![];
+
+                while let Addr::Lis(elem) = self.store(self.deref(Addr::HeapCell(l))) {
+                    list_elements.push(self.heap[elem].as_addr(elem));
+                    l = elem + 1;
+                }
+
+                for element in list_elements.into_iter().rev() {
+                    iter.stack().push(element);
+                }
+            }
+        }
+
+        seen_vars
+    }
 }
index a976423ffeb7edfdbee70e5d976f8605682c295b..549ee50de5750944d6de655aaa613952608313a7 100644 (file)
@@ -4,11 +4,11 @@ use prolog_parser::tabled_rc::*;
 
 use crate::prolog::clause_types::*;
 use crate::prolog::forms::*;
+use crate::prolog::heap_print::*;
 use crate::prolog::instructions::*;
 use crate::prolog::machine::code_repo::CodeRepo;
 use crate::prolog::machine::copier::*;
 use crate::prolog::machine::code_walker::*;
-use crate::prolog::heap_print::*;
 use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::machine_state::*;
@@ -3368,6 +3368,12 @@ impl MachineState {
             }
             &SystemClauseType::Succeed => {
             }
+            &SystemClauseType::TermAttributedVariables => {
+                let seen_vars = self.attr_vars_of_term(self[temp_v!(1)]);
+                let outcome = Addr::HeapCell(self.heap.to_list(seen_vars.into_iter()));
+
+                self.unify(self[temp_v!(2)], outcome);
+            }
             &SystemClauseType::TermVariables => {
                 let a1 = self[temp_v!(1)];
                 let mut seen_vars = IndexSet::new();