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