add classifications and occurrence counting

This commit is contained in:
Mark Thom
2022-10-04 09:24:37 -06:00
committed by Mark
parent d565f5901b
commit b9c9de5222
15 changed files with 153 additions and 148 deletions

View File

@@ -8,7 +8,6 @@ use crate::machine::machine_indices::*;
use crate::targets::*;
use std::cell::Cell;
use std::rc::Rc;
pub(crate) trait Allocator {
fn new() -> Self;
@@ -30,7 +29,7 @@ pub(crate) trait Allocator {
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
&mut self,
var_name: Rc<String>,
var_name: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
term_loc: GenContext,
@@ -41,7 +40,7 @@ pub(crate) trait Allocator {
fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self,
var_name: Rc<String>,
var_name: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
context: GenContext,
@@ -88,17 +87,17 @@ pub(crate) trait Allocator {
perm_vs
}
fn get(&self, var: Rc<String>) -> RegType {
fn get(&self, var: Var) -> RegType {
self.bindings()
.get(&var)
.map_or(temp_v!(0), |v| v.as_reg_type())
}
fn is_unbound(&self, var: Rc<String>) -> bool {
fn is_unbound(&self, var: Var) -> bool {
self.get(var).reg_num() == 0
}
fn record_register(&mut self, var: Rc<String>, r: RegType) {
fn record_register(&mut self, var: Var, r: RegType) {
match self.bindings_mut().get_mut(&var).unwrap() {
&mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(),
&mut VarData::Perm(ref mut s) => *s = r.reg_num(),

View File

@@ -22,7 +22,6 @@ use std::convert::TryFrom;
use std::f64;
use std::num::FpCategory;
use std::ops::Div;
use std::rc::Rc;
use std::vec::Vec;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -74,7 +73,7 @@ impl<'a> ArithInstructionIterator<'a> {
2,
))
}
Term::Var(cell, var) => TermIterState::Var(Level::Shallow, cell, RcMutPtr::new(var)),
Term::Var(cell, var) => TermIterState::Var(Level::Shallow, cell, VarPtr::from(var)),
};
Ok(ArithInstructionIterator {
@@ -87,7 +86,7 @@ impl<'a> ArithInstructionIterator<'a> {
pub(crate) enum ArithTermRef<'a> {
Literal(&'a Literal),
Op(Atom, usize), // name, arity.
Var(Level, &'a Cell<VarReg>, Rc<String>),
Var(Level, &'a Cell<VarReg>, Var),
}
impl<'a> Iterator for ArithInstructionIterator<'a> {
@@ -115,8 +114,8 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
}
}
TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))),
TermIterState::Var(lvl, cell, var) => {
return Some(Ok(ArithTermRef::Var(lvl, cell, var.owned())));
TermIterState::Var(lvl, cell, var_ref) => {
return Some(Ok(ArithTermRef::Var(lvl, cell, Var::from(var_ref))));
}
_ => {
return Some(Err(ArithmeticError::NonEvaluableFunctor(
@@ -317,7 +316,7 @@ impl<'a> ArithmeticEvaluator<'a> {
ArithTermRef::Var(lvl, cell, name) => {
let r = if lvl == Level::Shallow {
self.marker.mark_non_callable(
name.clone(),
name,
arg,
term_loc,
cell,

View File

@@ -20,7 +20,6 @@ use indexmap::{IndexMap, IndexSet};
use std::cell::Cell;
use std::collections::VecDeque;
use std::rc::Rc;
#[derive(Debug)]
pub(crate) struct ConjunctInfo<'a> {
@@ -170,7 +169,7 @@ impl CodeGenSettings {
pub(crate) struct CodeGenerator<'a> {
pub(crate) atom_tbl: &'a mut AtomTable,
marker: DebrayAllocator,
pub(crate) var_count: IndexMap<Rc<String>, usize>,
pub(crate) var_count: IndexMap<Var, usize>,
settings: CodeGenSettings,
pub(crate) skeleton: PredicateSkeleton,
pub(crate) jmp_by_locs: Vec<usize>,
@@ -180,7 +179,7 @@ pub(crate) struct CodeGenerator<'a> {
impl DebrayAllocator {
fn mark_var_in_non_callable(
&mut self,
name: Rc<String>,
name: Var,
term_loc: GenContext,
vr: &Cell<VarReg>,
code: &mut Code,
@@ -190,7 +189,7 @@ impl DebrayAllocator {
}
#[inline(always)]
pub(crate) fn get_binding(&self, name: &String) -> Option<RegType> {
pub(crate) fn get_binding(&self, name: &Var) -> Option<RegType> {
match self.bindings().get(name) {
Some(&VarData::Temp(_, t, _)) if t != 0 => Some(RegType::Temp(t)),
Some(&VarData::Perm(p)) if p != 0 => Some(RegType::Perm(p)),
@@ -200,7 +199,7 @@ impl DebrayAllocator {
pub(crate) fn mark_non_callable(
&mut self,
name: Rc<String>,
name: Var,
arg: usize,
term_loc: GenContext,
vr: &Cell<VarReg>,
@@ -299,7 +298,7 @@ impl<'b> CodeGenerator<'b> {
}
}
fn get_var_count(&self, var: &String) -> usize {
fn get_var_count(&self, var: &Var) -> usize {
*self.var_count.get(var).unwrap()
}
@@ -320,7 +319,7 @@ impl<'b> CodeGenerator<'b> {
fn deep_var_instr<'a, Target: crate::targets::CompilationTarget<'a>>(
&mut self,
cell: &'a Cell<VarReg>,
var: &Rc<String>,
var: &Var,
term_loc: GenContext,
target: &mut Code,
) {
@@ -429,7 +428,7 @@ impl<'b> CodeGenerator<'b> {
self.marker.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
target.push(Target::to_pstr(lvl, atom, cell.get(), false));
}
TermRef::Var(lvl @ Level::Shallow, cell, ref var) if var.as_str() == "!" => {
TermRef::Var(lvl @ Level::Shallow, cell, var) if var.as_str() == Some("!") => {
if self.marker.is_unbound(var.clone()) {
if term_loc != GenContext::Head {
self.marker.mark_reserved_var::<Target>(
@@ -835,7 +834,7 @@ impl<'b> CodeGenerator<'b> {
#[inline]
fn compile_unblocked_cut(&mut self, code: &mut Code, cell: &Cell<VarReg>) {
let r = self.marker.get(Rc::new(String::from("!")));
let r = self.marker.get(Var::from("!"));
cell.set(VarReg::Norm(r));
code.push(instr!("$set_cp", cell.get().norm(), 0));
}
@@ -844,7 +843,7 @@ impl<'b> CodeGenerator<'b> {
&mut self,
code: &mut Code,
cell: &Cell<VarReg>,
var: Rc<String>,
var: Var,
term_loc: GenContext,
) {
let mut target = Code::new();

View File

@@ -14,28 +14,27 @@ use fxhash::FxBuildHasher;
use std::cell::Cell;
use std::collections::BTreeSet;
use std::rc::Rc;
#[derive(Debug)]
pub(crate) struct DebrayAllocator {
bindings: IndexMap<Rc<String>, VarData, FxBuildHasher>,
bindings: IndexMap<Var, VarData, FxBuildHasher>,
arg_c: usize,
temp_lb: usize,
arity: usize, // 0 if not at head.
contents: IndexMap<usize, Rc<String>, FxBuildHasher>,
contents: IndexMap<usize, Var, FxBuildHasher>,
in_use: BTreeSet<usize>,
free_list: Vec<usize>,
}
impl DebrayAllocator {
fn is_curr_arg_distinct_from(&self, var: &String) -> bool {
fn is_curr_arg_distinct_from(&self, var: &Var) -> bool {
match self.contents.get(&self.arg_c) {
Some(t_var) if **t_var != *var => true,
Some(t_var) if *t_var != *var => true,
_ => false,
}
}
fn occurs_shallowly_in_head(&self, var: &String, r: usize) -> bool {
fn occurs_shallowly_in_head(&self, var: &Var, r: usize) -> bool {
match self.bindings.get(var).unwrap() {
&VarData::Temp(_, _, ref tvd) => tvd.use_set.contains(&(GenContext::Head, r)),
_ => false,
@@ -48,7 +47,7 @@ impl DebrayAllocator {
in_use_range || self.in_use.contains(&r)
}
fn alloc_with_cr(&self, var: &String) -> usize {
fn alloc_with_cr(&self, var: &Var) -> usize {
match self.bindings.get(var) {
Some(&VarData::Temp(_, _, ref tvd)) => {
for &(_, reg) in tvd.use_set.iter() {
@@ -74,7 +73,7 @@ impl DebrayAllocator {
}
}
fn alloc_with_ca(&self, var: &String) -> usize {
fn alloc_with_ca(&self, var: &Var) -> usize {
match self.bindings.get(var) {
Some(&VarData::Temp(_, _, ref tvd)) => {
for &(_, reg) in tvd.use_set.iter() {
@@ -102,7 +101,7 @@ impl DebrayAllocator {
}
}
fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Rc<String>, usize)> {
fn alloc_in_last_goal_hint(&self, chunk_num: usize) -> Option<(Var, usize)> {
// we want to allocate a register to the k^{th} parameter, par_k.
// par_k may not be a temporary variable.
let k = self.arg_c;
@@ -154,7 +153,7 @@ impl DebrayAllocator {
fn alloc_reg_to_var<'a, Target: CompilationTarget<'a>>(
&mut self,
var: &String,
var: &Var,
lvl: Level,
term_loc: GenContext,
target: &mut Vec<Instruction>,
@@ -202,7 +201,7 @@ impl DebrayAllocator {
final_index
}
fn in_place(&self, var: &String, term_loc: GenContext, r: RegType, k: usize) -> bool {
fn in_place(&self, var: &Var, term_loc: GenContext, r: RegType, k: usize) -> bool {
match term_loc {
GenContext::Head if !r.is_perm() => r.reg_num() == k,
_ => match self.bindings().get(var).unwrap() {
@@ -293,7 +292,7 @@ impl Allocator for DebrayAllocator {
fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self,
var: Rc<String>,
var: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
term_loc: GenContext,
@@ -321,7 +320,7 @@ impl Allocator for DebrayAllocator {
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
&mut self,
var: Rc<String>,
var: Var,
lvl: Level,
cell: &'a Cell<VarReg>,
term_loc: GenContext,

View File

@@ -9,7 +9,6 @@ use indexmap::{IndexMap, IndexSet};
use std::cell::Cell;
use std::collections::BTreeSet;
use std::mem::swap;
use std::rc::Rc;
use std::vec::Vec;
// labeled with chunk numbers.
@@ -84,8 +83,8 @@ type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
#[derive(Debug)]
pub(crate) struct VariableFixtures<'a> {
perm_vars: IndexMap<Rc<String>, VariableFixture<'a>>,
last_chunk_temp_vars: IndexSet<Rc<String>>,
perm_vars: IndexMap<Var, VariableFixture<'a>>,
last_chunk_temp_vars: IndexSet<Var>,
}
impl<'a> VariableFixtures<'a> {
@@ -96,11 +95,11 @@ impl<'a> VariableFixtures<'a> {
}
}
pub(crate) fn insert(&mut self, var: Rc<String>, vs: VariableFixture<'a>) {
pub(crate) fn insert(&mut self, var: Var, vs: VariableFixture<'a>) {
self.perm_vars.insert(var, vs);
}
pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Rc<String>) {
pub(crate) fn insert_last_chunk_temp_var(&mut self, var: Var) {
self.last_chunk_temp_vars.insert(var);
}
@@ -115,7 +114,7 @@ impl<'a> VariableFixtures<'a> {
// Compute the conflict set of u.
// 1.
let mut use_sets: IndexMap<Rc<String>, OccurrenceSet> = IndexMap::new();
let mut use_sets: IndexMap<Var, OccurrenceSet> = IndexMap::new();
for (var, &mut (ref mut var_status, _)) in self.iter_mut() {
if let &mut VarStatus::Temp(_, ref mut var_data) = var_status {
@@ -132,7 +131,7 @@ impl<'a> VariableFixtures<'a> {
if let GenContext::Last(cn_u) = term_loc {
for (ref t, &mut (ref mut var_status, _)) in self.iter_mut() {
if let &mut VarStatus::Temp(cn_t, ref mut t_data) = var_status {
if cn_u == cn_t && *u != ***t {
if cn_u == cn_t && u != **t {
if !t_data.uses_reg(reg) {
t_data.no_use_set.insert(reg);
}
@@ -153,11 +152,11 @@ impl<'a> VariableFixtures<'a> {
}
}
fn get_mut(&mut self, u: Rc<String>) -> Option<&mut VariableFixture<'a>> {
fn get_mut(&mut self, u: Var) -> Option<&mut VariableFixture<'a>> {
self.perm_vars.get_mut(&u)
}
fn iter_mut(&mut self) -> indexmap::map::IterMut<Rc<String>, VariableFixture<'a>> {
fn iter_mut(&mut self) -> indexmap::map::IterMut<Var, VariableFixture<'a>> {
self.perm_vars.iter_mut()
}
@@ -218,11 +217,11 @@ impl<'a> VariableFixtures<'a> {
}
}
pub(crate) fn into_iter(self) -> indexmap::map::IntoIter<Rc<String>, VariableFixture<'a>> {
pub(crate) fn into_iter(self) -> indexmap::map::IntoIter<Var, VariableFixture<'a>> {
self.perm_vars.into_iter()
}
fn values(&self) -> indexmap::map::Values<Rc<String>, VariableFixture<'a>> {
fn values(&self) -> indexmap::map::Values<Var, VariableFixture<'a>> {
self.perm_vars.values()
}

View File

@@ -21,7 +21,6 @@ use std::convert::TryFrom;
use std::fmt;
use std::ops::AddAssign;
use std::path::PathBuf;
use std::rc::Rc;
use crate::{is_infix, is_postfix};
@@ -85,8 +84,8 @@ pub enum QueryTerm {
Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy),
BlockedCut, // a cut which is 'blocked by letters', like the P term in P -> Q.
UnblockedCut(Cell<VarReg>),
GetLevelAndUnify(Cell<VarReg>, Rc<String>),
Jump(JumpStub),
GetLevelAndUnify(Cell<VarReg>, Var),
Jump(JumpStub), // SOON: Branch(Vec<QueryTerm>),
}
impl QueryTerm {

View File

@@ -472,7 +472,7 @@ pub struct HCPrinter<'a, Outputter> {
state_stack: Vec<TokenOrRedirect>,
toplevel_spec: Option<DirectedOp>,
last_item_idx: usize,
pub var_names: IndexMap<HeapCellValue, Rc<String>>,
pub var_names: IndexMap<HeapCellValue, Var>,
pub numbervars_offset: Integer,
pub numbervars: bool,
pub quoted: bool,
@@ -803,7 +803,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
if let Some(var) = self.var_names.get(&addr) {
read_heap_cell!(addr,
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
return Some(format!("{}", var.as_str()));
return Some(var.to_string());
}
_ => {
self.iter.push_stack(h);
@@ -847,10 +847,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
// short-circuits handle_heap_term.
// self.iter.pop_stack();
let var_str = var.as_str();
let var_str = var.to_string();
push_space_if_amb!(self, var_str, {
append_str!(self, var_str);
push_space_if_amb!(self, &var_str, {
append_str!(self, &var_str);
});
None
@@ -862,8 +862,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
Some(var) => {
// If the term is bound to a named variable,
// print the variable's name to output.
push_space_if_amb!(self, &var, {
append_str!(self, &var);
let var_str = var.to_string();
push_space_if_amb!(self, &var_str, {
append_str!(self, &var_str);
});
}
None => {
@@ -1715,9 +1717,7 @@ mod tests {
heap_loc_as_cell!(0)
);
printer
.var_names
.insert(list_loc_as_cell!(1), Rc::new("L".to_string()));
printer.var_names.insert(list_loc_as_cell!(1), Var::from("L"));
let output = printer.print();
@@ -1778,9 +1778,7 @@ mod tests {
heap_loc_as_cell!(0)
);
printer
.var_names
.insert(list_loc_as_cell!(1), Rc::new("L".to_string()));
printer.var_names.insert(list_loc_as_cell!(1), Var::from("L"));
let output = printer.print();

View File

@@ -7,11 +7,40 @@ use std::cell::Cell;
use std::collections::VecDeque;
use std::fmt;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::hash::{Hash};
use std::iter::*;
use std::rc::Rc;
use std::vec::Vec;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) struct VarPtr {
ptr: std::ptr::NonNull<Var>,
}
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<VarPtr> for Var {
#[inline]
fn from(value: VarPtr) -> Var {
unsafe {
(*value.ptr.as_ptr()).clone()
}
}
}
impl VarPtr {
pub(crate) fn set(&mut self, value: Var) {
unsafe { *self.ptr.as_mut() = value; }
}
}
#[derive(Debug, Clone)]
pub(crate) enum TermRef<'a> {
AnonVar(Level),
@@ -20,7 +49,7 @@ pub(crate) enum TermRef<'a> {
Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>),
PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
CompleteString(Level, &'a Cell<RegType>, Atom),
Var(Level, &'a Cell<VarReg>, Rc<String>),
Var(Level, &'a Cell<VarReg>, Var),
}
impl<'a> TermRef<'a> {
@@ -37,58 +66,6 @@ impl<'a> TermRef<'a> {
}
}
#[derive(Clone, Debug)]
pub(crate) struct RcMutPtr<T: Debug> {
owned: Rc<T>,
ptr: *mut Rc<T>,
}
impl<T: Debug> RcMutPtr<T> {
#[inline]
pub(crate) fn new(rc: &Rc<T>) -> Self {
Self { owned: rc.clone(), ptr: rc as *const _ as *mut _ }
}
#[inline]
pub(crate) fn owned(&self) -> Rc<T> {
self.owned.clone()
}
#[inline]
pub(crate) fn set(&mut self, var_b_marker: &Rc<T>) {
self.owned = var_b_marker.clone();
unsafe {
if !self.ptr.is_null() {
*self.ptr = self.owned.clone();
}
}
}
}
impl<T: Debug> From<T> for RcMutPtr<T> {
#[inline]
fn from(value: T) -> RcMutPtr<T> {
let owned = Rc::new(value);
RcMutPtr { owned, ptr: std::ptr::null_mut() }
}
}
impl<T: Debug + PartialEq> PartialEq for RcMutPtr<T> {
fn eq(&self, rhs: &Self) -> bool {
&self.owned == &rhs.owned
}
}
impl<T: Debug + Eq> Eq for RcMutPtr<T> {}
impl<T: Debug + Hash> Hash for RcMutPtr<T> {
#[inline(always)]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.owned.hash(hasher)
}
}
#[derive(Debug)]
pub(crate) enum TermIterState<'a> {
AnonVar(Level),
@@ -99,7 +76,8 @@ pub(crate) enum TermIterState<'a> {
InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
FinalPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
CompleteString(Level, &'a Cell<RegType>, Atom),
Var(Level, &'a Cell<VarReg>, RcMutPtr<String>),
UnblockedCut(Level, &'a Cell<VarReg>),
Var(Level, &'a Cell<VarReg>, VarPtr),
}
impl<'a> TermIterState<'a> {
@@ -119,7 +97,7 @@ impl<'a> TermIterState<'a> {
Term::CompleteString(cell, atom) => {
TermIterState::CompleteString(lvl, cell, *atom)
}
Term::Var(cell, var) => TermIterState::Var(lvl, cell, RcMutPtr::new(var)),
Term::Var(cell, var) => TermIterState::Var(lvl, cell, VarPtr::from(var)),
}
}
}
@@ -160,7 +138,7 @@ impl<'a> QueryIterator<'a> {
*name,
terms,
),
Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, RcMutPtr::new(var)),
Term::Var(cell, var) => TermIterState::Var(Level::Root, cell, VarPtr::from(var)),
};
QueryIterator {
@@ -183,13 +161,14 @@ impl<'a> QueryIterator<'a> {
}
}
&QueryTerm::UnblockedCut(ref cell) => {
let state = TermIterState::Var(Level::Root, cell, RcMutPtr::from("!".to_string()));
let state = TermIterState::UnblockedCut(Level::Root, cell);
QueryIterator {
state_stack: vec![state],
}
}
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => {
let state = TermIterState::Var(Level::Root, cell, RcMutPtr::new(var));
let state = TermIterState::Var(Level::Root, cell, VarPtr::from(var));
QueryIterator {
state_stack: vec![state],
}
@@ -267,7 +246,10 @@ impl<'a> Iterator for QueryIterator<'a> {
return Some(TermRef::Literal(lvl, cell, constant));
}
TermIterState::Var(lvl, cell, var) => {
return Some(TermRef::Var(lvl, cell, var.owned()));
return Some(TermRef::Var(lvl, cell, Var::from(var)));
}
TermIterState::UnblockedCut(lvl, cell) => {
return Some(TermRef::Var(lvl, cell, Var::from("!")));
}
};
}
@@ -333,7 +315,7 @@ impl<'a> FactIterator<'a> {
vec![TermIterState::Literal(Level::Root, cell, constant)]
}
Term::Var(cell, var) => {
vec![TermIterState::Var(Level::Root, cell, RcMutPtr::new(var))]
vec![TermIterState::Var(Level::Root, cell, VarPtr::from(var))]
}
};
@@ -380,7 +362,7 @@ impl<'a> Iterator for FactIterator<'a> {
return Some(TermRef::Literal(lvl, cell, constant))
}
TermIterState::Var(lvl, cell, var) => {
return Some(TermRef::Var(lvl, cell, var.owned()));
return Some(TermRef::Var(lvl, cell, Var::from(var)));
}
_ => {}
}
@@ -420,7 +402,7 @@ impl<'a> ChunkedTerm<'a> {
fn contains_cut_var<'a, Iter: Iterator<Item = &'a Term>>(terms: Iter) -> bool {
for term in terms {
if let &Term::Var(_, ref var) = term {
if var.as_str() == "!" {
if var.as_str() == Some("!") {
return true;
}
}

View File

@@ -21,7 +21,6 @@ use std::convert::TryFrom;
use std::fmt;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
/*
* The loader compiles Prolog terms read from a TermStream instance,
@@ -1429,8 +1428,7 @@ impl MachineState {
}
}
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar, h) => {
let offset_string = format!("_{}", h);
term_stack.push(Term::Var(Cell::default(), Rc::new(offset_string)));
term_stack.push(Term::Var(Cell::default(), Var::Generated(h)));
}
(HeapCellValueTag::Cons | HeapCellValueTag::CStr | HeapCellValueTag::Fixnum |
HeapCellValueTag::Char | HeapCellValueTag::F64) => {

View File

@@ -16,7 +16,6 @@ use modular_bitfield::specifiers::*;
use std::cmp::Ordering;
use std::collections::BTreeSet;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use crate::types::*;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -228,8 +227,8 @@ impl CodeIndex {
}
}
pub(crate) type HeapVarDict = IndexMap<Rc<String>, HeapCellValue, FxBuildHasher>;
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData, FxBuildHasher>;
pub(crate) type HeapVarDict = IndexMap<Var, HeapCellValue, FxBuildHasher>;
pub(crate) type AllocVarDict = IndexMap<Var, VarData, FxBuildHasher>;
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), FxBuildHasher>;

View File

@@ -21,7 +21,6 @@ use indexmap::IndexMap;
use std::convert::TryFrom;
use std::fmt;
use std::ops::{Index, IndexMut};
use std::rc::Rc;
pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1];
@@ -501,13 +500,13 @@ impl MachineState {
pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
fn push_var_eq_functors<'a>(
heap: &mut Heap,
iter: impl Iterator<Item = (&'a Rc<String>, &'a HeapCellValue)>,
iter: impl Iterator<Item = (&'a Var, &'a HeapCellValue)>,
atom_tbl: &mut AtomTable,
) -> Vec<HeapCellValue> {
let mut list_of_var_eqs = vec![];
for (var, binding) in iter {
let var_atom = atom_tbl.build_with(&var);
let var_atom = atom_tbl.build_with(&var.to_string());
let h = heap.len();
heap.push(atom_as_cell!(atom!("="), 2));
@@ -673,7 +672,7 @@ impl MachineState {
let printer = match self.try_from_list(self.registers[6], stub_gen) {
Ok(addrs) => {
let mut var_names: IndexMap<HeapCellValue, Rc<String>> = IndexMap::new();
let mut var_names: IndexMap<HeapCellValue, Var> = IndexMap::new();
for addr in addrs {
read_heap_cell!(addr,
@@ -691,18 +690,18 @@ impl MachineState {
read_heap_cell!(atom,
(HeapCellValueTag::Char, c) => {
var_names.insert(var, Rc::new(c.to_string()));
var_names.insert(var, Var::from(c.to_string()));
}
(HeapCellValueTag::Atom, (name, _arity)) => {
debug_assert_eq!(_arity, 0);
var_names.insert(var, Rc::new(name.as_str().to_owned()));
var_names.insert(var, Var::from(name.as_str()));
}
(HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity();
debug_assert_eq!(arity, 0);
var_names.insert(var, Rc::new(name.as_str().to_owned()));
var_names.insert(var, Var::from(name.as_str()));
}
_ => {
unreachable!();

View File

@@ -12,7 +12,6 @@ use indexmap::IndexSet;
use std::cell::Cell;
use std::collections::VecDeque;
use std::convert::TryFrom;
use std::rc::Rc;
/*
* The preprocessor fabricates if-then-else ( .. -> ... ; ...)
@@ -373,7 +372,7 @@ fn mark_cut_variable(term: &mut Term) -> bool {
};
if cut_var_found {
*term = Term::Var(Cell::default(), Rc::new(String::from("!")));
*term = Term::Var(Cell::default(), Var::from("!"));
true
} else {
false
@@ -656,7 +655,7 @@ fn compute_head(term: &Term) -> Vec<Term> {
}
}
vars.insert(Rc::new(String::from("!")));
vars.insert(Var::from("!"));
vars.into_iter()
.map(|v| Term::Var(Cell::default(), v))
.collect()
@@ -767,7 +766,7 @@ impl Preprocessor {
}
}
Term::Literal(_, Literal::Char('!')) => Ok(QueryTerm::BlockedCut),
Term::Var(_, ref v) if v.as_str() == "!" => {
Term::Var(_, ref v) if v.as_str() == Some("!") => {
Ok(QueryTerm::UnblockedCut(Cell::default()))
}
Term::Clause(r, name, mut terms) => match (name, source_arity(&terms)) {

View File

@@ -51,7 +51,6 @@ use std::net::{TcpListener, TcpStream, SocketAddr, ToSocketAddrs};
use std::num::NonZeroU32;
use std::ops::Sub;
use std::process;
use std::rc::Rc;
use std::str::FromStr;
use std::sync::Arc;
@@ -1410,7 +1409,7 @@ impl Machine {
let vars: Vec<_> = vars
.union(&result.supp_vars) // difference + union does not cancel.
.map(|v| Term::Var(Cell::default(), Rc::new(format!("_{}", v.get_value()))))
.map(|v| Term::Var(Cell::default(), Var::Generated(v.get_value())))
.collect();
let helper_clause_loc = self.code.len();

View File

@@ -572,6 +572,44 @@ impl Literal {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Var {
Generated(usize),
Named(Rc<String>),
}
impl From<String> for Var {
#[inline(always)]
fn from(value: String) -> Var {
Var::Named(Rc::new(value))
}
}
impl From<&str> for Var {
#[inline(always)]
fn from(value: &str) -> Var {
Var::Named(Rc::new(value.to_owned()))
}
}
impl Var {
#[inline(always)]
pub fn as_str(&self) -> Option<&str> {
match self {
Var::Generated(_) => None,
Var::Named(value) => Some(&value),
}
}
#[inline(always)]
pub fn to_string(&self) -> String {
match self {
Var::Generated(n) => format!("_{}", n),
Var::Named(value) => value.to_string(),
}
}
}
#[derive(Debug, Clone)]
pub enum Term {
AnonVar,
@@ -582,7 +620,7 @@ pub enum Term {
// other PartialString variants in as_partial_string.
PartialString(Cell<RegType>, String, Box<Term>),
CompleteString(Cell<RegType>, Atom),
Var(Cell<VarReg>, Rc<String>),
Var(Cell<VarReg>, Var),
}
impl Term {

View File

@@ -8,7 +8,6 @@ use crate::parser::rug::ops::NegAssign;
use std::cell::Cell;
use std::mem;
use std::rc::Rc;
#[derive(Debug, Clone, Copy, PartialEq)]
enum TokenType {
@@ -427,7 +426,7 @@ impl<'a, R: CharRead> Parser<'a, R> {
if v.trim() == "_" {
self.terms.push(Term::AnonVar);
} else {
self.terms.push(Term::Var(Cell::default(), Rc::new(v)));
self.terms.push(Term::Var(Cell::default(), Var::from(v)));
}
TokenType::Term