no longer generate a choice point in bb_b_put/2 (#742)

This commit is contained in:
Mark Thom
2021-02-22 18:27:30 -07:00
parent 1a9f6f06df
commit 6c447da730
8 changed files with 195 additions and 154 deletions

View File

@@ -206,6 +206,11 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
}
}
#[inline]
pub(crate) fn is_empty(&self) -> bool {
self.h() == 0
}
#[inline]
pub(crate) fn pop(&mut self) {
let h = self.h();

View File

@@ -12,7 +12,6 @@ use crate::machine::partial_string::*;
use crate::machine::raw_block::RawBlockTraits;
use crate::machine::streams::Stream;
use crate::machine::term_stream::LoadStatePayload;
use crate::machine::Ball;
use crate::machine::CompilationTarget;
use crate::rug::{Integer, Rational};
use ordered_float::OrderedFloat;
@@ -297,6 +296,8 @@ pub enum TrailRef {
Ref(Ref),
AttrVarHeapLink(usize),
AttrVarListLink(usize, usize),
BlackboardEntry(usize),
BlackboardOffset(usize, usize), // key atom heap location, key value heap location
}
impl From<Ref> for TrailRef {
@@ -691,13 +692,7 @@ impl SubAssign<usize> for CodePtr {
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
pub type InSituCodeDir = IndexMap<PredicateKey, usize>;
pub type GlobalVarDir = IndexMap<ClauseName, (Ball, Option<usize>)>;
#[derive(Debug)]
pub(crate) struct ModuleStub {
pub(crate) in_situ_code_dir: InSituCodeDir,
}
pub type GlobalVarDir = IndexMap<ClauseName, (Ball, Option<Addr>)>;
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
pub(crate) type StreamDir = BTreeSet<Stream>;

View File

@@ -657,7 +657,12 @@ impl MachineState {
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
pub(crate) trait CallPolicy: Any + fmt::Debug {
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
fn retry_me_else(
&mut self,
machine_st: &mut MachineState,
offset: usize,
global_variables: &mut GlobalVarDir,
) -> CallResult {
let b = machine_st.b;
let n = machine_st
.stack
@@ -679,7 +684,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
@@ -708,7 +713,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
Ok(())
}
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
fn retry(
&mut self,
machine_st: &mut MachineState,
offset: usize,
global_variables: &mut GlobalVarDir,
) -> CallResult {
let b = machine_st.b;
let n = machine_st
.stack
@@ -730,7 +740,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
@@ -759,7 +769,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
Ok(())
}
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
fn trust(
&mut self,
machine_st: &mut MachineState,
offset: usize,
global_variables: &mut GlobalVarDir,
) -> CallResult {
let b = machine_st.b;
let n = machine_st
.stack
@@ -779,7 +794,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
@@ -811,7 +826,11 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
Ok(())
}
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
fn trust_me(
&mut self,
machine_st: &mut MachineState,
global_variables: &mut GlobalVarDir,
) -> CallResult {
let b = machine_st.b;
let n = machine_st
.stack
@@ -831,7 +850,7 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
let old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
let curr_tr = machine_st.tr;
machine_st.unwind_trail(old_tr, curr_tr);
machine_st.unwind_trail(old_tr, curr_tr, global_variables);
machine_st.tr = machine_st.stack.index_or_frame(b).prelude.tr;
machine_st.trail.truncate(machine_st.tr);
@@ -1225,23 +1244,42 @@ impl CallPolicy for CWILCallPolicy {
self.increment(machine_st)
}
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
self.prev_policy.retry_me_else(machine_st, offset)?;
fn retry_me_else(
&mut self,
machine_st: &mut MachineState,
offset: usize,
global_variables: &mut GlobalVarDir,
) -> CallResult {
self.prev_policy.retry_me_else(machine_st, offset, global_variables)?;
self.increment(machine_st)
}
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
self.prev_policy.retry(machine_st, offset)?;
fn retry(
&mut self,
machine_st: &mut MachineState,
offset: usize,
global_variables: &mut GlobalVarDir,
) -> CallResult {
self.prev_policy.retry(machine_st, offset, global_variables)?;
self.increment(machine_st)
}
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
self.prev_policy.trust_me(machine_st)?;
fn trust_me(
&mut self,
machine_st: &mut MachineState,
global_variables: &mut GlobalVarDir,
) -> CallResult {
self.prev_policy.trust_me(machine_st, global_variables)?;
self.increment(machine_st)
}
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
self.prev_policy.trust(machine_st, offset)?;
fn trust(
&mut self,
machine_st: &mut MachineState,
offset: usize,
global_variables: &mut GlobalVarDir,
) -> CallResult {
self.prev_policy.trust(machine_st, offset, global_variables)?;
self.increment(machine_st)
}

View File

@@ -621,6 +621,14 @@ impl MachineState {
self.tr += 1;
}
}
TrailRef::BlackboardOffset(key_h, value_h) => {
self.trail.push(TrailRef::BlackboardOffset(key_h, value_h));
self.tr += 1;
}
TrailRef::BlackboardEntry(key_h) => {
self.trail.push(TrailRef::BlackboardEntry(key_h));
self.tr += 1;
}
}
}
@@ -644,7 +652,12 @@ impl MachineState {
}
}
pub(super) fn unwind_trail(&mut self, a1: usize, a2: usize) {
pub(super) fn unwind_trail(
&mut self,
a1: usize,
a2: usize,
global_variables: &mut GlobalVarDir,
) {
// the sequence is reversed to respect the chronology of trail
// additions, now that deleted attributes can be undeleted by
// backtracking.
@@ -665,6 +678,30 @@ impl MachineState {
TrailRef::AttrVarListLink(h, l) => {
self.heap[h] = HeapCellValue::Addr(Addr::Lis(l));
}
TrailRef::BlackboardOffset(key_h, value_h) => {
let key = atom_from!(
self,
self.store(self.deref(self.heap[key_h].as_addr(key_h)))
);
let value_addr = self.heap[value_h].as_addr(value_h);
match global_variables.get_mut(&key) {
Some((_, ref mut loc)) => *loc = Some(value_addr),
None => unreachable!(),
}
}
TrailRef::BlackboardEntry(key_h) => {
let key = atom_from!(
self,
self.store(self.deref(self.heap[key_h].as_addr(key_h)))
);
match global_variables.get_mut(&key) {
Some((_, ref mut loc)) => *loc = None,
None => unreachable!(),
}
}
}
}
}
@@ -1266,6 +1303,7 @@ impl MachineState {
&mut self,
indexing_lines: &Vec<IndexingLine>,
call_policy: &mut Box<dyn CallPolicy>,
global_variables: &mut GlobalVarDir,
) {
let mut index = 0;
let addr = match &indexing_lines[0] {
@@ -1372,7 +1410,12 @@ impl MachineState {
unreachable!()
}
self.execute_indexed_choice_instr(instrs.first().unwrap(), call_policy);
self.execute_indexed_choice_instr(
instrs.first().unwrap(),
call_policy,
global_variables,
);
break;
}
}
@@ -2989,6 +3032,7 @@ impl MachineState {
&mut self,
instr: &IndexedChoiceInstruction,
call_policy: &mut Box<dyn CallPolicy>,
global_variables: &mut GlobalVarDir,
) {
match instr {
&IndexedChoiceInstruction::Try(offset) => {
@@ -3018,10 +3062,10 @@ impl MachineState {
self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset));
}
&IndexedChoiceInstruction::Retry(l) => {
try_or_fail!(self, call_policy.retry(self, l));
try_or_fail!(self, call_policy.retry(self, l, global_variables));
}
&IndexedChoiceInstruction::Trust(l) => {
try_or_fail!(self, call_policy.trust(self, l));
try_or_fail!(self, call_policy.trust(self, l, global_variables));
}
};
}
@@ -3030,6 +3074,7 @@ impl MachineState {
&mut self,
instr: &ChoiceInstruction,
call_policy: &mut Box<dyn CallPolicy>,
global_variables: &mut GlobalVarDir,
) {
match instr {
&ChoiceInstruction::TryMeElse(offset) => {
@@ -3059,17 +3104,17 @@ impl MachineState {
}
&ChoiceInstruction::DefaultRetryMeElse(offset) => {
let mut call_policy = DefaultCallPolicy {};
try_or_fail!(self, call_policy.retry_me_else(self, offset))
try_or_fail!(self, call_policy.retry_me_else(self, offset, global_variables))
}
&ChoiceInstruction::DefaultTrustMe(_) => {
let mut call_policy = DefaultCallPolicy {};
try_or_fail!(self, call_policy.trust_me(self))
try_or_fail!(self, call_policy.trust_me(self, global_variables))
}
&ChoiceInstruction::RetryMeElse(offset) => {
try_or_fail!(self, call_policy.retry_me_else(self, offset))
try_or_fail!(self, call_policy.retry_me_else(self, offset, global_variables))
}
&ChoiceInstruction::TrustMe(_) => {
try_or_fail!(self, call_policy.trust_me(self))
try_or_fail!(self, call_policy.trust_me(self, global_variables))
}
}
}

View File

@@ -560,7 +560,11 @@ impl MachineState {
match instr {
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
&Line::Choice(ref choice_instr) => {
self.execute_choice_instr(choice_instr, &mut policies.call_policy)
self.execute_choice_instr(
choice_instr,
&mut policies.call_policy,
&mut indices.global_variables,
)
}
&Line::Cut(ref cut_instr) => {
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
@@ -579,10 +583,18 @@ impl MachineState {
self.p += 1;
}
&Line::IndexingCode(ref indexing_lines) => {
self.execute_indexing_instr(indexing_lines, &mut policies.call_policy)
self.execute_indexing_instr(
indexing_lines,
&mut policies.call_policy,
&mut indices.global_variables,
)
}
&Line::IndexedChoice(ref choice_instr) => {
self.execute_indexed_choice_instr(choice_instr, &mut policies.call_policy)
self.execute_indexed_choice_instr(
choice_instr,
&mut policies.call_policy,
&mut indices.global_variables,
)
}
&Line::Query(ref query_instr) => {
self.execute_query_instr(&query_instr);

View File

@@ -1850,12 +1850,10 @@ impl MachineState {
self.copy_term(AttrVarPolicy::StripAttributes);
}
&SystemClauseType::FetchGlobalVar => {
let key = self[temp_v!(1)];
let key = match self.store(self.deref(key)) {
let (key_h, key) = match self.store(self.deref(self[temp_v!(1)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.clone()
(h, atom.clone())
} else {
unreachable!()
}
@@ -1868,52 +1866,24 @@ impl MachineState {
let addr = self[temp_v!(2)];
match indices.global_variables.get_mut(&key) {
Some((ref mut ball, None)) => {
let h = self.heap.h();
let stub = ball.copy_and_align(h);
Some((ref ball, ref mut loc)) => {
match loc {
Some(ref value_addr) => {
self.unify(addr, *value_addr);
}
loc @ None if !ball.stub.is_empty() => {
let h = self.heap.h();
let stub = ball.copy_and_align(h);
self.heap.extend(stub.into_iter());
self.unify(addr, Addr::HeapCell(h));
}
Some((_, Some(h))) => self.unify(addr, Addr::HeapCell(*h)),
None => self.fail = true,
};
}
&SystemClauseType::FetchGlobalVarWithOffset => {
let key = self[temp_v!(1)];
self.heap.extend(stub.into_iter());
self.unify(addr, Addr::HeapCell(h));
let key = match self.store(self.deref(key)) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.clone()
} else {
unreachable!()
}
}
_ => {
unreachable!()
}
};
let addr = self[temp_v!(2)];
match indices.global_variables.get_mut(&key) {
Some((ref mut ball, ref mut offset @ None)) => {
let h = self.heap.h();
let stub = ball.copy_and_align(h);
self.heap.extend(stub.into_iter());
self.unify(addr, Addr::HeapCell(h));
*offset = Some(h);
}
Some((_, Some(h))) => {
let offset = self[temp_v!(3)];
self.unify(offset, Addr::Usize(*h));
if !self.fail {
self.unify(addr, Addr::HeapCell(*h));
if !self.fail {
*loc = Some(Addr::HeapCell(h));
self.trail(TrailRef::BlackboardEntry(key_h));
}
}
_ => self.fail = true,
}
}
None => self.fail = true,
@@ -3572,6 +3542,7 @@ impl MachineState {
}
}
}
/*
&SystemClauseType::ResetGlobalVarAtKey => {
let key = self[temp_v!(1)];
@@ -3626,6 +3597,7 @@ impl MachineState {
}
}
}
*/
&SystemClauseType::ResetAttrVarState => {
self.attr_var_init.reset();
}
@@ -4539,9 +4511,7 @@ impl MachineState {
self.unify(self[temp_v!(3)], property);
}
&SystemClauseType::StoreGlobalVar => {
let key = self[temp_v!(1)];
let key = match self.store(self.deref(key)) {
let key = match self.store(self.deref(self[temp_v!(1)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.clone()
@@ -4567,13 +4537,11 @@ impl MachineState {
indices.global_variables.insert(key, (ball, None));
}
&SystemClauseType::StoreGlobalVarWithOffset => {
let key = self[temp_v!(1)];
let key = match self.store(self.deref(key)) {
&SystemClauseType::StoreBacktrackableGlobalVar => {
let (key_h, key) = match self.store(self.deref(self[temp_v!(1)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.clone()
(h, atom.clone())
} else {
unreachable!()
}
@@ -4583,24 +4551,27 @@ impl MachineState {
}
};
let value = self[temp_v!(2)];
let mut ball = Ball::new();
let h = self.heap.h();
let new_value = self.store(self.deref(self[temp_v!(2)]));
ball.boundary = h;
copy_term(
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
value,
AttrVarPolicy::DeepCopy,
);
let stub = ball.copy_and_align(h);
self.heap.extend(stub.into_iter());
indices.global_variables.insert(key, (ball, Some(h)));
self.unify(value, Addr::HeapCell(h));
match indices.global_variables.get_mut(&key) {
Some((_, ref mut loc)) => {
match loc {
Some(ref mut value) => {
let old_value_loc = self.heap.push(HeapCellValue::Addr(*value));
self.trail(TrailRef::BlackboardOffset(key_h, old_value_loc));
*value = new_value;
}
loc @ None => {
self.trail(TrailRef::BlackboardEntry(key_h));
*loc = Some(new_value);
}
}
}
None => {
self.trail(TrailRef::BlackboardEntry(key_h));
indices.global_variables.insert(key, (Ball::new(), Some(new_value)));
}
}
}
&SystemClauseType::Succeed => {}
&SystemClauseType::TermAttributedVariables => {