[package]
name = "scryer-prolog"
-version = "0.8.99"
+version = "0.8.100"
build = "build.rs"
repository = "https://github.com/mthom/scryer-prolog"
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;
_ => 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)]
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>);
.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>);
&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)]
use prolog::debray_allocator::*;
use prolog::forms::*;
use prolog::instructions::*;
+use prolog::iterators::*;
use prolog::machine::machine_errors::*;
use prolog::machine::machine_indices::*;
use prolog::machine::term_expansion::ExpansionAdditionResult;
}
fn issue_singleton_warnings(
- tl: &TopLevel,
module_name: ClauseName,
+ terms_and_locs: Vec<(Term, usize, usize)>,
) {
- if let Some((line_num, _)) = tl.location() {
- if let Some(var_counts) = tl.var_count() {
- for var_count in var_counts {
- let mut singletons = vec![];
-
- for (var, count) in var_count {
- if count == 1 && !var.starts_with("_") && var.as_str() != "!" {
- singletons.push(var);
- }
- }
+ for (term, line_num, _col_num) in terms_and_locs {
+ let mut singletons = vec![];
+ let mut var_count = IndexMap::new();
+
+ for subterm in breadth_first_iter(&term, true) {
+ if let TermRef::Var(_, _, var) = subterm {
+ let entry = var_count.entry(var).or_insert(0);
+ *entry += 1;
+ }
+ }
+
+ for (var, count) in var_count {
+ if count == 1 && !var.starts_with("_") && var.as_str() != "!" {
+ singletons.push(var);
+ }
+ }
- if let Some(last_var) = singletons.pop() {
- print!("Warning: {}:{}: Singleton variables: [",
- module_name, line_num);
-
- for var in singletons {
- print!("{}, ", var);
- }
-
- println!("{}]", last_var);
- }
+ if let Some(last_var) = singletons.pop() {
+ print!("Warning: {}:{}: Singleton variables: [",
+ module_name, line_num);
+
+ for var in singletons {
+ print!("{}, ", var);
}
+
+ println!("{}]", last_var);
}
}
}
toplevel_results: Vec<PredicateCompileQueue>,
toplevel_indices: IndexStore,
addition_results: ExpansionAdditionResult,
+ top_level_terms: Vec<(Term, usize, usize)>
}
pub struct ClauseCodeGenerator {
compile_appendix(&mut decl_code, &queue, non_counted_bt, wam.machine_flags())?;
- if !self.suppress_warnings {
- issue_singleton_warnings(&decl, self.get_module_name());
- }
-
let idx = code_dir
.entry((name.clone(), arity))
.or_insert(CodeIndex::default());
toplevel_results,
toplevel_indices,
addition_results,
+ top_level_terms: worker.term_stream.top_level_terms(),
})
}
wam.run_init_code(init_goal_code);
}
+ if !compiler.suppress_warnings {
+ issue_singleton_warnings(compiler.get_module_name(), results.top_level_terms);
+ }
+
EvalSession::EntrySuccess
}
pub(crate) flags: MachineFlags,
term_expansion_lens: (usize, usize),
goal_expansion_lens: (usize, usize),
+ top_level_terms: Vec<(Term, usize, usize)> // term, line_num, col_num.
}
pub struct ExpansionAdditionResult {
parser: Parser::new(src, atom_tbl, flags),
in_module: false,
flags,
+ top_level_terms: vec![]
}
}
+ #[inline]
+ pub fn top_level_terms(&mut self) -> Vec<(Term, usize, usize)> {
+ mem::replace(&mut self.top_level_terms, vec![])
+ }
+
#[inline]
pub fn add_to_top(&mut self, buf: &str) {
self.parser.add_to_top(buf);
self.parser.reset();
+ let line_num = self.line_num();
+ let col_num = self.col_num();
+
let term = self.parser.read_term(composite_op!(
self.in_module,
&self.wam.indices.op_dir,
op_dir
))?;
+ // preserve a copy of the original unexpanded term for warning scans,
+ // if that stage is reached.
+ self.top_level_terms.push((term.clone(), line_num, col_num));
self.stack.push(term);
}
}