add term_attributed_variables/2 (#422)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user