From: Mark Thom Date: Wed, 28 Dec 2022 06:19:18 +0000 (-0700) Subject: add QueryTerm::ChunkTypeBoundary X-Git-Tag: v0.9.2~123^2~31 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=097849385ee50ba49a1b7a06125ece28bab597b8;p=scryer-prolog.git add QueryTerm::ChunkTypeBoundary --- diff --git a/src/forms.rs b/src/forms.rs index 2b46da2c..4d7b7f47 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -79,6 +79,24 @@ pub enum CallPolicy { 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)] pub enum QueryTerm { // register, clause type, subterms, clause call policy. @@ -88,6 +106,7 @@ pub enum QueryTerm { IfThen(Vec, Vec), Branch(Vec>), GetLevelAndUnify(Cell, Var), + ChunkTypeBoundary(ChunkType), } impl QueryTerm { diff --git a/src/machine/disjuncts.rs b/src/machine/disjuncts.rs index 3231c652..501aaddd 100644 --- a/src/machine/disjuncts.rs +++ b/src/machine/disjuncts.rs @@ -137,24 +137,6 @@ impl DerefMut for BranchMap { type RootSet = IndexSet; -#[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)] pub struct ClassifyInfo { arg_c: usize, @@ -257,7 +239,7 @@ fn merge_branch_seq>(branches: Iter) -> Branch } fn flatten_into_disjunct(build_stack: &mut Vec, 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] { disjuncts.push(iter.collect()); @@ -342,28 +324,6 @@ impl VariableClassifier { Ok((head, query_terms, self.branch_map.separate_and_classify_variables())) } - /* - pub fn to_branch_map(mut self, term: Term) -> Result { - 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) { for branches in self.branch_map.values_mut() { let mut old_branches = std::mem::replace(branches, vec![]); @@ -487,8 +447,6 @@ impl VariableClassifier { Ok(()) } - // TODO: maybe replace Vec 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>>( &mut self, loader: &mut Loader<'a, LS>, @@ -515,15 +473,18 @@ impl VariableClassifier { TraversalState::IncrChunkNum => { self.current_chunk_num += 1; chunk_type = ChunkType::Mid; + build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type)); } TraversalState::ResetCallPolicy(call_policy) => { self.call_policy = call_policy; } TraversalState::SetLastChunkType => { chunk_type = ChunkType::Last; + build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type)); } TraversalState::BuildDisjunct(reset_chunk_type, preceding_len) => { chunk_type = reset_chunk_type; + build_stack.push(QueryTerm::ChunkTypeBoundary(chunk_type)); flatten_into_disjunct(&mut build_stack, preceding_len); } TraversalState::BuildFinalDisjunct(preceding_len) => { @@ -579,7 +540,7 @@ impl VariableClassifier { } 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( self.current_branch_num.halve_delta(), @@ -630,6 +591,7 @@ impl VariableClassifier { state_stack.push(TraversalState::IncrChunkNum); // TODO: need to classify this variable? + // what is the difference between $get_cp and this exactly? if let Term::Var(_, ref var) = &terms[0] { build_stack.push( QueryTerm::GetLevelAndUnify(