self.has_deep_cut as usize
}
- fn mark_unsafe_vars(&self, mut unsafe_var_marker: UnsafeVarMarker, code: &mut Code) {
+ fn mark_unsafe_vars<Alloc: Allocator<'a>>(
+ &self,
+ mut unsafe_var_marker: UnsafeVarMarker,
+ marker: &Alloc,
+ code: &mut Code
+ ) {
// target the last goal of the rule for handling unsafe variables.
// we use this weird logic to find the last goal.
- let right_index = if let &Line::Control(_) = code.last().unwrap() {
- code.len() - 2
+ let right_index = if let Some(Line::Control(_)) = code.last() {
+ if code.len() >= 2 {
+ code.len() - 2
+ } else {
+ return;
+ }
} else {
- code.len() - 1
+ if code.len() >= 1 {
+ code.len() - 1
+ } else {
+ return;
+ }
};
let mut index = right_index;
if let Line::Query(_) = &code[right_index] {
while let Line::Query(_) = &code[index] {
- // index >= 0.
if index == 0 {
break;
} else {
index += 1;
}
- unsafe_var_marker.record_unsafe_vars(&self.perm_vs);
+ unsafe_var_marker.record_unsafe_vars(&self.perm_vs, marker);
- for line in code.iter_mut() {
- if let &mut Line::Query(ref mut query_instr) = line {
+ for line in code.iter() {
+ if let Line::Query(ref query_instr) = line {
unsafe_var_marker.mark_safe_vars(query_instr);
}
}
fn collect_var_data(&mut self, mut iter: ChunkedIterator<'a>) -> ConjunctInfo<'a> {
let mut vs = VariableFixtures::new();
-
+
while let Some((chunk_num, lt_arity, chunked_terms)) = iter.next() {
for (i, chunked_term) in chunked_terms.iter().enumerate() {
let term_loc = match chunked_term {
- &ChunkedTerm::HeadClause(..) => GenContext::Head,
+ &ChunkedTerm::HeadClause(..) =>
+ GenContext::Head,
&ChunkedTerm::BodyTerm(_) => {
if i < chunked_terms.len() - 1 {
GenContext::Mid(chunk_num)
vs.populate_restricting_sets();
vs.set_perm_vals(has_deep_cut);
- let vs = self.marker.drain_var_data(vs);
-
+ let vs = self.marker.drain_var_data(vs, num_of_chunks);
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
}
let iter = ChunkedIterator::from_rule_body(p1, clauses);
self.compile_seq(iter, &conjunct_info, &mut code, false)?;
- if conjunct_info.allocates() {
- conjunct_info.mark_unsafe_vars(unsafe_var_marker, &mut code);
- }
+ conjunct_info.mark_unsafe_vars(unsafe_var_marker, &self.marker, &mut code);
Self::compile_cleanup(&mut code, &conjunct_info, clauses.last().unwrap_or(p1));
Ok(code)
vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head);
vs.populate_restricting_sets();
- self.marker.drain_var_data(vs);
+ self.marker.drain_var_data(vs, 1);
let mut code = Vec::new();
let iter = ChunkedIterator::from_term_sequence(query);
self.compile_seq(iter, &conjunct_info, &mut code, true)?;
- if conjunct_info.allocates() {
- conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &mut code);
- }
+ conjunct_info.mark_unsafe_vars(UnsafeVarMarker::new(), &self.marker, &mut code);
if let Some(query_term) = query.last() {
Self::compile_cleanup(&mut code, &conjunct_info, query_term);
use prolog_parser::ast::*;
+use crate::prolog::allocator::*;
use crate::prolog::forms::*;
use crate::prolog::instructions::*;
use crate::prolog::iterators::*;
-use indexmap::IndexMap;
+use indexmap::{IndexMap, IndexSet};
use std::cell::Cell;
-use std::collections::btree_map::{IntoIter, IterMut, Values};
-use std::collections::{BTreeMap, BTreeSet};
+use std::collections::BTreeSet;
use std::mem::swap;
use std::rc::Rc;
use std::vec::Vec;
}
type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
-pub struct VariableFixtures<'a>(BTreeMap<Rc<Var>, VariableFixture<'a>>);
+
+pub struct VariableFixtures<'a>{
+ perm_vars: IndexMap<Rc<Var>, VariableFixture<'a>>,
+ last_chunk_temp_vars: IndexSet<Rc<Var>>
+}
impl<'a> VariableFixtures<'a> {
pub fn new() -> Self {
- VariableFixtures(BTreeMap::new())
+ VariableFixtures {
+ perm_vars: IndexMap::new(),
+ last_chunk_temp_vars: IndexSet::new()
+ }
+
}
pub fn insert(&mut self, var: Rc<Var>, vs: VariableFixture<'a>) {
- self.0.insert(var, vs);
+ self.perm_vars.insert(var, vs);
+ }
+
+ pub fn insert_last_chunk_temp_var(&mut self, var: Rc<Var>) {
+ self.last_chunk_temp_vars.insert(var);
}
// computes no_use and conflict sets for all temp vars.
}
fn get_mut(&mut self, u: Rc<Var>) -> Option<&mut VariableFixture<'a>> {
- self.0.get_mut(&u)
+ self.perm_vars.get_mut(&u)
}
- fn iter_mut(&mut self) -> IterMut<Rc<Var>, VariableFixture<'a>> {
- self.0.iter_mut()
+ fn iter_mut(&mut self) -> indexmap::map::IterMut<Rc<Var>, VariableFixture<'a>> {
+ self.perm_vars.iter_mut()
}
fn record_temp_info(&mut self, tvd: &mut TempVarData, arg_c: usize, term_loc: GenContext) {
for term_ref in iter {
if let &TermRef::Var(lvl, cell, ref var) = &term_ref {
- let mut status = self.0.remove(var).unwrap_or((
+ let mut status = self.perm_vars.remove(var).unwrap_or((
VarStatus::Temp(chunk_num, TempVarData::new(lt_arity)),
Vec::new(),
));
_ => status.0 = VarStatus::Perm(chunk_num),
};
- self.0.insert(var.clone(), status);
+ self.perm_vars.insert(var.clone(), status);
}
if let Level::Shallow = term_ref.level() {
}
}
- pub fn into_iter(self) -> IntoIter<Rc<Var>, VariableFixture<'a>> {
- self.0.into_iter()
+ pub fn into_iter(self) -> indexmap::map::IntoIter<Rc<Var>, VariableFixture<'a>> {
+ self.perm_vars.into_iter()
}
- fn values(&self) -> Values<Rc<Var>, VariableFixture<'a>> {
- self.0.values()
+ fn values(&self) -> indexmap::map::Values<Rc<Var>, VariableFixture<'a>> {
+ self.perm_vars.values()
}
pub fn size(&self) -> usize {
- self.0.len()
+ self.perm_vars.len()
}
pub fn set_perm_vals(&self, has_deep_cuts: bool) {
}
}
- pub fn record_unsafe_vars(&mut self, fixtures: &VariableFixtures) {
- for &(_, ref cb) in fixtures.values() {
+ pub fn record_unsafe_vars<'a, Alloc: Allocator<'a>>(
+ &mut self,
+ fixtures: &VariableFixtures,
+ marker: &Alloc
+ ) {
+ for &(_, ref cb) in fixtures.values() {
if let Some(index) = cb.first() {
if !self.unsafe_vars.contains_key(&index.get().norm()) {
self.unsafe_vars.insert(index.get().norm(), false);
}
}
}
+
+ for var in fixtures.last_chunk_temp_vars.iter().cloned() {
+ let r = marker.get(var);
+ self.unsafe_vars.insert(r, false);
+ }
}
- pub fn mark_safe_vars(&mut self, query_instr: &mut QueryInstruction) {
+ pub fn mark_safe_vars(&mut self, query_instr: &QueryInstruction) {
match query_instr {
- &mut QueryInstruction::PutVariable(RegType::Temp(r), _) => {
- if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(r)) {
+ QueryInstruction::PutVariable(RegType::Temp(r), _) => {
+ if let Some(found) = self.unsafe_vars.get_mut(&RegType::Temp(*r)) {
*found = true;
}
}
- &mut QueryInstruction::SetVariable(reg) => {
- if let Some(found) = self.unsafe_vars.get_mut(®) {
+ QueryInstruction::SetVariable(reg) => {
+ if let Some(found) = self.unsafe_vars.get_mut(reg) {
*found = true;
}
}