add classifications and occurrence counting
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
110
src/iterators.rs
110
src/iterators.rs
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
@@ -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!();
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user