Revert "remove Term"
This reverts commit 3b5879841aedecba5057c70c71da0ba23e5cd84a.
This commit is contained in:
250
src/forms.rs
250
src/forms.rs
@@ -3,8 +3,7 @@ use crate::atom_table::*;
|
||||
use crate::functor_macro::*;
|
||||
use crate::instructions::*;
|
||||
use crate::machine::disjuncts::VarData;
|
||||
use crate::machine::heap::*;
|
||||
// use crate::machine::loader::PredicateQueue;
|
||||
use crate::machine::loader::PredicateQueue;
|
||||
use crate::machine::machine_errors::*;
|
||||
use crate::machine::machine_indices::*;
|
||||
use crate::parser::ast::*;
|
||||
@@ -18,6 +17,7 @@ use fxhash::FxBuildHasher;
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use ordered_float::OrderedFloat;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
@@ -55,6 +55,15 @@ pub enum Level {
|
||||
Shallow,
|
||||
}
|
||||
|
||||
impl Level {
|
||||
pub(crate) fn child_level(self) -> Level {
|
||||
match self {
|
||||
Level::Root => Level::Shallow,
|
||||
_ => Level::Deep,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum CallPolicy {
|
||||
Default,
|
||||
@@ -77,15 +86,6 @@ impl GenContext {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn chunk_type(&self) -> ChunkType {
|
||||
match self {
|
||||
GenContext::Head => ChunkType::Head,
|
||||
GenContext::Mid(_) => ChunkType::Mid,
|
||||
GenContext::Last(_) => ChunkType::Last,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_last(self) -> bool {
|
||||
matches!(self, GenContext::Last(_))
|
||||
@@ -99,6 +99,19 @@ pub enum ChunkType {
|
||||
Last,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RootIterationPolicy {
|
||||
Iterated,
|
||||
NotIterated,
|
||||
}
|
||||
|
||||
impl RootIterationPolicy {
|
||||
#[inline(always)]
|
||||
pub fn iterable(&self) -> bool {
|
||||
matches!(self, RootIterationPolicy::Iterated)
|
||||
}
|
||||
}
|
||||
|
||||
impl ChunkType {
|
||||
#[inline(always)]
|
||||
pub fn to_gen_context(self, chunk_num: usize) -> GenContext {
|
||||
@@ -118,17 +131,12 @@ impl ChunkType {
|
||||
#[derive(Debug)]
|
||||
pub enum ChunkedTerms {
|
||||
Branch(Vec<VecDeque<ChunkedTerms>>),
|
||||
Chunk {
|
||||
chunk_num: usize,
|
||||
terms: VecDeque<QueryTerm>,
|
||||
},
|
||||
Chunk { terms: VecDeque<QueryTerm> },
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ChunkedTermVec {
|
||||
pub chunk_vec: VecDeque<ChunkedTerms>,
|
||||
pub current_chunk_num: usize,
|
||||
pub current_chunk_type: ChunkType,
|
||||
}
|
||||
|
||||
impl Deref for ChunkedTermVec {
|
||||
@@ -153,8 +161,6 @@ impl ChunkedTermVec {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
chunk_vec: VecDeque::new(),
|
||||
current_chunk_num: 0,
|
||||
current_chunk_type: ChunkType::Mid,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,45 +169,18 @@ impl ChunkedTermVec {
|
||||
.push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity)));
|
||||
}
|
||||
|
||||
pub fn try_set_chunk_at_inlined_boundary(&mut self) -> bool {
|
||||
if self.current_chunk_type.is_last() {
|
||||
self.current_chunk_type = ChunkType::Mid;
|
||||
self.current_chunk_num += 1;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_set_chunk_at_call_boundary(&mut self) -> bool {
|
||||
if self.current_chunk_type.is_last() {
|
||||
self.current_chunk_num += 1;
|
||||
true
|
||||
} else {
|
||||
self.current_chunk_type = ChunkType::Last;
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_chunk(&mut self) {
|
||||
let chunk = ChunkedTerms::Chunk {
|
||||
chunk_num: self.current_chunk_num,
|
||||
terms: VecDeque::from(vec![]),
|
||||
};
|
||||
self.chunk_vec.push_back(chunk);
|
||||
}
|
||||
|
||||
pub fn current_gen_context(&self) -> GenContext {
|
||||
self.current_chunk_type
|
||||
.to_gen_context(self.current_chunk_num)
|
||||
}
|
||||
|
||||
pub fn push_chunk_term(&mut self, term: QueryTerm) {
|
||||
match self.chunk_vec.back_mut() {
|
||||
Some(ChunkedTerms::Branch(_)) => {
|
||||
let chunk = ChunkedTerms::Chunk {
|
||||
chunk_num: self.current_chunk_num,
|
||||
terms: VecDeque::from(vec![term]),
|
||||
};
|
||||
|
||||
@@ -212,7 +191,6 @@ impl ChunkedTermVec {
|
||||
}
|
||||
None => {
|
||||
let chunk = ChunkedTerms::Chunk {
|
||||
chunk_num: self.current_chunk_num,
|
||||
terms: VecDeque::from(vec![term]),
|
||||
};
|
||||
|
||||
@@ -222,39 +200,35 @@ impl ChunkedTermVec {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct QueryClause {
|
||||
pub ct: ClauseType,
|
||||
pub term: HeapCellValue,
|
||||
pub code_indices: IndexMap<usize, CodeIndex, FxBuildHasher>,
|
||||
pub call_policy: CallPolicy,
|
||||
}
|
||||
|
||||
impl QueryClause {
|
||||
pub fn term_loc(&self) -> usize {
|
||||
self.term.get_value() as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum QueryTerm {
|
||||
Clause(QueryClause),
|
||||
// register, clause type, subterms, clause call policy.
|
||||
Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy),
|
||||
Fail,
|
||||
Succeed,
|
||||
LocalCut { var_num: usize, cut_prev: bool },
|
||||
GlobalCut(usize), // var_num
|
||||
LocalCut { var_num: usize, cut_prev: bool }, // var_num
|
||||
GlobalCut(usize), // var_num
|
||||
GetCutPoint { var_num: usize, prev_b: bool },
|
||||
GetLevel(usize), // var_num
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
impl QueryTerm {
|
||||
pub(crate) fn arity(&self) -> usize {
|
||||
match self {
|
||||
QueryTerm::Clause(_, _, subterms, ..) => subterms.len(),
|
||||
&QueryTerm::GetLevel(_) | &QueryTerm::GetCutPoint { .. } => 1,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Fact {
|
||||
pub(crate) term_loc: usize,
|
||||
pub(crate) head: Term,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Rule {
|
||||
pub(crate) term_loc: usize,
|
||||
pub(crate) head: (Atom, Vec<Term>),
|
||||
pub(crate) clauses: ChunkedTermVec,
|
||||
}
|
||||
|
||||
@@ -271,32 +245,90 @@ impl ListingSource {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clause_predicate_key_from_heap(
|
||||
heap: &impl SizedHeap,
|
||||
value: HeapCellValue,
|
||||
) -> Option<PredicateKey> {
|
||||
read_heap_cell!(value,
|
||||
(HeapCellValueTag::Atom, (name, _arity)) => {
|
||||
debug_assert_eq!(_arity, 0);
|
||||
Some((name, 0))
|
||||
}
|
||||
_ => {
|
||||
if value.is_ref() {
|
||||
clause_predicate_key(heap, value.get_value() as usize)
|
||||
} else {
|
||||
None
|
||||
pub trait ClauseInfo {
|
||||
fn is_consistent(&self, clauses: &PredicateQueue) -> bool {
|
||||
match clauses.first() {
|
||||
Some(cl) => {
|
||||
self.name() == ClauseInfo::name(cl) && self.arity() == ClauseInfo::arity(cl)
|
||||
}
|
||||
None => true,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fn name(&self) -> Option<Atom>;
|
||||
fn arity(&self) -> usize;
|
||||
}
|
||||
|
||||
pub fn clause_predicate_key(heap: &impl SizedHeap, term_loc: usize) -> Option<PredicateKey> {
|
||||
let key_opt = term_predicate_key(heap, term_loc);
|
||||
impl ClauseInfo for PredicateKey {
|
||||
#[inline]
|
||||
fn name(&self) -> Option<Atom> {
|
||||
Some(self.0)
|
||||
}
|
||||
|
||||
if Some((atom!(":-"), 2)) == key_opt {
|
||||
term_nth_arg(heap, term_loc, 1).and_then(|arg_loc| term_predicate_key(heap, arg_loc))
|
||||
} else {
|
||||
key_opt
|
||||
#[inline]
|
||||
fn arity(&self) -> usize {
|
||||
self.1
|
||||
}
|
||||
}
|
||||
|
||||
impl ClauseInfo for Term {
|
||||
fn name(&self) -> Option<Atom> {
|
||||
match self {
|
||||
Term::Clause(_, name, terms) => {
|
||||
match name {
|
||||
atom!(":-") => {
|
||||
match terms.len() {
|
||||
1 => None, // a declaration.
|
||||
2 => terms[0].name(),
|
||||
_ => Some(*name),
|
||||
}
|
||||
}
|
||||
_ => Some(*name), //str_buf),
|
||||
}
|
||||
}
|
||||
Term::Literal(_, Literal::Atom(name)) => Some(*name),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
match self {
|
||||
Term::Clause(_, name, terms) => match &*name.as_str() {
|
||||
":-" => match terms.len() {
|
||||
1 => 0,
|
||||
2 => terms[0].arity(),
|
||||
_ => terms.len(),
|
||||
},
|
||||
_ => terms.len(),
|
||||
},
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClauseInfo for Rule {
|
||||
fn name(&self) -> Option<Atom> {
|
||||
Some(self.head.0)
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
self.head.1.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClauseInfo for PredicateClause {
|
||||
fn name(&self) -> Option<Atom> {
|
||||
match self {
|
||||
PredicateClause::Fact(ref term, ..) => term.head.name(),
|
||||
PredicateClause::Rule(ref rule, ..) => rule.name(),
|
||||
}
|
||||
}
|
||||
|
||||
fn arity(&self) -> usize {
|
||||
match self {
|
||||
PredicateClause::Fact(ref term, ..) => term.head.arity(),
|
||||
PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,26 +339,20 @@ pub enum PredicateClause {
|
||||
}
|
||||
|
||||
impl PredicateClause {
|
||||
pub(crate) fn args<'a>(&self, heap: &'a Heap) -> Option<std::ops::RangeInclusive<usize>> {
|
||||
let focus = match self {
|
||||
&PredicateClause::Fact(Fact { term_loc }, _) => term_loc,
|
||||
&PredicateClause::Rule(Rule { term_loc, .. }, _) => {
|
||||
term_nth_arg(heap, term_loc, 1).unwrap()
|
||||
pub(crate) fn args(&self) -> Option<&[Term]> {
|
||||
match self {
|
||||
PredicateClause::Fact(term, ..) => match &term.head {
|
||||
Term::Clause(_, _, args) => Some(args),
|
||||
_ => None,
|
||||
},
|
||||
PredicateClause::Rule(rule, ..) => {
|
||||
if rule.head.1.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(&rule.head.1)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let arity = clause_predicate_key(heap, focus)
|
||||
.map(|(_name, arity)| arity)
|
||||
.unwrap_or(0);
|
||||
|
||||
read_heap_cell!(heap_bound_store(heap, heap_bound_deref(heap, heap[focus])),
|
||||
(HeapCellValueTag::Str, s) => {
|
||||
Some(s+1 ..= s+arity)
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,7 +725,7 @@ impl ArenaFrom<Number> for Literal {
|
||||
impl ArenaFrom<u64> for HeapCellValue {
|
||||
#[inline]
|
||||
fn arena_from(value: u64, arena: &mut Arena) -> HeapCellValue {
|
||||
fixnum!(value as i64, arena)
|
||||
HeapCellValue::from(fixnum!(Literal, value as i64, arena))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -779,10 +805,10 @@ impl Number {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) enum OptArgIndexKey {
|
||||
Literal(usize, usize, HeapCellValue, Vec<HeapCellValue>), // index, IndexingCode location, opt arg, alternatives
|
||||
List(usize, usize), // index, IndexingCode location
|
||||
Literal(usize, usize, Literal, Option<Literal>), // index, IndexingCode location, opt arg, alternatives
|
||||
List(usize, usize), // index, IndexingCode location
|
||||
None,
|
||||
Structure(usize, usize, Atom, usize), // index, IndexingCode location, name, arity
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user