add term_attributed_variables/2 (#422)

This commit is contained in:
Mark Thom
2020-05-02 18:46:29 -06:00
parent 9dabce819a
commit b642bd2cfd
5 changed files with 56 additions and 6 deletions

View 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),

View 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;

View File

@@ -1,4 +1,5 @@
:- module(atts, [op(1199, fx, attribute), call_residue_vars/2,
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,
@@ -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).

View 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
}
}

View 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();