add term_attributed_variables/2 (#422)
This commit is contained in:
@@ -255,6 +255,7 @@ pub enum SystemClauseType {
|
|||||||
SkipMaxList,
|
SkipMaxList,
|
||||||
Sleep,
|
Sleep,
|
||||||
Succeed,
|
Succeed,
|
||||||
|
TermAttributedVariables,
|
||||||
TermVariables,
|
TermVariables,
|
||||||
TruncateLiftedHeapTo,
|
TruncateLiftedHeapTo,
|
||||||
UnifyWithOccursCheck,
|
UnifyWithOccursCheck,
|
||||||
@@ -410,6 +411,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
|
&SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
|
||||||
&SystemClauseType::Sleep => clause_name!("$sleep"),
|
&SystemClauseType::Sleep => clause_name!("$sleep"),
|
||||||
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
&SystemClauseType::Succeed => clause_name!("$succeed"),
|
||||||
|
&SystemClauseType::TermAttributedVariables => clause_name!("$term_attributed_variables"),
|
||||||
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
&SystemClauseType::TermVariables => clause_name!("$term_variables"),
|
||||||
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
&SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"),
|
||||||
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
&SystemClauseType::UnifyWithOccursCheck => clause_name!("$unify_with_occurs_check"),
|
||||||
@@ -538,6 +540,7 @@ impl SystemClauseType {
|
|||||||
("$sleep", 1) => Some(SystemClauseType::Sleep),
|
("$sleep", 1) => Some(SystemClauseType::Sleep),
|
||||||
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
||||||
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
|
("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
|
||||||
|
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
||||||
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||||
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
|
||||||
("$unwind_environments", 0) => Some(SystemClauseType::UnwindEnvironments),
|
("$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>
|
impl<'a> Iterator for HCAcyclicIterator<'a>
|
||||||
{
|
{
|
||||||
type Item = Addr;
|
type Item = Addr;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
:- module(atts, [op(1199, fx, attribute), call_residue_vars/2,
|
:- module(atts, [op(1199, fx, attribute), call_residue_vars/2,
|
||||||
'$absent_attr'/2, '$copy_attr_list'/2, '$get_attr'/2,
|
term_attributed_variables/2,
|
||||||
'$put_attr'/2, '$absent_from_list'/2,
|
'$absent_attr'/2, '$copy_attr_list'/2, '$get_attr'/2,
|
||||||
'$get_from_list'/3, '$add_to_list'/3, '$del_attr'/3,
|
'$put_attr'/2, '$absent_from_list'/2,
|
||||||
'$del_attr_step'/3, '$del_attr_buried'/4,
|
'$get_from_list'/3, '$add_to_list'/3, '$del_attr'/3,
|
||||||
'$default_attr_list'/4]).
|
'$del_attr_step'/3, '$del_attr_buried'/4,
|
||||||
|
'$default_attr_list'/4]).
|
||||||
|
|
||||||
:- use_module(library(dcgs)).
|
:- use_module(library(dcgs)).
|
||||||
:- use_module(library(terms)).
|
:- use_module(library(terms)).
|
||||||
@@ -159,3 +160,6 @@ call_residue_vars(Goal, Vars) :-
|
|||||||
'$get_attr_var_queue_delim'(B),
|
'$get_attr_var_queue_delim'(B),
|
||||||
call(Goal),
|
call(Goal),
|
||||||
'$get_attr_var_queue_beyond'(B, Vars).
|
'$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 crate::prolog::machine::*;
|
||||||
|
|
||||||
|
use indexmap::IndexSet;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::vec::IntoIter;
|
use std::vec::IntoIter;
|
||||||
|
|
||||||
@@ -137,4 +140,30 @@ impl MachineState {
|
|||||||
self.b0 = self.b;
|
self.b0 = self.b;
|
||||||
self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
|
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::clause_types::*;
|
||||||
use crate::prolog::forms::*;
|
use crate::prolog::forms::*;
|
||||||
|
use crate::prolog::heap_print::*;
|
||||||
use crate::prolog::instructions::*;
|
use crate::prolog::instructions::*;
|
||||||
use crate::prolog::machine::code_repo::CodeRepo;
|
use crate::prolog::machine::code_repo::CodeRepo;
|
||||||
use crate::prolog::machine::copier::*;
|
use crate::prolog::machine::copier::*;
|
||||||
use crate::prolog::machine::code_walker::*;
|
use crate::prolog::machine::code_walker::*;
|
||||||
use crate::prolog::heap_print::*;
|
|
||||||
use crate::prolog::machine::machine_errors::*;
|
use crate::prolog::machine::machine_errors::*;
|
||||||
use crate::prolog::machine::machine_indices::*;
|
use crate::prolog::machine::machine_indices::*;
|
||||||
use crate::prolog::machine::machine_state::*;
|
use crate::prolog::machine::machine_state::*;
|
||||||
@@ -3368,6 +3368,12 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
&SystemClauseType::Succeed => {
|
&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 => {
|
&SystemClauseType::TermVariables => {
|
||||||
let a1 = self[temp_v!(1)];
|
let a1 = self[temp_v!(1)];
|
||||||
let mut seen_vars = IndexSet::new();
|
let mut seen_vars = IndexSet::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user