mark variables in ArithmeticEvaluator (#690)

This commit is contained in:
Mark Thom
2022-03-05 15:27:36 -07:00
parent de35baadf3
commit 0c19c56909
5 changed files with 161 additions and 152 deletions

View File

@@ -5,48 +5,52 @@ use crate::fixtures::*;
use crate::forms::*; use crate::forms::*;
use crate::instructions::*; use crate::instructions::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::targets::*;
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
pub(crate) trait Allocator<'a> { pub(crate) trait Allocator {
fn new() -> Self; fn new() -> Self;
fn mark_anon_var<Target>(&mut self, _: Level, _: GenContext, _: &mut Code) fn mark_anon_var<'a, Target: CompilationTarget<'a>>(
where
Target: crate::targets::CompilationTarget<'a>;
fn mark_non_var<Target>(
&mut self, &mut self,
_: Level, lvl: Level,
_: GenContext, context: GenContext,
_: &'a Cell<RegType>, code: &mut Code,
_: &mut Code, );
) where
Target: crate::targets::CompilationTarget<'a>; fn mark_non_var<'a, Target: CompilationTarget<'a>>(
fn mark_reserved_var<Target>(
&mut self, &mut self,
_: Rc<String>, lvl: Level,
_: Level, context: GenContext,
_: &'a Cell<VarReg>, cell: &'a Cell<RegType>,
_: GenContext, code: &mut Code,
_: &mut Code, );
_: RegType,
_: bool, fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
) where
Target: crate::targets::CompilationTarget<'a>;
fn mark_var<Target>(
&mut self, &mut self,
_: Rc<String>, var_name: Rc<String>,
_: Level, lvl: Level,
_: &'a Cell<VarReg>, cell: &'a Cell<VarReg>,
_: GenContext, term_loc: GenContext,
_: &mut Code, code: &mut Code,
) where r: RegType,
Target: crate::targets::CompilationTarget<'a>; is_new_var: bool,
);
fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self,
var_name: Rc<String>,
lvl: Level,
cell: &'a Cell<VarReg>,
context: GenContext,
code: &mut Code,
);
fn reset(&mut self); fn reset(&mut self);
fn reset_contents(&mut self) {} fn reset_contents(&mut self) {}
fn reset_arg(&mut self, _: usize); fn reset_arg(&mut self, arg_num: usize);
fn reset_at_head(&mut self, args: &Vec<Term>); fn reset_at_head(&mut self, args: &Vec<Term>);
fn advance_arg(&mut self); fn advance_arg(&mut self);
@@ -56,7 +60,7 @@ pub(crate) trait Allocator<'a> {
fn take_bindings(self) -> AllocVarDict; fn take_bindings(self) -> AllocVarDict;
fn drain_var_data( fn drain_var_data<'a>(
&mut self, &mut self,
vs: VariableFixtures<'a>, vs: VariableFixtures<'a>,
num_of_chunks: usize, num_of_chunks: usize,

View File

@@ -1,3 +1,4 @@
use crate::allocator::*;
use crate::arena::*; use crate::arena::*;
use crate::atom_table::*; use crate::atom_table::*;
use crate::fixtures::*; use crate::fixtures::*;
@@ -96,7 +97,7 @@ impl<'a> ArithInstructionIterator<'a> {
pub(crate) enum ArithTermRef<'a> { pub(crate) enum ArithTermRef<'a> {
Literal(&'a Literal), Literal(&'a Literal),
Op(Atom, usize), // name, arity. Op(Atom, usize), // name, arity.
Var(&'a Cell<VarReg>, Rc<String>), Var(Level, &'a Cell<VarReg>, Rc<String>),
} }
impl<'a> Iterator for ArithInstructionIterator<'a> { impl<'a> Iterator for ArithInstructionIterator<'a> {
@@ -124,8 +125,11 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
} }
} }
TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))), TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))),
TermIterState::Var(_, cell, var) => { TermIterState::Var(lvl, cell, var) => {
return Some(Ok(ArithTermRef::Var(cell, var.clone()))); // the expression is the second argument of an
// is/2 but the iterator can't see that, so the
// level needs to be demoted manually.
return Some(Ok(ArithTermRef::Var(lvl.child_level(), cell, var.clone())));
} }
_ => { _ => {
return Some(Err(ArithmeticError::NonEvaluableFunctor( return Some(Err(ArithmeticError::NonEvaluableFunctor(
@@ -141,8 +145,8 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct ArithmeticEvaluator<'a> { pub(crate) struct ArithmeticEvaluator<'a, TermMarker> {
bindings: &'a AllocVarDict, marker: &'a mut TermMarker,
interm: Vec<ArithmeticTerm>, interm: Vec<ArithmeticTerm>,
interm_c: usize, interm_c: usize,
} }
@@ -182,10 +186,10 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
Ok(()) Ok(())
} }
impl<'a> ArithmeticEvaluator<'a> { impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
pub(crate) fn new(bindings: &'a AllocVarDict, target_int: usize) -> Self { pub(crate) fn new(marker: &'a mut TermMarker, target_int: usize) -> Self {
ArithmeticEvaluator { ArithmeticEvaluator {
bindings, marker,
interm: Vec::new(), interm: Vec::new(),
interm_c: target_int, interm_c: target_int,
} }
@@ -311,20 +315,46 @@ impl<'a> ArithmeticEvaluator<'a> {
} }
} }
pub(crate) fn eval(&mut self, src: &'a Term) -> Result<ArithCont, ArithmeticError> { pub(crate) fn eval(
&mut self,
src: &'a Term,
term_loc: GenContext,
) -> Result<ArithCont, ArithmeticError>
{
let mut code = vec![]; let mut code = vec![];
let mut iter = src.iter()?; let mut iter = src.iter()?;
while let Some(term_ref) = iter.next() { while let Some(term_ref) = iter.next() {
match term_ref? { match term_ref? {
ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?, ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?,
ArithTermRef::Var(cell, name) => { ArithTermRef::Var(lvl, cell, name) => {
let r = if cell.get().norm().reg_num() == 0 { let r = if cell.get().norm().reg_num() == 0 {
match self.bindings.get(&name) { let mut getter = || {
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t), use crate::targets::QueryInstruction;
Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p),
_ => return Err(ArithmeticError::UninstantiatedVar), loop {
} match self.marker.bindings().get(&name) {
Some(&VarData::Temp(_, t, _)) if t != 0 =>
return RegType::Temp(t),
Some(&VarData::Perm(p)) if p != 0 =>
return RegType::Perm(p),
_ => {
self.marker.mark_var::<QueryInstruction>(
name.clone(),
lvl,
cell,
term_loc,
&mut code,
);
}
}
}
};
getter()
/*
_ => return Err(ArithmeticError::UninstantiatedVar),
*/
} else { } else {
cell.get().norm() cell.get().norm()
}; };

View File

@@ -208,7 +208,7 @@ pub(crate) struct CodeGenerator<'a, TermMarker> {
global_jmp_by_locs_offset: usize, global_jmp_by_locs_offset: usize,
} }
impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> { impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self { pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
CodeGenerator { CodeGenerator {
atom_tbl, atom_tbl,
@@ -221,7 +221,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
} }
fn update_var_count<Iter: Iterator<Item = TermRef<'a>>>(&mut self, iter: Iter) { fn update_var_count<'a, Iter: Iterator<Item = TermRef<'a>>>(&mut self, iter: Iter) {
for term in iter { for term in iter {
if let TermRef::Var(_, _, var) = term { if let TermRef::Var(_, _, var) = term {
let entry = self.var_count.entry(var).or_insert(0); let entry = self.var_count.entry(var).or_insert(0);
@@ -230,7 +230,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
} }
fn get_var_count(&self, var: &'a String) -> usize { fn get_var_count(&self, var: &String) -> usize {
*self.var_count.get(var).unwrap() *self.var_count.get(var).unwrap()
} }
@@ -238,7 +238,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
&mut self, &mut self,
name: Rc<String>, name: Rc<String>,
term_loc: GenContext, term_loc: GenContext,
vr: &'a Cell<VarReg>, vr: &Cell<VarReg>,
code: &mut Code, code: &mut Code,
) -> RegType { ) -> RegType {
let mut target = Code::new(); let mut target = Code::new();
@@ -256,7 +256,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
name: Rc<String>, name: Rc<String>,
arg: usize, arg: usize,
term_loc: GenContext, term_loc: GenContext,
vr: &'a Cell<VarReg>, vr: &Cell<VarReg>,
code: &mut Code, code: &mut Code,
) -> RegType { ) -> RegType {
match self.marker.bindings().get(&name) { match self.marker.bindings().get(&name) {
@@ -273,7 +273,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
} }
fn add_or_increment_void_instr<Target>(target: &mut Code) fn add_or_increment_void_instr<'a, Target>(target: &mut Code)
where where
Target: crate::targets::CompilationTarget<'a>, Target: crate::targets::CompilationTarget<'a>,
{ {
@@ -287,10 +287,10 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
target.push(Target::to_void(1)); target.push(Target::to_void(1));
} }
fn deep_var_instr<Target: crate::targets::CompilationTarget<'a>>( fn deep_var_instr<'a, Target: crate::targets::CompilationTarget<'a>>(
&mut self, &mut self,
cell: &'a Cell<VarReg>, cell: &'a Cell<VarReg>,
var: &'a Rc<String>, var: &Rc<String>,
term_loc: GenContext, term_loc: GenContext,
is_exposed: bool, is_exposed: bool,
target: &mut Code, target: &mut Code,
@@ -302,7 +302,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
} }
fn subterm_to_instr<Target: crate::targets::CompilationTarget<'a>>( fn subterm_to_instr<'a, Target: crate::targets::CompilationTarget<'a>>(
&mut self, &mut self,
subterm: &'a Term, subterm: &'a Term,
term_loc: GenContext, term_loc: GenContext,
@@ -331,7 +331,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
}; };
} }
fn compile_target<Target, Iter>( fn compile_target<'a, Target, Iter>(
&mut self, &mut self,
iter: Iter, iter: Iter,
term_loc: GenContext, term_loc: GenContext,
@@ -413,7 +413,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
target target
} }
fn collect_var_data(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> { fn collect_var_data<'a>(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> {
let mut vs = VariableFixtures::new(); let mut vs = VariableFixtures::new();
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() { while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
@@ -490,7 +490,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
dealloc_index dealloc_index
} }
fn compile_inlined( fn compile_inlined<'a>(
&mut self, &mut self,
ct: &InlinedClauseType, ct: &InlinedClauseType,
terms: &'a Vec<Term>, terms: &'a Vec<Term>,
@@ -501,8 +501,8 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
&InlinedClauseType::CompareNumber(mut cmp) => { &InlinedClauseType::CompareNumber(mut cmp) => {
self.marker.reset_arg(2); self.marker.reset_arg(2);
let (mut lcode, at_1) = self.call_arith_eval(&terms[0], 1)?; let (mut lcode, at_1) = self.compile_arith_expr(&terms[0], 1, term_loc)?;
let (mut rcode, at_2) = self.call_arith_eval(&terms[1], 2)?; let (mut rcode, at_2) = self.compile_arith_expr(&terms[1], 2, term_loc)?;
let at_1 = if let &Term::Var(ref vr, ref name) = &terms[0] { let at_1 = if let &Term::Var(ref vr, ref name) = &terms[0] {
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code)) ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code))
@@ -655,74 +655,63 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
Ok(()) Ok(())
} }
fn call_arith_eval( fn compile_arith_expr(
&mut self, &mut self,
term: &'a Term, term: &Term,
target_int: usize, target_int: usize,
term_loc: GenContext,
) -> Result<ArithCont, ArithmeticError> { ) -> Result<ArithCont, ArithmeticError> {
let mut evaluator = ArithmeticEvaluator::new(&self.marker.bindings(), target_int); let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int);
evaluator.eval(term) evaluator.eval(term, term_loc)
} }
fn compile_is_call( fn compile_is_call(
&mut self, &mut self,
terms: &'a Vec<Term>, terms: &Vec<Term>,
code: &mut Code, code: &mut Code,
term_loc: GenContext, term_loc: GenContext,
use_default_call_policy: bool, use_default_call_policy: bool,
) -> Result<(), CompilationError> { ) -> Result<(), CompilationError> {
let (mut acode, at) = self.call_arith_eval(&terms[1], 1)?; macro_rules! compile_expr {
code.append(&mut acode); ($self:expr, $terms:expr, $term_loc:expr, $code:expr) => ({
let (acode, at) = $self.compile_arith_expr(&$terms[1], 1, $term_loc)?;
$code.extend(acode.into_iter());
at
});
}
self.marker.reset_arg(2); self.marker.reset_arg(2);
match &terms[0] { let at = match &terms[0] {
&Term::Var(ref vr, ref name) => { &Term::Var(ref vr, ref name) => {
let mut target = vec![];
self.marker.mark_var::<QueryInstruction>( self.marker.mark_var::<QueryInstruction>(
name.clone(), name.clone(),
Level::Shallow, Level::Shallow,
vr, vr,
term_loc, term_loc,
&mut target, code,
); );
if !target.is_empty() { compile_expr!(self, terms, term_loc, code)
code.extend(target.into_iter());
}
} }
&Term::Literal(_, c @ Literal::Integer(_)) &Term::Literal(_, c @ Literal::Integer(_) |
| &Term::Literal(_, c @ Literal::Fixnum(_)) => { c @ Literal::Float(_) |
let v = HeapCellValue::from(c); c @ Literal::Rational(_) |
code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1))); c @ Literal::Fixnum(_)) => {
self.marker.advance_arg();
}
&Term::Literal(_, c @ Literal::Float(_)) => {
let v = HeapCellValue::from(c);
code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1)));
self.marker.advance_arg();
}
&Term::Literal(_, c @ Literal::Rational(_)) => {
let v = HeapCellValue::from(c); let v = HeapCellValue::from(c);
code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1))); code.push(instr!("put_constant", Level::Shallow, v, temp_v!(1)));
self.marker.advance_arg(); self.marker.advance_arg();
compile_expr!(self, terms, term_loc, code)
} }
_ => { _ => {
code.push(instr!("$fail", 0)); code.push(instr!("$fail", 0));
return Ok(()); return Ok(());
} }
}
let at = if let &Term::Var(ref vr, ref name) = &terms[1] {
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
} else {
at.unwrap_or(interm!(1))
}; };
let at = at.unwrap_or(interm!(1));
Ok(if use_default_call_policy { Ok(if use_default_call_policy {
code.push(instr!("is", default, temp_v!(1), at, 0)); code.push(instr!("is", default, temp_v!(1), at, 0));
} else { } else {
@@ -731,7 +720,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
#[inline] #[inline]
fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &'a Cell<VarReg>) { fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &Cell<VarReg>) {
let r = self.marker.get(Rc::new(String::from("!"))); let r = self.marker.get(Rc::new(String::from("!")));
cell.set(VarReg::Norm(r)); cell.set(VarReg::Norm(r));
code.push(instr!("$set_cp", cell.get().norm(), 0)); code.push(instr!("$set_cp", cell.get().norm(), 0));
@@ -740,7 +729,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
fn compile_get_level_and_unify( fn compile_get_level_and_unify(
&mut self, &mut self,
code: &mut Code, code: &mut Code,
cell: &'a Cell<VarReg>, cell: &Cell<VarReg>,
var: Rc<String>, var: Rc<String>,
term_loc: GenContext, term_loc: GenContext,
) { ) {
@@ -756,7 +745,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
code.push(instr!("get_level_and_unify", cell.get().norm())); code.push(instr!("get_level_and_unify", cell.get().norm()));
} }
fn compile_seq( fn compile_seq<'a>(
&mut self, &mut self,
iter: ChunkedIterator<'a>, iter: ChunkedIterator<'a>,
conjunct_info: &ConjunctInfo<'a>, conjunct_info: &ConjunctInfo<'a>,
@@ -820,10 +809,10 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
} }
fn compile_cleanup( fn compile_cleanup<'a>(
&mut self, &mut self,
code: &mut Code, code: &mut Code,
conjunct_info: &ConjunctInfo, conjunct_info: &ConjunctInfo<'a>,
toc: &'a QueryTerm, toc: &'a QueryTerm,
) { ) {
// add a proceed to bookend any trailing cuts. // add a proceed to bookend any trailing cuts.
@@ -850,10 +839,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
} }
} }
pub(crate) fn compile_rule<'c: 'a>( pub(crate) fn compile_rule(&mut self, rule: &Rule) -> Result<Code, CompilationError> {
&mut self,
rule: &'c Rule,
) -> Result<Code, CompilationError> {
let iter = ChunkedIterator::from_rule(rule); let iter = ChunkedIterator::from_rule(rule);
let conjunct_info = self.collect_var_data(iter); let conjunct_info = self.collect_var_data(iter);
@@ -907,7 +893,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
UnsafeVarMarker::from_safe_vars(safe_vars) UnsafeVarMarker::from_safe_vars(safe_vars)
} }
pub(crate) fn compile_fact<'c: 'a>(&mut self, term: &'c Term) -> Code { pub(crate) fn compile_fact(&mut self, term: &Term) -> Code {
self.update_var_count(post_order_iter(term)); self.update_var_count(post_order_iter(term));
let mut vs = VariableFixtures::new(); let mut vs = VariableFixtures::new();
@@ -942,7 +928,7 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
fn compile_query_line( fn compile_query_line(
&mut self, &mut self,
term: &'a QueryTerm, term: &QueryTerm,
term_loc: GenContext, term_loc: GenContext,
code: &mut Code, code: &mut Code,
num_perm_vars_left: usize, num_perm_vars_left: usize,
@@ -1029,9 +1015,9 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
subseqs subseqs
} }
fn compile_pred_subseq<'c: 'a, I: Indexer>( fn compile_pred_subseq<I: Indexer>(
&mut self, &mut self,
clauses: &'c [PredicateClause], clauses: &[PredicateClause],
optimal_index: usize, optimal_index: usize,
) -> Result<Code, CompilationError> { ) -> Result<Code, CompilationError> {
let mut code = VecDeque::new(); let mut code = VecDeque::new();
@@ -1121,19 +1107,12 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
Ok(Vec::from(code)) Ok(Vec::from(code))
} }
pub(crate) fn compile_predicate<'c: 'a>( pub(crate) fn compile_predicate(
&mut self, &mut self,
clauses: &'c Vec<PredicateClause>, clauses: &Vec<PredicateClause>,
) -> Result<Code, CompilationError> { ) -> Result<Code, CompilationError> {
let mut code = Code::new(); let mut code = Code::new();
/*
let optimal_index = match Self::first_instantiated_index(&clauses) {
Some(index) => index,
None => 0, // Default to first argument indexing.
};
*/
let split_pred = Self::split_predicate(&clauses); let split_pred = Self::split_predicate(&clauses);
let multi_seq = split_pred.len() > 1; let multi_seq = split_pred.len() > 1;

View File

@@ -126,10 +126,11 @@ impl DebrayAllocator {
} }
} }
fn evacuate_arg<'a, Target>(&mut self, chunk_num: usize, target: &mut Vec<Instruction>) fn evacuate_arg<'a, Target: CompilationTarget<'a>>(
where &mut self,
Target: CompilationTarget<'a>, chunk_num: usize,
{ code: &mut Code,
) {
match self.alloc_in_last_goal_hint(chunk_num) { match self.alloc_in_last_goal_hint(chunk_num) {
Some((var, r)) => { Some((var, r)) => {
let k = self.arg_c; let k = self.arg_c;
@@ -137,7 +138,7 @@ impl DebrayAllocator {
if r != k { if r != k {
let r = RegType::Temp(r); let r = RegType::Temp(r);
target.push(Target::move_to_register(r, k)); code.push(Target::move_to_register(r, k));
self.contents.swap_remove(&k); self.contents.swap_remove(&k);
self.contents.insert(r.reg_num(), var.clone()); self.contents.insert(r.reg_num(), var.clone());
@@ -207,7 +208,7 @@ impl DebrayAllocator {
} }
} }
impl<'a> Allocator<'a> for DebrayAllocator { impl Allocator for DebrayAllocator {
fn new() -> DebrayAllocator { fn new() -> DebrayAllocator {
DebrayAllocator { DebrayAllocator {
arity: 0, arity: 0,
@@ -219,42 +220,37 @@ impl<'a> Allocator<'a> for DebrayAllocator {
} }
} }
fn mark_anon_var<Target>( fn mark_anon_var<'a, Target: CompilationTarget<'a>>(
&mut self, &mut self,
lvl: Level, lvl: Level,
term_loc: GenContext, term_loc: GenContext,
target: &mut Vec<Instruction>, code: &mut Code,
) ) {
where
Target: CompilationTarget<'a>,
{
let r = RegType::Temp(self.alloc_reg_to_non_var()); let r = RegType::Temp(self.alloc_reg_to_non_var());
match lvl { match lvl {
Level::Deep => target.push(Target::subterm_to_variable(r)), Level::Deep => code.push(Target::subterm_to_variable(r)),
Level::Root | Level::Shallow => { Level::Root | Level::Shallow => {
let k = self.arg_c; let k = self.arg_c;
if let GenContext::Last(chunk_num) = term_loc { if let GenContext::Last(chunk_num) = term_loc {
self.evacuate_arg::<Target>(chunk_num, target); self.evacuate_arg::<Target>(chunk_num, code);
} }
self.arg_c += 1; self.arg_c += 1;
target.push(Target::argument_to_variable(r, k)); code.push(Target::argument_to_variable(r, k));
} }
}; };
} }
fn mark_non_var<Target>( fn mark_non_var<'a, Target: CompilationTarget<'a>>(
&mut self, &mut self,
lvl: Level, lvl: Level,
term_loc: GenContext, term_loc: GenContext,
cell: &Cell<RegType>, cell: &'a Cell<RegType>,
target: &mut Vec<Instruction>, code: &mut Code,
) where ) {
Target: CompilationTarget<'a>,
{
let r = cell.get(); let r = cell.get();
let r = match lvl { let r = match lvl {
@@ -262,7 +258,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
let k = self.arg_c; let k = self.arg_c;
if let GenContext::Last(chunk_num) = term_loc { if let GenContext::Last(chunk_num) = term_loc {
self.evacuate_arg::<Target>(chunk_num, target); self.evacuate_arg::<Target>(chunk_num, code);
} }
self.arg_c += 1; self.arg_c += 1;
@@ -278,18 +274,18 @@ impl<'a> Allocator<'a> for DebrayAllocator {
cell.set(r); cell.set(r);
} }
fn mark_var<Target: CompilationTarget<'a>>( fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self, &mut self,
var: Rc<String>, var: Rc<String>,
lvl: Level, lvl: Level,
cell: &'a Cell<VarReg>, cell: &'a Cell<VarReg>,
term_loc: GenContext, term_loc: GenContext,
target: &mut Vec<Instruction>, code: &mut Code,
) { ) {
let (r, is_new_var) = match self.get(var.clone()) { let (r, is_new_var) = match self.get(var.clone()) {
RegType::Temp(0) => { RegType::Temp(0) => {
// here, r is temporary *and* unassigned. // here, r is temporary *and* unassigned.
let o = self.alloc_reg_to_var::<Target>(&var, lvl, term_loc, target); let o = self.alloc_reg_to_var::<Target>(&var, lvl, term_loc, code);
cell.set(VarReg::Norm(RegType::Temp(o))); cell.set(VarReg::Norm(RegType::Temp(o)));
(RegType::Temp(o), true) (RegType::Temp(o), true)
@@ -303,16 +299,16 @@ impl<'a> Allocator<'a> for DebrayAllocator {
r => (r, false), r => (r, false),
}; };
self.mark_reserved_var::<Target>(var, lvl, cell, term_loc, target, r, is_new_var); self.mark_reserved_var::<Target>(var, lvl, cell, term_loc, code, r, is_new_var);
} }
fn mark_reserved_var<Target: CompilationTarget<'a>>( fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
&mut self, &mut self,
var: Rc<String>, var: Rc<String>,
lvl: Level, lvl: Level,
cell: &'a Cell<VarReg>, cell: &'a Cell<VarReg>,
term_loc: GenContext, term_loc: GenContext,
target: &mut Vec<Instruction>, code: &mut Code,
r: RegType, r: RegType,
is_new_var: bool, is_new_var: bool,
) { ) {
@@ -321,7 +317,7 @@ impl<'a> Allocator<'a> for DebrayAllocator {
let k = self.arg_c; let k = self.arg_c;
if self.is_curr_arg_distinct_from(&var) { if self.is_curr_arg_distinct_from(&var) {
self.evacuate_arg::<Target>(term_loc.chunk_num(), target); self.evacuate_arg::<Target>(term_loc.chunk_num(), code);
} }
self.arg_c += 1; self.arg_c += 1;
@@ -330,24 +326,24 @@ impl<'a> Allocator<'a> for DebrayAllocator {
if !self.in_place(&var, term_loc, r, k) { if !self.in_place(&var, term_loc, r, k) {
if is_new_var { if is_new_var {
target.push(Target::argument_to_variable(r, k)); code.push(Target::argument_to_variable(r, k));
} else { } else {
target.push(Target::argument_to_value(r, k)); code.push(Target::argument_to_value(r, k));
} }
} }
} }
Level::Deep if is_new_var => { Level::Deep if is_new_var => {
if let GenContext::Head = term_loc { if let GenContext::Head = term_loc {
if self.occurs_shallowly_in_head(&var, r.reg_num()) { if self.occurs_shallowly_in_head(&var, r.reg_num()) {
target.push(Target::subterm_to_value(r)); code.push(Target::subterm_to_value(r));
} else { } else {
target.push(Target::subterm_to_variable(r)); code.push(Target::subterm_to_variable(r));
} }
} else { } else {
target.push(Target::subterm_to_variable(r)); code.push(Target::subterm_to_variable(r));
} }
} }
Level::Deep => target.push(Target::subterm_to_value(r)), Level::Deep => code.push(Target::subterm_to_value(r)),
}; };
if !r.is_perm() { if !r.is_perm() {

View File

@@ -229,7 +229,7 @@ staggered_sc(G, _) :- call('$call'(G)).
staggered_sc(_, G) :- call('$call'(G)). staggered_sc(_, G) :- call('$call'(G)).
! :- !. !.
:- non_counted_backtracking set_cp/1. :- non_counted_backtracking set_cp/1.