use crate::atom_table::*; use crate::forms::*; use crate::instructions::*; use crate::parser::ast::*; use std::cell::Cell; use std::collections::VecDeque; use std::fmt; use std::fmt::Debug; use std::hash::{Hash}; use std::iter::*; use std::vec::Vec; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub(crate) enum VarPtr { ToVar(std::ptr::NonNull), InSitu(usize), } impl From<&Var> for VarPtr { #[inline] fn from(value: &Var) -> VarPtr { unsafe { VarPtr { ptr: std::ptr::NonNull::new_unchecked(value as *const _ as *mut _) } } } } impl From for Var { #[inline(always)] fn from(value: VarPtr) -> Var { match value { VarPtr::ToPtr(ptr) => unsafe { (*ptr.ptr.as_ptr()).clone() }, VarPtr::InSitu(var_num) => { Var::Generated(var_num) } } } } impl VarPtr { pub(crate) fn set(&mut self, value: Var) { match self { VarPtr::ToVar(ref mut ptr) => unsafe { *ptr.as_mut() = value }, VarPtr::InSitu(_) => { } } } } #[derive(Debug, Clone)] pub(crate) enum TermRef<'a> { AnonVar(Level), Cut(Level), GetLevel(Level), Cons(Level, &'a Cell, &'a Term, &'a Term), Fail(Level), Literal(Level, &'a Cell, &'a Literal), Clause(Level, &'a Cell, Atom, &'a Vec), PartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), Var(Level, &'a Cell, Var), InitialBranch(Level), MiddleBranch(Level), FinalBranch(Level), } impl<'a> TermRef<'a> { pub(crate) fn level(self) -> Level { match self { TermRef::AnonVar(lvl) | TermRef::Cons(lvl, ..) | TermRef::Cut(lvl) | TermRef::GetLevel(lvl) | TermRef::Literal(lvl, ..) | TermRef::Var(lvl, ..) | TermRef::Clause(lvl, ..) | TermRef::CompleteString(lvl, ..) | TermRef::PartialString(lvl, ..) | TermRef::InitialBranch(lvl) | TermRef::MiddleBranch(lvl) | TermRef::FinalBranch(lvl) | TermRef::Fail(lvl) => lvl, } } } #[derive(Debug)] pub(crate) enum TermIterState<'a> { AnonVar(Level), Clause(Level, usize, &'a Cell, Atom, &'a Vec), Cut(Level), Fail(Level), GetLevel(Level), InitialBranch(Level, &'a Vec), MiddleBranch(Level, &'a Vec), FinalBranch(Level, &'a Vec), Sequence(Level, &'a Vec), Literal(Level, &'a Cell, &'a Literal), InitialCons(Level, &'a Cell, &'a Term, &'a Term), FinalCons(Level, &'a Cell, &'a Term, &'a Term), InitialPartialString(Level, &'a Cell, &'a String, &'a Box), FinalPartialString(Level, &'a Cell, &'a String, &'a Box), CompleteString(Level, &'a Cell, Atom), Var(Level, &'a Cell, VarPtr), } impl<'a> TermIterState<'a> { pub(crate) fn subterm_to_state(lvl: Level, term: &'a Term) -> TermIterState<'a> { match term { Term::AnonVar => TermIterState::AnonVar(lvl), Term::Clause(cell, name, subterms) => { TermIterState::Clause(lvl, 0, cell, *name, subterms) } Term::Cons(cell, head, tail) => { TermIterState::InitialCons(lvl, cell, head.as_ref(), tail.as_ref()) } Term::Literal(cell, constant) => TermIterState::Literal(lvl, cell, constant), Term::PartialString(cell, string_buf, tail) => { TermIterState::InitialPartialString(lvl, cell, string_buf, tail) } Term::CompleteString(cell, atom) => { TermIterState::CompleteString(lvl, cell, *atom) } Term::Var(cell, var) => TermIterState::Var(lvl, cell, VarPtr::from(var)), } } } #[derive(Debug)] pub(crate) struct QueryIterator<'a> { state_stack: Vec>, } impl<'a> QueryIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { self.state_stack.push(TermIterState::subterm_to_state(lvl, term)); } fn from_rule_head_clause(terms: &'a Vec) -> Self { let state_stack = terms .iter() .rev() .map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt)) .collect(); QueryIterator { state_stack } } fn from_term(term: &'a Term) -> Self { let state = match term { Term::AnonVar | Term::Cons(..) | Term::Literal(..) | Term::PartialString(..) | Term::CompleteString(..) => { return QueryIterator { state_stack: vec![], } } Term::Clause(r, name, terms) => TermIterState::Clause( Level::Root, 0, r, *name, terms, ), Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, VarPtr::from(var)), }; QueryIterator { state_stack: vec![state], } } fn extend_state(&mut self, lvl: Level, term: &'a QueryTerm) { match term { &QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => { self.state_stack.push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms)); } &QueryTerm::Clause(ref cell, ref ct, ref terms, _) => { self.state_stack.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms)); } &QueryTerm::Cut => { self.state_stack.push(TermIterState::Cut(lvl)); } &QueryTerm::Not(ref terms) => { self.state_stack.push(TermIterState::Fail(lvl)); self.state_stack.push(TermIterState::Cut(lvl)); self.state_stack.push(TermIterState::Sequence(lvl, terms)); } &QueryTerm::IfThen(ref if_terms, ref then_terms) => { self.state_stack.push(TermIterState::Sequence(lvl, then_terms)); self.state_stack.push(TermIterState::Cut(lvl)); self.state_stack.push(TermIterState::Sequence(lvl, if_terms)); self.state_stack.push(TermIterState::GetLevel(lvl)); } &QueryTerm::Branch(ref branches) => { let len = branches.len(); self.state_stack.push(TermIterState::FinalBranch(lvl, &branches[len - 1])); self.state_stack.extend(branches[1 .. len - 1] .iter() .rev() .map(|t| TermIterState::MiddleBranch(lvl, t)), ); self.state_stack.push(TermIterState::InitialBranch(lvl, &branches[0])); } } } fn new(term: &'a QueryTerm) -> Self { let mut iter = QueryIterator { state_stack: vec![] }; iter.extend_state(Level::Root, term); iter } } impl<'a> Iterator for QueryIterator<'a> { type Item = TermRef<'a>; fn next(&mut self) -> Option { while let Some(iter_state) = self.state_stack.pop() { match iter_state { TermIterState::AnonVar(lvl) => { return Some(TermRef::AnonVar(lvl)); } TermIterState::Clause(lvl, child_num, cell, name, child_terms) => { if child_num == child_terms.len() { match name { atom!("$call") if lvl == Level::Root => { self.push_subterm(Level::Shallow, &child_terms[0]); } _ => { return match lvl { Level::Root => None, lvl => Some(TermRef::Clause(lvl, cell, name, child_terms)), } } }; } else { self.state_stack.push(TermIterState::Clause( lvl, child_num + 1, cell, name, child_terms, )); self.push_subterm(lvl.child_level(), &child_terms[child_num]); } } TermIterState::InitialCons(lvl, cell, head, tail) => { self.state_stack.push(TermIterState::FinalCons(lvl, cell, head, tail)); self.push_subterm(lvl.child_level(), tail); self.push_subterm(lvl.child_level(), head); } TermIterState::InitialPartialString(lvl, cell, string, tail) => { self.state_stack.push(TermIterState::FinalPartialString(lvl, cell, string, tail)); self.push_subterm(lvl.child_level(), tail); } TermIterState::FinalPartialString(lvl, cell, atom, tail) => { return Some(TermRef::PartialString(lvl, cell, atom, tail)); } TermIterState::CompleteString(lvl, cell, atom) => { return Some(TermRef::CompleteString(lvl, cell, atom)); } TermIterState::FinalCons(lvl, cell, head, tail) => { return Some(TermRef::Cons(lvl, cell, head, tail)); } TermIterState::Literal(lvl, cell, constant) => { return Some(TermRef::Literal(lvl, cell, constant)); } TermIterState::Var(lvl, cell, var) => { return Some(TermRef::Var(lvl, cell, Var::from(var))); } TermIterState::Cut(lvl) => { return Some(TermRef::Cut(lvl)); } TermIterState::GetLevel(lvl) => { return Some(TermRef::GetLevel(lvl)); } TermIterState::InitialBranch(lvl, ref branch) => { self.state_stack.push(TermIterState::Sequence(lvl, branch)); return Some(TermRef::InitialBranch(lvl)); } TermIterState::MiddleBranch(lvl, ref branch) => { self.state_stack.push(TermIterState::Sequence(lvl, branch)); return Some(TermRef::MiddleBranch(lvl)); } TermIterState::FinalBranch(lvl, ref branch) => { self.state_stack.push(TermIterState::Sequence(lvl, branch)); return Some(TermRef::FinalBranch(lvl)); } TermIterState::Sequence(lvl, ref terms) => { for term in branch.iter().rev() { self.extend_state(lvl, term); } } TermIterState::Fail(lvl) => { return Some(TermRef::Fail(lvl)); } }; } None } } #[derive(Debug)] pub(crate) struct FactIterator<'a> { state_queue: VecDeque>, iterable_root: bool, } impl<'a> FactIterator<'a> { fn push_subterm(&mut self, lvl: Level, term: &'a Term) { self.state_queue .push_back(TermIterState::subterm_to_state(lvl, term)); } pub(crate) fn from_rule_head_clause(terms: &'a Vec) -> Self { let state_queue = terms .iter() .map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt)) .collect(); FactIterator { state_queue, iterable_root: false, } } fn new(term: &'a Term, iterable_root: bool) -> Self { let states = match term { Term::AnonVar => { vec![TermIterState::AnonVar(Level::Root)] } Term::Clause(cell, name, terms) => { vec![TermIterState::Clause(Level::Root, 0, cell, *name, terms)] } Term::Cons(cell, head, tail) => vec![TermIterState::InitialCons( Level::Root, cell, head.as_ref(), tail.as_ref(), )], Term::PartialString(cell, string_buf, tail) => { vec![TermIterState::InitialPartialString( Level::Root, cell, string_buf, tail, )] } Term::CompleteString(cell, atom) => { vec![TermIterState::CompleteString( Level::Root, cell, *atom, )] } Term::Literal(cell, constant) => { vec![TermIterState::Literal(Level::Root, cell, constant)] } Term::Var(cell, var) => { vec![TermIterState::Var(Level::Root, cell, VarPtr::from(var))] } }; FactIterator { state_queue: VecDeque::from(states), iterable_root, } } } impl<'a> Iterator for FactIterator<'a> { type Item = TermRef<'a>; fn next(&mut self) -> Option { while let Some(state) = self.state_queue.pop_front() { match state { TermIterState::AnonVar(lvl) => { return Some(TermRef::AnonVar(lvl)); } TermIterState::Clause(lvl, _, cell, name, child_terms) => { for child_term in child_terms { self.push_subterm(lvl.child_level(), child_term); } match lvl { Level::Root if !self.iterable_root => continue, _ => return Some(TermRef::Clause(lvl, cell, name, child_terms)), }; } TermIterState::InitialCons(lvl, cell, head, tail) => { self.push_subterm(Level::Deep, head); self.push_subterm(Level::Deep, tail); return Some(TermRef::Cons(lvl, cell, head, tail)); } TermIterState::InitialPartialString(lvl, cell, string_buf, tail) => { self.push_subterm(Level::Deep, tail); return Some(TermRef::PartialString(lvl, cell, string_buf, tail)); } TermIterState::CompleteString(lvl, cell, atom) => { return Some(TermRef::CompleteString(lvl, cell, atom)); } TermIterState::Literal(lvl, cell, constant) => { return Some(TermRef::Literal(lvl, cell, constant)) } TermIterState::Var(lvl, cell, var) => { return Some(TermRef::Var(lvl, cell, Var::from(var))); } _ => {} } } None } } pub(crate) fn post_order_iter<'a>(term: &'a Term) -> QueryIterator<'a> { QueryIterator::from_term(term) } pub(crate) fn breadth_first_iter<'a>(term: &'a Term, iterable_root: bool) -> FactIterator<'a> { FactIterator::new(term, iterable_root) } /* #[derive(Debug)] pub(crate) enum ChunkedTerm<'a> { HeadClause(Atom, &'a Vec), BodyTerm(&'a QueryTerm), } pub(crate) fn query_term_post_order_iter<'a>(query_term: &'a QueryTerm) -> QueryIterator<'a> { QueryIterator::new(query_term) } impl<'a> ChunkedTerm<'a> { pub(crate) fn post_order_iter(&self) -> QueryIterator<'a> { match self { &ChunkedTerm::BodyTerm(qt) => QueryIterator::new(qt), &ChunkedTerm::HeadClause(_, terms) => QueryIterator::from_rule_head_clause(terms), } } } pub(crate) struct ChunkedIterator<'a> { pub(crate) chunk_num: usize, iter: Box> + 'a>, } impl<'a> fmt::Debug for ChunkedIterator<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.debug_struct("ChunkedIterator") .field("chunk_num", &self.chunk_num) // Hacky solution. .field("iter", &"Box> + 'a>") .finish() } } type ChunkedIteratorItem<'a> = (usize, usize, Vec>); type RuleBodyIteratorItem<'a> = (usize, usize, Vec<&'a QueryTerm>); impl<'a> ChunkedIterator<'a> { pub(crate) fn rule_body_iter(self) -> Box> + 'a> { Box::new(self.filter_map(|(cn, lt_arity, terms)| { let filtered_terms: Vec<_> = terms .into_iter() .filter_map(|ct| match ct { ChunkedTerm::BodyTerm(qt) => Some(qt), _ => None, }) .collect(); if filtered_terms.is_empty() { None } else { Some((cn, lt_arity, filtered_terms)) } })) } pub(crate) fn from_rule_body(p1: &'a QueryTerm, clauses: &'a Vec) -> Self { let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); let iter = inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t))); ChunkedIterator { chunk_num: 0, iter: Box::new(iter), } } pub(crate) fn from_rule(rule: &'a Rule) -> Self { let &Rule { head: (ref name, ref args, ref p1), ref clauses, .. } = rule; let iter = once(ChunkedTerm::HeadClause(name.clone(), args)); let inner_iter = Box::new(once(ChunkedTerm::BodyTerm(p1))); let iter = iter.chain(inner_iter.chain(clauses.iter().map(|t| ChunkedTerm::BodyTerm(t)))); ChunkedIterator { chunk_num: 0, iter: Box::new(iter), } } fn take_chunk(&mut self, term: ChunkedTerm<'a>) -> (usize, usize, Vec>) { let mut arity = 0; let mut item = Some(term); let mut result = Vec::new(); while let Some(term) = item { match term { ChunkedTerm::HeadClause(_, terms) => { result.push(term); } ChunkedTerm::BodyTerm(&QueryTerm::Cut) => { result.push(term); } ChunkedTerm::BodyTerm(&QueryTerm::Clause(_, ClauseType::Inlined(_), ..)) => { result.push(term); } ChunkedTerm::BodyTerm(&QueryTerm::Clause( _, ClauseType::CallN(_), ref subterms, _, )) => { result.push(term); arity = subterms.len() + 1; break; } ChunkedTerm::BodyTerm(qt) => { result.push(term); arity = qt.arity(); break; } }; item = self.iter.next(); } let chunk_num = self.chunk_num; self.chunk_num += 1; (chunk_num, arity, result) } } impl<'a> Iterator for ChunkedIterator<'a> { // the chunk number, last term arity, and vector of references. type Item = ChunkedIteratorItem<'a>; fn next(&mut self) -> Option { self.iter.next().map(|term| self.take_chunk(term)) } } */