add term_attributed_variables/2 (#422)
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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