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 crate::targets::*;
use std::cell::Cell; use std::cell::Cell;
use std::rc::Rc;
pub(crate) trait Allocator { pub(crate) trait Allocator {
fn new() -> Self; fn new() -> Self;
@@ -30,7 +29,7 @@ pub(crate) trait Allocator {
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>( fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
&mut self, &mut self,
var_name: Rc<String>, var_name: Var,
lvl: Level, lvl: Level,
cell: &'a Cell<VarReg>, cell: &'a Cell<VarReg>,
term_loc: GenContext, term_loc: GenContext,
@@ -41,7 +40,7 @@ pub(crate) trait Allocator {
fn mark_var<'a, Target: CompilationTarget<'a>>( fn mark_var<'a, Target: CompilationTarget<'a>>(
&mut self, &mut self,
var_name: Rc<String>, var_name: Var,
lvl: Level, lvl: Level,
cell: &'a Cell<VarReg>, cell: &'a Cell<VarReg>,
context: GenContext, context: GenContext,
@@ -88,17 +87,17 @@ pub(crate) trait Allocator {
perm_vs perm_vs
} }
fn get(&self, var: Rc<String>) -> RegType { fn get(&self, var: Var) -> RegType {
self.bindings() self.bindings()
.get(&var) .get(&var)
.map_or(temp_v!(0), |v| v.as_reg_type()) .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 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() { match self.bindings_mut().get_mut(&var).unwrap() {
&mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(), &mut VarData::Temp(_, ref mut s, _) => *s = r.reg_num(),
&mut VarData::Perm(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::f64;
use std::num::FpCategory; use std::num::FpCategory;
use std::ops::Div; use std::ops::Div;
use std::rc::Rc;
use std::vec::Vec; use std::vec::Vec;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -74,7 +73,7 @@ impl<'a> ArithInstructionIterator<'a> {
2, 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 { Ok(ArithInstructionIterator {
@@ -87,7 +86,7 @@ impl<'a> ArithInstructionIterator<'a> {
pub(crate) enum ArithTermRef<'a> { pub(crate) enum ArithTermRef<'a> {
Literal(&'a Literal), Literal(&'a Literal),
Op(Atom, usize), // name, arity. Op(Atom, usize), // name, arity.
Var(Level, &'a Cell<VarReg>, Rc<String>), Var(Level, &'a Cell<VarReg>, Var),
} }
impl<'a> Iterator for ArithInstructionIterator<'a> { 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::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(c))),
TermIterState::Var(lvl, cell, var) => { TermIterState::Var(lvl, cell, var_ref) => {
return Some(Ok(ArithTermRef::Var(lvl, cell, var.owned()))); return Some(Ok(ArithTermRef::Var(lvl, cell, Var::from(var_ref))));
} }
_ => { _ => {
return Some(Err(ArithmeticError::NonEvaluableFunctor( return Some(Err(ArithmeticError::NonEvaluableFunctor(
@@ -317,7 +316,7 @@ impl<'a> ArithmeticEvaluator<'a> {
ArithTermRef::Var(lvl, cell, name) => { ArithTermRef::Var(lvl, cell, name) => {
let r = if lvl == Level::Shallow { let r = if lvl == Level::Shallow {
self.marker.mark_non_callable( self.marker.mark_non_callable(
name.clone(), name,
arg, arg,
term_loc, term_loc,
cell, cell,

View File

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

View File

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

View File

@@ -9,7 +9,6 @@ use indexmap::{IndexMap, IndexSet};
use std::cell::Cell; use std::cell::Cell;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::mem::swap; use std::mem::swap;
use std::rc::Rc;
use std::vec::Vec; use std::vec::Vec;
// labeled with chunk numbers. // labeled with chunk numbers.
@@ -84,8 +83,8 @@ type VariableFixture<'a> = (VarStatus, Vec<&'a Cell<VarReg>>);
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct VariableFixtures<'a> { pub(crate) struct VariableFixtures<'a> {
perm_vars: IndexMap<Rc<String>, VariableFixture<'a>>, perm_vars: IndexMap<Var, VariableFixture<'a>>,
last_chunk_temp_vars: IndexSet<Rc<String>>, last_chunk_temp_vars: IndexSet<Var>,
} }
impl<'a> VariableFixtures<'a> { 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); 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); self.last_chunk_temp_vars.insert(var);
} }
@@ -115,7 +114,7 @@ impl<'a> VariableFixtures<'a> {
// Compute the conflict set of u. // Compute the conflict set of u.
// 1. // 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() { for (var, &mut (ref mut var_status, _)) in self.iter_mut() {
if let &mut VarStatus::Temp(_, ref mut var_data) = var_status { 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 { if let GenContext::Last(cn_u) = term_loc {
for (ref t, &mut (ref mut var_status, _)) in self.iter_mut() { 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 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) { if !t_data.uses_reg(reg) {
t_data.no_use_set.insert(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) 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() 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() 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() self.perm_vars.values()
} }

View File

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

View File

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

View File

@@ -7,11 +7,40 @@ use std::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt; use std::fmt;
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::{Hash, Hasher}; use std::hash::{Hash};
use std::iter::*; use std::iter::*;
use std::rc::Rc;
use std::vec::Vec; 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)] #[derive(Debug, Clone)]
pub(crate) enum TermRef<'a> { pub(crate) enum TermRef<'a> {
AnonVar(Level), AnonVar(Level),
@@ -20,7 +49,7 @@ pub(crate) enum TermRef<'a> {
Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>), Clause(Level, &'a Cell<RegType>, Atom, &'a Vec<Term>),
PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), PartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
CompleteString(Level, &'a Cell<RegType>, Atom), CompleteString(Level, &'a Cell<RegType>, Atom),
Var(Level, &'a Cell<VarReg>, Rc<String>), Var(Level, &'a Cell<VarReg>, Var),
} }
impl<'a> TermRef<'a> { 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)] #[derive(Debug)]
pub(crate) enum TermIterState<'a> { pub(crate) enum TermIterState<'a> {
AnonVar(Level), AnonVar(Level),
@@ -99,7 +76,8 @@ pub(crate) enum TermIterState<'a> {
InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>), InitialPartialString(Level, &'a Cell<RegType>, &'a String, &'a Box<Term>),
FinalPartialString(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), 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> { impl<'a> TermIterState<'a> {
@@ -119,7 +97,7 @@ impl<'a> TermIterState<'a> {
Term::CompleteString(cell, atom) => { Term::CompleteString(cell, atom) => {
TermIterState::CompleteString(lvl, 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, *name,
terms, 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 { QueryIterator {
@@ -183,13 +161,14 @@ impl<'a> QueryIterator<'a> {
} }
} }
&QueryTerm::UnblockedCut(ref cell) => { &QueryTerm::UnblockedCut(ref cell) => {
let state = TermIterState::Var(Level::Root, cell, RcMutPtr::from("!".to_string())); let state = TermIterState::UnblockedCut(Level::Root, cell);
QueryIterator { QueryIterator {
state_stack: vec![state], state_stack: vec![state],
} }
} }
&QueryTerm::GetLevelAndUnify(ref cell, ref var) => { &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 { QueryIterator {
state_stack: vec![state], state_stack: vec![state],
} }
@@ -267,7 +246,10 @@ impl<'a> Iterator for QueryIterator<'a> {
return Some(TermRef::Literal(lvl, cell, constant)); return Some(TermRef::Literal(lvl, cell, constant));
} }
TermIterState::Var(lvl, cell, var) => { 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)] vec![TermIterState::Literal(Level::Root, cell, constant)]
} }
Term::Var(cell, var) => { 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)) return Some(TermRef::Literal(lvl, cell, constant))
} }
TermIterState::Var(lvl, cell, var) => { 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 { fn contains_cut_var<'a, Iter: Iterator<Item = &'a Term>>(terms: Iter) -> bool {
for term in terms { for term in terms {
if let &Term::Var(_, ref var) = term { if let &Term::Var(_, ref var) = term {
if var.as_str() == "!" { if var.as_str() == Some("!") {
return true; return true;
} }
} }

View File

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

View File

@@ -16,7 +16,6 @@ use modular_bitfield::specifiers::*;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use crate::types::*; use crate::types::*;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[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 HeapVarDict = IndexMap<Var, HeapCellValue, FxBuildHasher>;
pub(crate) type AllocVarDict = IndexMap<Rc<String>, VarData, FxBuildHasher>; pub(crate) type AllocVarDict = IndexMap<Var, VarData, FxBuildHasher>;
pub(crate) type GlobalVarDir = IndexMap<Atom, (Ball, Option<HeapCellValue>), 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::convert::TryFrom;
use std::fmt; use std::fmt;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::rc::Rc;
pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1]; 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 { pub fn read_term(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
fn push_var_eq_functors<'a>( fn push_var_eq_functors<'a>(
heap: &mut Heap, heap: &mut Heap,
iter: impl Iterator<Item = (&'a Rc<String>, &'a HeapCellValue)>, iter: impl Iterator<Item = (&'a Var, &'a HeapCellValue)>,
atom_tbl: &mut AtomTable, atom_tbl: &mut AtomTable,
) -> Vec<HeapCellValue> { ) -> Vec<HeapCellValue> {
let mut list_of_var_eqs = vec![]; let mut list_of_var_eqs = vec![];
for (var, binding) in iter { 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(); let h = heap.len();
heap.push(atom_as_cell!(atom!("="), 2)); 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) { let printer = match self.try_from_list(self.registers[6], stub_gen) {
Ok(addrs) => { 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 { for addr in addrs {
read_heap_cell!(addr, read_heap_cell!(addr,
@@ -691,18 +690,18 @@ impl MachineState {
read_heap_cell!(atom, read_heap_cell!(atom,
(HeapCellValueTag::Char, c) => { (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)) => { (HeapCellValueTag::Atom, (name, _arity)) => {
debug_assert_eq!(_arity, 0); 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) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s]) let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity(); .get_name_and_arity();
debug_assert_eq!(arity, 0); 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!(); unreachable!();

View File

@@ -12,7 +12,6 @@ use indexmap::IndexSet;
use std::cell::Cell; use std::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::rc::Rc;
/* /*
* The preprocessor fabricates if-then-else ( .. -> ... ; ...) * The preprocessor fabricates if-then-else ( .. -> ... ; ...)
@@ -373,7 +372,7 @@ fn mark_cut_variable(term: &mut Term) -> bool {
}; };
if cut_var_found { if cut_var_found {
*term = Term::Var(Cell::default(), Rc::new(String::from("!"))); *term = Term::Var(Cell::default(), Var::from("!"));
true true
} else { } else {
false 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() vars.into_iter()
.map(|v| Term::Var(Cell::default(), v)) .map(|v| Term::Var(Cell::default(), v))
.collect() .collect()
@@ -767,7 +766,7 @@ impl Preprocessor {
} }
} }
Term::Literal(_, Literal::Char('!')) => Ok(QueryTerm::BlockedCut), 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())) Ok(QueryTerm::UnblockedCut(Cell::default()))
} }
Term::Clause(r, name, mut terms) => match (name, source_arity(&terms)) { 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::num::NonZeroU32;
use std::ops::Sub; use std::ops::Sub;
use std::process; use std::process;
use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc; use std::sync::Arc;
@@ -1410,7 +1409,7 @@ impl Machine {
let vars: Vec<_> = vars let vars: Vec<_> = vars
.union(&result.supp_vars) // difference + union does not cancel. .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(); .collect();
let helper_clause_loc = self.code.len(); 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)] #[derive(Debug, Clone)]
pub enum Term { pub enum Term {
AnonVar, AnonVar,
@@ -582,7 +620,7 @@ pub enum Term {
// other PartialString variants in as_partial_string. // other PartialString variants in as_partial_string.
PartialString(Cell<RegType>, String, Box<Term>), PartialString(Cell<RegType>, String, Box<Term>),
CompleteString(Cell<RegType>, Atom), CompleteString(Cell<RegType>, Atom),
Var(Cell<VarReg>, Rc<String>), Var(Cell<VarReg>, Var),
} }
impl Term { impl Term {

View File

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