SkipMaxList,
Sleep,
Succeed,
+ TermAttributedVariables,
TermVariables,
TruncateLiftedHeapTo,
UnifyWithOccursCheck,
&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"),
("$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),
}
}
+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;
:- 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)).
'$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).
+use crate::prolog::heap_iter::*;
use crate::prolog::machine::*;
+use indexmap::IndexSet;
+
use std::cmp::Ordering;
use std::vec::IntoIter;
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
+ }
}
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::*;
}
&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();