perform singleton variable scans on top level terms only

This commit is contained in:
Mark Thom
2019-10-04 10:38:45 -06:00
parent 0a84f183fe
commit caeff99f69
4 changed files with 46 additions and 132 deletions

View File

@@ -3,7 +3,6 @@ use prolog_parser::parser::OpDesc;
use prolog_parser::tabled_rc::*;
use prolog::clause_types::*;
use prolog::iterators::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::ordered_float::OrderedFloat;
@@ -59,40 +58,6 @@ impl TopLevel {
_ => false,
}
}
pub fn location(&self) -> Option<(usize, usize)> {
match self {
&TopLevel::Fact(_, line_num, col_num) | &TopLevel::Rule(_, line_num, col_num) =>
Some((line_num, col_num)),
&TopLevel::Predicate(Predicate(ref clauses)) =>
clauses.first().map(|clause| (clause.line_num(), clause.col_num())),
_ =>
None
}
}
pub fn var_count(&self) -> Option<Vec<IndexMap<Rc<Var>, usize>>> {
match self {
&TopLevel::Fact(ref term, ..) => {
let mut var_count = IndexMap::new();
for term_ref in breadth_first_iter(term, true) {
if let TermRef::Var(_, _, var) = term_ref {
let entry = var_count.entry(var).or_insert(0);
*entry += 1;
}
}
Some(vec![var_count])
}
&TopLevel::Rule(ref rule, ..) =>
Some(vec![rule.var_count()]),
&TopLevel::Predicate(ref predicate) =>
Some(predicate.var_count()),
_ =>
None
}
}
}
#[derive(Clone, Copy)]
@@ -145,40 +110,6 @@ pub struct Rule {
pub clauses: Vec<QueryTerm>,
}
impl Rule {
pub fn var_count(&self) -> IndexMap<Rc<Var>, usize> {
let mut var_count = IndexMap::new();
for root_term in &self.head.1 {
// true because the root term is iterable.
for term_ref in breadth_first_iter(root_term, true) {
if let TermRef::Var(_, _, var) = term_ref {
let entry = var_count.entry(var).or_insert(0);
*entry += 1;
}
}
}
for term_ref in query_term_post_order_iter(&self.head.2) {
if let TermRef::Var(_, _, var) = term_ref {
let entry = var_count.entry(var).or_insert(0);
*entry += 1;
}
}
for clause in &self.clauses {
for term_ref in query_term_post_order_iter(clause) {
if let TermRef::Var(_, _, var) = term_ref {
let entry = var_count.entry(var).or_insert(0);
*entry += 1;
}
}
}
var_count
}
}
#[derive(Clone)]
pub struct Predicate(pub Vec<PredicateClause>);
@@ -199,10 +130,6 @@ impl Predicate {
.first()
.and_then(|clause| clause.name().map(|name| (name, clause.arity())))
}
pub fn var_count(&self) -> Vec<IndexMap<Rc<Var>, usize>> {
self.0.iter().map(|clause| clause.var_count()).collect()
}
}
pub type CompiledResult = (Predicate, VecDeque<TopLevel>);
@@ -234,39 +161,6 @@ impl PredicateClause {
&PredicateClause::Rule(ref rule, ..) => Some(rule.head.0.clone()),
}
}
pub fn line_num(&self) -> usize {
match self {
&PredicateClause::Fact(_, line_num, _) => line_num,
&PredicateClause::Rule(_, line_num, _) => line_num
}
}
pub fn col_num(&self) -> usize {
match self {
&PredicateClause::Fact(_, _, col_num) => col_num,
&PredicateClause::Rule(_, _, col_num) => col_num
}
}
pub fn var_count(&self) -> IndexMap<Rc<Var>, usize> {
match self {
&PredicateClause::Fact(ref term, ..) => {
let mut var_count = IndexMap::new();
for term_ref in breadth_first_iter(term, true) {
if let TermRef::Var(_, _, var) = term_ref {
let entry = var_count.entry(var).or_insert(0);
*entry += 1;
}
}
var_count
}
&PredicateClause::Rule(ref rule, ..) =>
rule.var_count()
}
}
}
#[derive(Clone)]