Revert "remove Term"

This reverts commit 3b5879841aedecba5057c70c71da0ba23e5cd84a.
This commit is contained in:
Mark Thom
2025-03-15 13:19:26 -07:00
committed by Mark Thom
parent eef7b06919
commit 9e1e99f961
53 changed files with 3726 additions and 4517 deletions

View File

@@ -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
}