new TermIterState variants

This commit is contained in:
Mark Thom
2022-12-05 20:49:23 -07:00
committed by Mark
parent a66d666bed
commit 063cf0c608
9 changed files with 141 additions and 148 deletions

View File

@@ -456,6 +456,7 @@ impl<'b> CodeGenerator<'b> {
target target
} }
/*
fn collect_var_data<'a>(&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();
@@ -486,6 +487,7 @@ impl<'b> CodeGenerator<'b> {
let vs = self.marker.drain_var_data(vs, num_of_chunks); let vs = self.marker.drain_var_data(vs, num_of_chunks);
ConjunctInfo::new(vs, num_of_chunks, has_deep_cut) ConjunctInfo::new(vs, num_of_chunks, has_deep_cut)
} }
*/
fn add_conditional_call(&mut self, code: &mut Code, qt: &QueryTerm, pvs: usize) { fn add_conditional_call(&mut self, code: &mut Code, qt: &QueryTerm, pvs: usize) {
match qt { match qt {
@@ -912,7 +914,8 @@ impl<'b> CodeGenerator<'b> {
Ok(()) Ok(())
} }
fn compile_seq_prelude(&mut self, conjunct_info: &ConjunctInfo, body: &mut Code) { fn compile_seq_prelude(&mut self, var_data: &VarData, body: &mut Code) {
/*
if conjunct_info.allocates() { if conjunct_info.allocates() {
let perm_vars = conjunct_info.perm_vars(); let perm_vars = conjunct_info.perm_vars();
@@ -922,6 +925,7 @@ impl<'b> CodeGenerator<'b> {
body.push(Instruction::GetLevel(perm_v!(1))); body.push(Instruction::GetLevel(perm_v!(1)));
} }
} }
*/
} }
fn compile_cleanup( fn compile_cleanup(
@@ -955,18 +959,19 @@ impl<'b> CodeGenerator<'b> {
} }
pub(crate) fn compile_rule(&mut self, rule: &Rule) -> Result<Code, CompilationError> { pub(crate) fn compile_rule(&mut self, rule: &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);
let &Rule { let &Rule {
head: (_, ref args, ref p1), head: (_, ref args, ref p1),
ref clauses, ref clauses,
ref var_data,
} = rule; } = rule;
let mut code = Code::new(); let mut code = Code::new();
self.marker.reset_at_head(args); self.marker.reset_at_head(args);
self.compile_seq_prelude(&conjunct_info, &mut code); self.compile_seq_prelude(&var_data, &mut code);
let iter = FactIterator::from_rule_head_clause(args); let iter = FactIterator::from_rule_head_clause(args);
let mut fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head); let mut fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head);
@@ -1015,15 +1020,15 @@ impl<'b> CodeGenerator<'b> {
UnsafeVarMarker::from_fact_vars(safe_vars) UnsafeVarMarker::from_fact_vars(safe_vars)
} }
pub(crate) fn compile_fact(&mut self, term: &Term) -> Result<Code, CompilationError> { pub(crate) fn compile_fact(&mut self, fact: &Fact) -> Result<Code, CompilationError> {
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();
vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head); // vs.mark_vars_in_chunk(post_order_iter(term), term.arity(), GenContext::Head);
vs.populate_restricting_sets(); // vs.populate_restricting_sets();
self.marker.drain_var_data(vs, 1); // self.marker.drain_var_data(vs, 1);
let mut code = Vec::new(); let mut code = Vec::new();

View File

@@ -17,7 +17,7 @@ use std::collections::BTreeSet;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct DebrayAllocator { pub(crate) struct DebrayAllocator {
bindings: IndexMap<Var, VarData, FxBuildHasher>, bindings: IndexMap<Var, VarAlloc, FxBuildHasher>,
arg_c: usize, arg_c: usize,
temp_lb: usize, temp_lb: usize,
arity: usize, // 0 if not at head. arity: usize, // 0 if not at head.
@@ -36,7 +36,7 @@ impl DebrayAllocator {
fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool { fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool {
match self.bindings.get(var).unwrap() { match self.bindings.get(var).unwrap() {
&VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)), &VarAlloc::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)),
_ => false, _ => false,
} }
} }
@@ -49,7 +49,7 @@ impl DebrayAllocator {
fn alloc_with_cr(&self, var: &Var) -> usize { fn alloc_with_cr(&self, var: &Var) -> usize {
match self.bindings.get(var) { match self.bindings.get(var) {
Some(&VarData::Temp(_, _, ref tvd)) => { Some(&VarAlloc::Temp(_, _, ref tvd)) => {
for &(_, reg) in tvd.use_set.iter() { for &(_, reg) in tvd.use_set.iter() {
if !self.is_in_use(reg) { if !self.is_in_use(reg) {
return reg; return reg;
@@ -75,7 +75,7 @@ impl DebrayAllocator {
fn alloc_with_ca(&self, var: &Var) -> usize { fn alloc_with_ca(&self, var: &Var) -> usize {
match self.bindings.get(var) { match self.bindings.get(var) {
Some(&VarData::Temp(_, _, ref tvd)) => { Some(&VarAlloc::Temp(_, _, ref tvd)) => {
for &(_, reg) in tvd.use_set.iter() { for &(_, reg) in tvd.use_set.iter() {
if !self.is_in_use(reg) { if !self.is_in_use(reg) {
return reg; return reg;
@@ -114,7 +114,7 @@ impl DebrayAllocator {
// (GenContext::Last(_), k) is in t_var.use_set. // (GenContext::Last(_), k) is in t_var.use_set.
let tvd = self.bindings.get(t_var).unwrap(); let tvd = self.bindings.get(t_var).unwrap();
if let &VarData::Temp(_, _, ref tvd) = tvd { if let &VarAlloc::Temp(_, _, ref tvd) = tvd {
if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) { if !tvd.use_set.contains(&(GenContext::Last(chunk_num), k)) {
return Some((t_var.clone(), self.alloc_with_ca(t_var))); return Some((t_var.clone(), self.alloc_with_ca(t_var)));
} }
@@ -205,7 +205,7 @@ impl DebrayAllocator {
match term_loc { match term_loc {
GenContext::Head if !r.is_perm() => r.reg_num() == k, GenContext::Head if !r.is_perm() => r.reg_num() == k,
_ => match self.bindings().get(var).unwrap() { _ => match self.bindings().get(var).unwrap() {
&VarData::Temp(_, o, _) if r.reg_num() == k => o == k, &VarAlloc::Temp(_, o, _) if r.reg_num() == k => o == k,
_ => false, _ => false,
}, },
} }

View File

@@ -1,17 +1,11 @@
use crate::parser::ast::*;
use crate::forms::*; use crate::forms::*;
use crate::instructions::*; use crate::instructions::*;
use crate::iterators::*; use crate::machine::disjuncts::ClassifyInfo;
use crate::parser::ast::*;
use bit_set::*; use bit_set::*;
use indexmap::{IndexMap, IndexSet}; use indexmap::{IndexMap, IndexSet};
use std::cell::Cell;
use std::collections::BTreeSet;
use std::mem::swap;
use std::vec::Vec;
pub(crate) type OccurrenceSet = IndexSet<(GenContext, usize)>; pub(crate) type OccurrenceSet = IndexSet<(GenContext, usize)>;
#[derive(Debug)] #[derive(Debug)]
@@ -28,20 +22,19 @@ pub(crate) struct TempVarStatus {
temp_var_data: TempVarData, temp_var_data: TempVarData,
} }
// TODO: get ridda this! I think.
// Perm: 0 initially, a stack register once processed. // Perm: 0 initially, a stack register once processed.
// Temp: labeled with chunk_num and temp offset (unassigned if 0). // Temp: labeled with chunk_num and temp offset (unassigned if 0).
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum VarData { pub(crate) enum VarAlloc {
Perm(usize), Perm(usize),
Temp(usize, usize, TempVarData), Temp(usize, usize, TempVarData),
} }
impl VarData { impl VarAlloc {
pub(crate) fn as_reg_type(&self) -> RegType { pub(crate) fn as_reg_type(&self) -> RegType {
match self { match self {
&VarData::Temp(_, r, _) => RegType::Temp(r), &VarAlloc::Temp(_, r, _) => RegType::Temp(r),
&VarData::Perm(r) => RegType::Perm(r), &VarAlloc::Perm(r) => RegType::Perm(r),
} }
} }
} }
@@ -50,7 +43,7 @@ impl TempVarData {
pub(crate) fn new(last_term_arity: usize) -> Self { pub(crate) fn new(last_term_arity: usize) -> Self {
TempVarData { TempVarData {
last_term_arity: last_term_arity, last_term_arity: last_term_arity,
use_set: BitSet::new(), use_set: BitSet::<usize>::new(),
no_use_set: BitSet::new(), no_use_set: BitSet::new(),
conflict_set: BitSet::new(), conflict_set: BitSet::new(),
} }
@@ -72,7 +65,7 @@ impl TempVarData {
let mut conflict_set: BitSet<usize> = (1..arity).collect(); let mut conflict_set: BitSet<usize> = (1..arity).collect();
for &(_, reg) in self.use_set.iter() { for &(_, reg) in self.use_set.iter() {
conflict_set.remove(&reg); conflict_set.remove(reg);
} }
self.conflict_set = conflict_set; self.conflict_set = conflict_set;
@@ -83,27 +76,15 @@ impl TempVarData {
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct VariableFixtures { pub(crate) struct VariableFixtures {
temp_vars: IndexMap<usize, TempVarStatus>, temp_vars: IndexMap<usize, TempVarStatus>,
last_chunk_temp_vars: IndexSet<usize>, // TODO: has no use at all! remove it.
} }
impl<'a> VariableFixtures<'a> { impl VariableFixtures {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
VariableFixtures { VariableFixtures {
temp_vars: IndexMap::new(), temp_vars: IndexMap::new(),
last_chunk_temp_vars: IndexSet::new(),
} }
} }
// TODO: get rid of this also.
pub(crate) fn insert(&mut self, var: Var, vs: VariableFixture<'a>) {
self.temp_vars.insert(var, vs);
}
// TODO: used?
pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Var) {
self.last_chunk_temp_vars.insert(var);
}
// computes no_use and conflict sets for all temp vars. // computes no_use and conflict sets for all temp vars.
pub(crate) fn populate_restricting_sets(&mut self) { pub(crate) fn populate_restricting_sets(&mut self) {
// three stages: // three stages:
@@ -121,7 +102,7 @@ impl<'a> VariableFixtures<'a> {
let TempVarStatus { ref mut temp_var_data, .. } = var_status; let TempVarStatus { ref mut temp_var_data, .. } = var_status;
let mut use_set = OccurrenceSet::new(); let mut use_set = OccurrenceSet::new();
mem::swap(&mut temp_var_data.use_set, &mut use_set); std::mem::swap(&mut temp_var_data.use_set, &mut use_set);
use_sets.insert(var_gen_index, use_set); use_sets.insert(var_gen_index, use_set);
} }

View File

@@ -1,7 +1,7 @@
use crate::arena::*; use crate::arena::*;
use crate::atom_table::*; use crate::atom_table::*;
use crate::instructions::*; use crate::instructions::*;
use crate::machine::disjuncts::VarRecord; use crate::machine::disjuncts::VarData;
use crate::machine::heap::*; use crate::machine::heap::*;
use crate::machine::loader::PredicateQueue; use crate::machine::loader::PredicateQueue;
use crate::machine::machine_errors::*; use crate::machine::machine_errors::*;
@@ -57,7 +57,7 @@ impl AppendOrPrepend {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Level { pub enum Level {
Deep, Deep,
Root, Root,
@@ -79,7 +79,7 @@ pub enum CallPolicy {
Counted, Counted,
} }
#[derive(Debug, Clone)] #[derive(Debug)]
pub enum QueryTerm { pub enum QueryTerm {
// register, clause type, subterms, clause call policy. // register, clause type, subterms, clause call policy.
Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy), Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy),
@@ -111,14 +111,14 @@ impl QueryTerm {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Fact { pub struct Fact {
pub(crate) head: Term, pub(crate) head: Term,
pub(crate) var_records: Vec<VarRecord>, pub(crate) var_data: VarData,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Rule { pub struct Rule {
pub(crate) head: (Atom, Vec<Term>, QueryTerm), pub(crate) head: (Atom, Vec<Term>, QueryTerm),
pub(crate) clauses: Vec<QueryTerm>, pub(crate) clauses: Vec<QueryTerm>,
pub(crate) var_records: Vec<VarRecord>, pub(crate) var_data: VarData,
} }
#[derive(Clone, Debug, Hash)] #[derive(Clone, Debug, Hash)]
@@ -224,7 +224,7 @@ impl ClauseInfo for PredicateClause {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum PredicateClause { pub enum PredicateClause {
Fact(Term), Fact(Fact),
Rule(Rule), Rule(Rule),
} }

View File

@@ -43,24 +43,36 @@ impl VarPtr {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) enum TermRef<'a> { pub(crate) enum TermRef<'a> {
AnonVar(Level), AnonVar(Level),
Cut(Level),
GetLevel(Level),
Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term), Cons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
Fail(Level),
Literal(Level, &'a Cell<RegType>, &'a Literal), Literal(Level, &'a Cell<RegType>, &'a Literal),
Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>), Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>),
PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
CompleteString(Level, &'a Cell<RegType>, Atom), CompleteString(Level, &'a Cell<RegType>, Atom),
Var(Level, &'a Cell<VarReg>, Var), Var(Level, &'a Cell<VarReg>, Var),
InitialBranch(Level),
MiddleBranch(Level),
FinalBranch(Level),
} }
impl<'a> TermRef<'a> { impl<'a> TermRef<'a> {
pub(crate) fn level(self) -> Level { pub(crate) fn level(self) -> Level {
match self { match self {
TermRef::AnonVar(lvl) TermRef::AnonVar(lvl) |
| TermRef::Cons(lvl, ..) TermRef::Cons(lvl, ..) |
| TermRef::Literal(lvl, ..) TermRef::Cut(lvl) |
| TermRef::Var(lvl, ..) TermRef::GetLevel(lvl) |
| TermRef::Clause(lvl, ..) TermRef::Literal(lvl, ..) |
| TermRef::CompleteString(lvl, ..) TermRef::Var(lvl, ..) |
| TermRef::PartialString(lvl, ..) => lvl, TermRef::Clause(lvl, ..) |
TermRef::CompleteString(lvl, ..) |
TermRef::PartialString(lvl, ..) |
TermRef::InitialBranch(lvl) |
TermRef::MiddleBranch(lvl) |
TermRef::FinalBranch(lvl) |
TermRef::Fail(lvl) => lvl,
} }
} }
} }
@@ -68,14 +80,20 @@ impl<'a> TermRef<'a> {
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum TermIterState<'a> { pub(crate) enum TermIterState<'a> {
AnonVar(Level), AnonVar(Level),
Literal(Level, &'a Cell<RegType>, &'a Literal),
Clause(Level, usize, &'a Cell<RegType>, Atom, &'a Vec<Term>), Clause(Level, usize, &'a Cell<RegType>, Atom, &'a Vec<Term>),
Cut(Level),
Fail(Level),
GetLevel(Level),
InitialBranch(Level, &'a Vec<QueryTerm>),
MiddleBranch(Level, &'a Vec<QueryTerm>),
FinalBranch(Level, &'a Vec<QueryTerm>),
Sequence(Level, &'a Vec<QueryTerm>),
Literal(Level, &'a Cell<RegType>, &'a Literal),
InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term), InitialCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term), FinalCons(Level, &'a Cell<RegType>, &'a Term, &'a Term),
InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
FinalPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), FinalPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
CompleteString(Level, &'a Cell<RegType>, Atom), CompleteString(Level, &'a Cell<RegType>, Atom),
UnblockedCut(Level, &'a Cell<VarReg>),
Var(Level, &'a Cell<VarReg>, VarPtr), Var(Level, &'a Cell<VarReg>, VarPtr),
} }
@@ -108,8 +126,7 @@ pub(crate) struct QueryIterator<'a> {
impl<'a> QueryIterator<'a> { impl<'a> QueryIterator<'a> {
fn push_subterm(&mut self, lvl: Level, term: &'a Term) { fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
self.state_stack self.state_stack.push(TermIterState::subterm_to_state(lvl, term));
.push(TermIterState::subterm_to_state(lvl, term));
} }
fn from_rule_head_clause(terms: &'a Vec<Term>) -> Self { fn from_rule_head_clause(terms: &'a Vec<Term>) -> Self {
@@ -145,47 +162,52 @@ impl<'a> QueryIterator<'a> {
} }
} }
fn new(term: &'a QueryTerm) -> Self { fn extend_state(&mut self, lvl: Level, term: &'a QueryTerm) {
match term { match term {
&QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => { &QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => {
let state = TermIterState::Clause(Level::Root, 1, cell, atom!("$call"), terms); self.state_stack.push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms));
QueryIterator {
state_stack: vec![state],
}
} }
&QueryTerm::Clause(ref cell, ref ct, ref terms, _) => { &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => {
let state = TermIterState::Clause(Level::Root, 0, cell, ct.name(), terms); self.state_stack.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms));
QueryIterator {
state_stack: vec![state],
}
} }
&QueryTerm::UnblockedCut(ref cell) => { &QueryTerm::Cut => {
let state = TermIterState::UnblockedCut(Level::Root, cell); self.state_stack.push(TermIterState::Cut(lvl));
QueryIterator {
state_stack: vec![state],
}
} }
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => { &QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
let state = TermIterState::Var(Level::Root, cell, VarPtr::from(var)); // TODO: get rid of it if possible. or! specialized TermIterState variant.
QueryIterator { self.state_stack.push(TermIterState::Var(lvl, cell, VarPtr::from(var)));
state_stack: vec![state],
}
} }
&QueryTerm::Jump(ref vars) => { &QueryTerm::Not(ref terms) => {
let state_stack = vars self.state_stack.push(TermIterState::Fail(lvl));
self.state_stack.push(TermIterState::Cut(lvl));
self.state_stack.push(TermIterState::Sequence(lvl, terms));
}
&QueryTerm::IfThen(ref if_terms, ref then_terms) => {
self.state_stack.push(TermIterState::Sequence(lvl, then_terms));
self.state_stack.push(TermIterState::Cut(lvl));
self.state_stack.push(TermIterState::Sequence(lvl, if_terms));
self.state_stack.push(TermIterState::GetLevel(lvl));
}
&QueryTerm::Branch(ref branches) => {
let len = branches.len();
self.state_stack.push(TermIterState::FinalBranch(lvl, &branches[len - 1]));
self.state_stack.extend(branches[1 .. len - 1]
.iter() .iter()
.rev() .rev()
.map(|t| TermIterState::subterm_to_state(Level::Shallow, t)) .map(|t| TermIterState::MiddleBranch(lvl, t)),
.collect(); );
QueryIterator { state_stack } self.state_stack.push(TermIterState::InitialBranch(lvl, &branches[0]));
} }
&QueryTerm::BlockedCut => QueryIterator {
state_stack: vec![],
},
} }
} }
fn new(term: &'a QueryTerm) -> Self {
let mut iter = QueryIterator { state_stack: vec![] };
iter.extend_state(Level::Root, term);
iter
}
} }
impl<'a> Iterator for QueryIterator<'a> { impl<'a> Iterator for QueryIterator<'a> {
@@ -247,8 +269,31 @@ impl<'a> Iterator for QueryIterator<'a> {
TermIterState::Var(lvl, cell, var) => { TermIterState::Var(lvl, cell, var) => {
return Some(TermRef::Var(lvl, cell, Var::from(var))); return Some(TermRef::Var(lvl, cell, Var::from(var)));
} }
TermIterState::UnblockedCut(lvl, cell) => { TermIterState::Cut(lvl) => {
return Some(TermRef::Var(lvl, cell, Var::from("!"))); return Some(TermRef::Cut(lvl));
}
TermIterState::GetLevel(lvl) => {
return Some(TermRef::GetLevel(lvl));
}
TermIterState::InitialBranch(lvl, ref branch) => {
self.state_stack.push(TermIterState::Sequence(lvl, branch));
return Some(TermRef::InitialBranch(lvl));
}
TermIterState::MiddleBranch(lvl, ref branch) => {
self.state_stack.push(TermIterState::Sequence(lvl, branch));
return Some(TermRef::MiddleBranch(lvl));
}
TermIterState::FinalBranch(lvl, ref branch) => {
self.state_stack.push(TermIterState::Sequence(lvl, branch));
return Some(TermRef::FinalBranch(lvl));
}
TermIterState::Sequence(lvl, ref terms) => {
for term in branch.iter().rev() {
self.extend_state(lvl, term);
}
}
TermIterState::Fail(lvl) => {
return Some(TermRef::Fail(lvl));
} }
}; };
} }
@@ -398,23 +443,9 @@ impl<'a> ChunkedTerm<'a> {
} }
} }
fn contains_cut_var<'a, Iter: Iterator<Item = &'a Term>>(terms: Iter) -> bool {
for term in terms {
if let &Term::Var(_, ref var) = term {
if var.as_str() == Some("!") {
return true;
}
}
}
false
}
pub(crate) struct ChunkedIterator<'a> { pub(crate) struct ChunkedIterator<'a> {
pub(crate) chunk_num: usize, pub(crate) chunk_num: usize,
iter: Box<dyn Iterator<Item = ChunkedTerm<'a>> + 'a>, iter: Box<dyn Iterator<Item = ChunkedTerm<'a>> + 'a>,
deep_cut_encountered: bool,
cut_var_in_head: bool,
} }
impl<'a> fmt::Debug for ChunkedIterator<'a> { impl<'a> fmt::Debug for ChunkedIterator<'a> {
@@ -423,8 +454,6 @@ impl<'a> fmt::Debug for ChunkedIterator<'a> {
.field("chunk_num", &self.chunk_num) .field("chunk_num", &self.chunk_num)
// Hacky solution. // Hacky solution.
.field("iter", &"Box<dyn Iterator<Item = ChunkedTerm<'a>> + 'a>") .field("iter", &"Box<dyn Iterator<Item = ChunkedTerm<'a>> + 'a>")
.field("deep_cut_encountered", &self.deep_cut_encountered)
.field("cut_var_in_head", &self.cut_var_in_head)
.finish() .finish()
} }
} }
@@ -458,8 +487,6 @@ impl<'a> ChunkedIterator<'a> {
ChunkedIterator { ChunkedIterator {
chunk_num: 0, chunk_num: 0,
iter: Box::new(iter), iter: Box::new(iter),
deep_cut_encountered: false,
cut_var_in_head: false,
} }
} }
@@ -467,6 +494,7 @@ impl<'a> ChunkedIterator<'a> {
let &Rule { let &Rule {
head: (ref name, ref args, ref p1), head: (ref name, ref args, ref p1),
ref clauses, ref clauses,
..
} = rule; } = rule;
let iter = once(ChunkedTerm::HeadClause(name.clone(), args)); let iter = once(ChunkedTerm::HeadClause(name.clone(), args));
@@ -476,15 +504,9 @@ impl<'a> ChunkedIterator<'a> {
ChunkedIterator { ChunkedIterator {
chunk_num: 0, chunk_num: 0,
iter: Box::new(iter), iter: Box::new(iter),
deep_cut_encountered: false,
cut_var_in_head: false,
} }
} }
pub(crate) fn encountered_deep_cut(&self) -> bool {
self.deep_cut_encountered
}
fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec<ChunkedTerm<'a>>) { fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec<ChunkedTerm<'a>>) {
let mut arity = 0; let mut arity = 0;
let mut item = Some(term); let mut item = Some(term);
@@ -493,42 +515,18 @@ impl<'a> ChunkedIterator<'a> {
while let Some(term) = item { while let Some(term) = item {
match term { match term {
ChunkedTerm::HeadClause(_, terms) => { ChunkedTerm::HeadClause(_, terms) => {
if contains_cut_var(terms.iter()) {
self.cut_var_in_head = true;
}
result.push(term); result.push(term);
} }
ChunkedTerm::BodyTerm(&QueryTerm::Jump(ref vars)) => { ChunkedTerm::BodyTerm(&QueryTerm::Cut) => {
result.push(term); result.push(term);
arity = vars.len();
if contains_cut_var(vars.iter()) && !self.cut_var_in_head {
self.deep_cut_encountered = true;
}
break;
}
ChunkedTerm::BodyTerm(&QueryTerm::BlockedCut) => {
result.push(term);
if self.chunk_num > 0 {
self.deep_cut_encountered = true;
}
} }
ChunkedTerm::BodyTerm(&QueryTerm::GetLevelAndUnify(..)) => { ChunkedTerm::BodyTerm(&QueryTerm::GetLevelAndUnify(..)) => {
self.deep_cut_encountered = true;
result.push(term); result.push(term);
arity = 1; arity = 1;
break; break;
} }
ChunkedTerm::BodyTerm(&QueryTerm::UnblockedCut(..)) => {
self.deep_cut_encountered = true;
result.push(term);
}
ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => { ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => {
result.push(term) result.push(term);
} }
ChunkedTerm::BodyTerm(&QueryTerm::Clause( ChunkedTerm::BodyTerm(&QueryTerm::Clause(
_, _,

View File

@@ -57,6 +57,7 @@ pub(super) fn compile_relation(
} }
} }
/*
pub(super) fn compile_appendix( pub(super) fn compile_appendix(
code: &mut Code, code: &mut Code,
mut queue: VecDeque<TopLevel>, mut queue: VecDeque<TopLevel>,
@@ -97,6 +98,7 @@ pub(super) fn compile_appendix(
Ok(()) Ok(())
} }
*/
fn lower_bound_of_target_clause(skeleton: &PredicateSkeleton, target_pos: usize) -> usize { fn lower_bound_of_target_clause(skeleton: &PredicateSkeleton, target_pos: usize) -> usize {
if target_pos == 0 { if target_pos == 0 {
@@ -1342,7 +1344,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut preprocessor = Preprocessor::new(settings); let mut preprocessor = Preprocessor::new(settings);
let clause = self.try_term_to_tl(term, &mut preprocessor)?; let clause = self.try_term_to_tl(term, &mut preprocessor)?;
let queue = preprocessor.parse_queue(self)?; // let queue = preprocessor.parse_queue(self)?;
let mut cg = CodeGenerator::new( let mut cg = CodeGenerator::new(
&mut LS::machine_st(&mut self.payload).atom_tbl, &mut LS::machine_st(&mut self.payload).atom_tbl,
@@ -1351,6 +1353,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut clause_code = cg.compile_predicate(&vec![clause])?; let mut clause_code = cg.compile_predicate(&vec![clause])?;
/*
compile_appendix( compile_appendix(
&mut clause_code, &mut clause_code,
queue, queue,
@@ -1358,6 +1361,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
settings.non_counted_bt, settings.non_counted_bt,
cg.atom_tbl, cg.atom_tbl,
)?; )?;
*/
Ok(StandaloneCompileResult { Ok(StandaloneCompileResult {
clause_code, clause_code,
@@ -1385,7 +1389,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
clauses.push(self.try_term_to_tl(term, &mut preprocessor)?); clauses.push(self.try_term_to_tl(term, &mut preprocessor)?);
} }
let queue = preprocessor.parse_queue(self)?; // let queue = preprocessor.parse_queue(self)?;
let mut cg = CodeGenerator::new( let mut cg = CodeGenerator::new(
&mut LS::machine_st(&mut self.payload).atom_tbl, &mut LS::machine_st(&mut self.payload).atom_tbl,
@@ -1394,6 +1398,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut code = cg.compile_predicate(&clauses)?; let mut code = cg.compile_predicate(&clauses)?;
/*
compile_appendix( compile_appendix(
&mut code, &mut code,
queue, queue,
@@ -1401,6 +1406,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
settings.non_counted_bt, settings.non_counted_bt,
cg.atom_tbl, cg.atom_tbl,
)?; )?;
*/
if settings.is_extensible { if settings.is_extensible {
let mut clause_clause_locs = VecDeque::new(); let mut clause_clause_locs = VecDeque::new();

View File

@@ -487,6 +487,8 @@ impl VariableClassifier {
Ok(()) Ok(())
} }
// TODO: maybe replace Vec<QueryTerm> with an iterator that has, in the stream,
// with a 'QueryTerm' that toggles the chunk num and type, like we do here.
fn classify_body_variables<'a, LS: LoadState<'a>>( fn classify_body_variables<'a, LS: LoadState<'a>>(
&mut self, &mut self,
loader: &mut Loader<'a, LS>, loader: &mut Loader<'a, LS>,
@@ -826,6 +828,7 @@ impl BranchMap {
debug_assert_eq!(var_data.records.len(), var_num); debug_assert_eq!(var_data.records.len(), var_num);
var_data.fixtures.populate_restricting_sets();
var_data var_data
} }
} }

View File

@@ -228,7 +228,7 @@ impl CodeIndex {
} }
pub(crate) type HeapVarDict = IndexMap<Var, HeapCellValue, FxBuildHasher>; pub(crate) type HeapVarDict = IndexMap<Var, HeapCellValue, FxBuildHasher>;
pub(crate) type AllocVarDict = IndexMap<Var, VarData, FxBuildHasher>; pub(crate) type AllocVarDict = IndexMap<Var, VarAlloc, FxBuildHasher>;
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>; pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>;

View File

@@ -553,9 +553,9 @@ impl Preprocessor {
self.settings.default_call_policy(), self.settings.default_call_policy(),
); );
let (head, var_records) = classifier.classify_fact(term)?; let (head, var_data) = classifier.classify_fact(term)?;
Ok(Fact { head, var_records }) Ok(Fact { head, var_data })
} }
_ => Err(CompilationError::InadmissibleFact), _ => Err(CompilationError::InadmissibleFact),
} }
@@ -571,7 +571,7 @@ impl Preprocessor {
self.settings.default_call_policy(), self.settings.default_call_policy(),
); );
let (head, mut query_terms, var_records) = let (head, mut query_terms, var_data) =
classifier.classify_rule(loader, head, body)?; classifier.classify_rule(loader, head, body)?;
let clauses = query_terms.drain(1..).collect(); let clauses = query_terms.drain(1..).collect();
@@ -581,12 +581,12 @@ impl Preprocessor {
Term::Clause(_, name, terms) => Ok(Rule { Term::Clause(_, name, terms) => Ok(Rule {
head: (name, terms, qt), head: (name, terms, qt),
clauses, clauses,
var_records, var_data,
}), }),
Term::Literal(_, Literal::Atom(name)) => Ok(Rule { Term::Literal(_, Literal::Atom(name)) => Ok(Rule {
head: (name, vec![], qt), head: (name, vec![], qt),
clauses, clauses,
var_records, var_data,
}), }),
_ => Err(CompilationError::InvalidRuleHead), _ => Err(CompilationError::InvalidRuleHead),
} }