group predicate subsequences by first instantiated arg (#1053)
This commit is contained in:
113
src/codegen.rs
113
src/codegen.rs
@@ -969,68 +969,61 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of the first instantiated argument.
|
fn split_predicate(clauses: &[PredicateClause]) -> Vec<ClauseSpan> {
|
||||||
fn first_instantiated_index(clauses: &[PredicateClause]) -> Option<usize> {
|
|
||||||
let mut optimal_index = None;
|
|
||||||
let has_args = match clauses.first() {
|
|
||||||
Some(clause) => match clause.args() {
|
|
||||||
Some(args) => !args.is_empty(),
|
|
||||||
None => false,
|
|
||||||
},
|
|
||||||
None => false,
|
|
||||||
};
|
|
||||||
if !has_args {
|
|
||||||
return optimal_index;
|
|
||||||
}
|
|
||||||
for clause in clauses.iter() {
|
|
||||||
let args = clause.args().unwrap();
|
|
||||||
for (i, arg) in args.iter().enumerate() {
|
|
||||||
if let Some(optimal_index) = optimal_index {
|
|
||||||
if i >= optimal_index {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match arg {
|
|
||||||
Term::AnonVar | Term::Var(..) => (),
|
|
||||||
_ => {
|
|
||||||
match optimal_index {
|
|
||||||
Some(ref mut optimal_i) => *optimal_i = i,
|
|
||||||
None => optimal_index = Some(i),
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
optimal_index
|
|
||||||
}
|
|
||||||
|
|
||||||
fn split_predicate(clauses: &[PredicateClause], optimal_index: usize) -> Vec<(usize, usize)> {
|
|
||||||
let mut subseqs = Vec::new();
|
let mut subseqs = Vec::new();
|
||||||
let mut left_index = 0;
|
let mut left = 0;
|
||||||
|
let mut optimal_index = 0;
|
||||||
|
|
||||||
if clauses.first().unwrap().args().is_some() {
|
'outer: for (right, clause) in clauses.iter().enumerate() {
|
||||||
for (right_index, clause) in clauses.iter().enumerate() {
|
if let Some(args) = clause.args() {
|
||||||
// Can unwrap safely.
|
for (instantiated_arg_index, arg) in args.iter().enumerate() {
|
||||||
if let Some(arg) = clause.args().unwrap().iter().nth(optimal_index) {
|
|
||||||
match arg {
|
match arg {
|
||||||
Term::Var(..) | Term::AnonVar => {
|
Term::Var(..) | Term::AnonVar => {
|
||||||
if left_index < right_index {
|
}
|
||||||
subseqs.push((left_index, right_index));
|
_ => {
|
||||||
|
if optimal_index != instantiated_arg_index {
|
||||||
|
if left >= right {
|
||||||
|
optimal_index = instantiated_arg_index;
|
||||||
|
continue 'outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
subseqs.push(ClauseSpan {
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
instantiated_arg_index: optimal_index,
|
||||||
|
});
|
||||||
|
|
||||||
|
optimal_index = instantiated_arg_index;
|
||||||
|
left = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
subseqs.push((right_index, right_index + 1));
|
continue 'outer;
|
||||||
left_index = right_index + 1;
|
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if left < right {
|
||||||
|
subseqs.push(ClauseSpan { left, right, instantiated_arg_index: optimal_index });
|
||||||
|
}
|
||||||
|
|
||||||
|
optimal_index = 0;
|
||||||
|
|
||||||
|
subseqs.push(ClauseSpan {
|
||||||
|
left: right,
|
||||||
|
right: right + 1,
|
||||||
|
instantiated_arg_index: optimal_index,
|
||||||
|
});
|
||||||
|
|
||||||
|
left = right + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if left_index < clauses.len() {
|
if left < clauses.len() {
|
||||||
subseqs.push((left_index, clauses.len()));
|
subseqs.push(ClauseSpan {
|
||||||
|
left,
|
||||||
|
right: clauses.len(),
|
||||||
|
instantiated_arg_index: optimal_index,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
subseqs
|
subseqs
|
||||||
@@ -1134,28 +1127,36 @@ impl<'a, 'b: 'a, TermMarker: Allocator<'a>> CodeGenerator<'b, TermMarker> {
|
|||||||
) -> 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) {
|
let optimal_index = match Self::first_instantiated_index(&clauses) {
|
||||||
Some(index) => index,
|
Some(index) => index,
|
||||||
None => 0, // Default to first argument indexing.
|
None => 0, // Default to first argument indexing.
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
let split_pred = Self::split_predicate(&clauses, optimal_index);
|
let split_pred = Self::split_predicate(&clauses);
|
||||||
let multi_seq = split_pred.len() > 1;
|
let multi_seq = split_pred.len() > 1;
|
||||||
|
|
||||||
for (l, r) in split_pred {
|
for ClauseSpan { left, right, instantiated_arg_index } in split_pred {
|
||||||
let skel_lower_bound = self.skeleton.clauses.len();
|
let skel_lower_bound = self.skeleton.clauses.len();
|
||||||
let code_segment = if self.settings.is_dynamic() {
|
let code_segment = if self.settings.is_dynamic() {
|
||||||
self.compile_pred_subseq::<DynamicCodeIndices>(&clauses[l..r], optimal_index)?
|
self.compile_pred_subseq::<DynamicCodeIndices>(
|
||||||
|
&clauses[left..right],
|
||||||
|
instantiated_arg_index,
|
||||||
|
)?
|
||||||
} else {
|
} else {
|
||||||
self.compile_pred_subseq::<StaticCodeIndices>(&clauses[l..r], optimal_index)?
|
self.compile_pred_subseq::<StaticCodeIndices>(
|
||||||
|
&clauses[left..right],
|
||||||
|
instantiated_arg_index,
|
||||||
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let clause_start_offset = code.len();
|
let clause_start_offset = code.len();
|
||||||
|
|
||||||
if multi_seq {
|
if multi_seq {
|
||||||
let choice = match l {
|
let choice = match left {
|
||||||
0 => self.settings.try_me_else(code_segment.len() + 1),
|
0 => self.settings.try_me_else(code_segment.len() + 1),
|
||||||
_ if r == clauses.len() => self.settings.trust_me(),
|
_ if right == clauses.len() => self.settings.trust_me(),
|
||||||
_ => self.settings.retry_me_else(code_segment.len() + 1),
|
_ => self.settings.retry_me_else(code_segment.len() + 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -219,7 +219,6 @@ pub enum PredicateClause {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PredicateClause {
|
impl PredicateClause {
|
||||||
// TODO: add this to `Term` in `crate::parser` like `first_arg`.
|
|
||||||
pub(crate) fn args(&self) -> Option<&[Term]> {
|
pub(crate) fn args(&self) -> Option<&[Term]> {
|
||||||
match self {
|
match self {
|
||||||
PredicateClause::Fact(term, ..) => match term {
|
PredicateClause::Fact(term, ..) => match term {
|
||||||
@@ -237,6 +236,13 @@ impl PredicateClause {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ClauseSpan {
|
||||||
|
pub left: usize,
|
||||||
|
pub right: usize,
|
||||||
|
pub instantiated_arg_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ModuleSource {
|
pub enum ModuleSource {
|
||||||
Library(Atom),
|
Library(Atom),
|
||||||
|
|||||||
Reference in New Issue
Block a user