add QueryTerm::ChunkTypeBoundary

This commit is contained in:
Mark Thom
2022-12-27 23:19:18 -07:00
committed by Mark
parent c4783062ff
commit 097849385e
2 changed files with 25 additions and 44 deletions

View File

@@ -79,6 +79,24 @@ pub enum CallPolicy {
Counted, Counted,
} }
#[derive(Debug, Clone, Copy)]
enum ChunkType {
Head,
Mid,
Last,
}
impl ChunkType {
#[inline(always)]
pub fn to_gen_context(self, chunk_num: usize) -> GenContext {
match self {
ChunkType::Head => GenContext::Head,
ChunkType::Mid => GenContext::Mid(chunk_num),
ChunkType::Last => GenContext::Last(chunk_num),
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum QueryTerm { pub enum QueryTerm {
// register, clause type, subterms, clause call policy. // register, clause type, subterms, clause call policy.
@@ -88,6 +106,7 @@ pub enum QueryTerm {
IfThen(Vec<QueryTerm>, Vec<QueryTerm>), IfThen(Vec<QueryTerm>, Vec<QueryTerm>),
Branch(Vec<Vec<QueryTerm>>), Branch(Vec<Vec<QueryTerm>>),
GetLevelAndUnify(Cell<VarReg>, Var), GetLevelAndUnify(Cell<VarReg>, Var),
ChunkTypeBoundary(ChunkType),
} }
impl QueryTerm { impl QueryTerm {

View File

@@ -137,24 +137,6 @@ impl DerefMut for BranchMap {
type RootSet = IndexSet<BranchNumber>; type RootSet = IndexSet<BranchNumber>;
#[derive(Debug, Clone, Copy)]
enum ChunkType {
Head,
Mid,
Last,
}
impl ChunkType {
#[inline(always)]
fn to_gen_context(self, chunk_num: usize) -> GenContext {
match self {
ChunkType::Head => GenContext::Head,
ChunkType::Mid => GenContext::Mid(chunk_num),
ChunkType::Last => GenContext::Last(chunk_num),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ClassifyInfo { pub struct ClassifyInfo {
arg_c: usize, arg_c: usize,
@@ -257,7 +239,7 @@ fn merge_branch_seq<Iter: Iterator<Item = BranchInfo>>(branches: Iter) -> Branch
} }
fn flatten_into_disjunct(build_stack: &mut Vec<QueryTerm>, preceding_len: usize) { fn flatten_into_disjunct(build_stack: &mut Vec<QueryTerm>, preceding_len: usize) {
let iter = build_stack.drain(preceding_len ..); let iter = build_stack.drain(preceding_len + 1 ..);
if let QueryTerm::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] { if let QueryTerm::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] {
disjuncts.push(iter.collect()); disjuncts.push(iter.collect());
@@ -342,28 +324,6 @@ impl VariableClassifier {
Ok((head, query_terms, self.branch_map.separate_and_classify_variables())) Ok((head, query_terms, self.branch_map.separate_and_classify_variables()))
} }
/*
pub fn to_branch_map(mut self, term: Term) -> Result<ClassifierResult, CompilationError> {
self.root_set.insert(BranchNumber::default());
let (head_term, query_terms) = match term {
Term::Clause(_, atom!(":-"), terms) if terms.len() == 2 => {
let head_term = terms[0];
self.classify_head_variables(&head_term)?;
(head_term, self.classify_body_variables(terms[1])?)
}
_ => {
self.classify_head_variables(&term)?;
(term, vec![])
}
};
self.merge_branches();
Ok((head_term, query_terms, self.branch_map))
}
*/
fn merge_branches(&mut self) { fn merge_branches(&mut self) {
for branches in self.branch_map.values_mut() { for branches in self.branch_map.values_mut() {
let mut old_branches = std::mem::replace(branches, vec![]); let mut old_branches = std::mem::replace(branches, vec![]);
@@ -487,8 +447,6 @@ 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>,
@@ -515,15 +473,18 @@ impl VariableClassifier {
TraversalState::IncrChunkNum => { TraversalState::IncrChunkNum => {
self.current_chunk_num += 1; self.current_chunk_num += 1;
chunk_type = ChunkType::Mid; chunk_type = ChunkType::Mid;
build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type));
} }
TraversalState::ResetCallPolicy(call_policy) => { TraversalState::ResetCallPolicy(call_policy) => {
self.call_policy = call_policy; self.call_policy = call_policy;
} }
TraversalState::SetLastChunkType => { TraversalState::SetLastChunkType => {
chunk_type = ChunkType::Last; chunk_type = ChunkType::Last;
build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type));
} }
TraversalState::BuildDisjunct(reset_chunk_type, preceding_len) => { TraversalState::BuildDisjunct(reset_chunk_type, preceding_len) => {
chunk_type = reset_chunk_type; chunk_type = reset_chunk_type;
build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type));
flatten_into_disjunct(&mut build_stack, preceding_len); flatten_into_disjunct(&mut build_stack, preceding_len);
} }
TraversalState::BuildFinalDisjunct(preceding_len) => { TraversalState::BuildFinalDisjunct(preceding_len) => {
@@ -579,7 +540,7 @@ impl VariableClassifier {
} }
let build_stack_len = build_stack.len(); let build_stack_len = build_stack.len();
build_stack.push(QueryTerm::Branch(vec![])); build_stack.push(QueryTerm::Branch(Vec::with_capacity(branches.len())));
state_stack.push(TraversalState::RepBranchNum( state_stack.push(TraversalState::RepBranchNum(
self.current_branch_num.halve_delta(), self.current_branch_num.halve_delta(),
@@ -630,6 +591,7 @@ impl VariableClassifier {
state_stack.push(TraversalState::IncrChunkNum); state_stack.push(TraversalState::IncrChunkNum);
// TODO: need to classify this variable? // TODO: need to classify this variable?
// what is the difference between $get_cp and this exactly?
if let Term::Var(_, ref var) = &terms[0] { if let Term::Var(_, ref var) = &terms[0] {
build_stack.push( build_stack.push(
QueryTerm::GetLevelAndUnify( QueryTerm::GetLevelAndUnify(