no longer generate a choice point in bb_b_put/2 (#742)
This commit is contained in:
@@ -186,7 +186,6 @@ pub enum SystemClauseType {
|
|||||||
EnqueueAttributeGoal,
|
EnqueueAttributeGoal,
|
||||||
EnqueueAttributedVar,
|
EnqueueAttributedVar,
|
||||||
FetchGlobalVar,
|
FetchGlobalVar,
|
||||||
FetchGlobalVarWithOffset,
|
|
||||||
FirstStream,
|
FirstStream,
|
||||||
FlushOutput,
|
FlushOutput,
|
||||||
GetByte,
|
GetByte,
|
||||||
@@ -240,14 +239,12 @@ pub enum SystemClauseType {
|
|||||||
RemoveCallPolicyCheck,
|
RemoveCallPolicyCheck,
|
||||||
RemoveInferenceCounter,
|
RemoveInferenceCounter,
|
||||||
ResetContinuationMarker,
|
ResetContinuationMarker,
|
||||||
ResetGlobalVarAtKey,
|
|
||||||
ResetGlobalVarAtOffset,
|
|
||||||
RestoreCutPolicy,
|
RestoreCutPolicy,
|
||||||
SetCutPoint(RegType),
|
SetCutPoint(RegType),
|
||||||
SetInput,
|
SetInput,
|
||||||
SetOutput,
|
SetOutput,
|
||||||
|
StoreBacktrackableGlobalVar,
|
||||||
StoreGlobalVar,
|
StoreGlobalVar,
|
||||||
StoreGlobalVarWithOffset,
|
|
||||||
StreamProperty,
|
StreamProperty,
|
||||||
SetStreamPosition,
|
SetStreamPosition,
|
||||||
InferenceLevel,
|
InferenceLevel,
|
||||||
@@ -434,9 +431,6 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
&SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"),
|
||||||
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
&SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
|
||||||
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
|
||||||
&SystemClauseType::FetchGlobalVarWithOffset => {
|
|
||||||
clause_name!("$fetch_global_var_with_offset")
|
|
||||||
}
|
|
||||||
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
&SystemClauseType::FirstStream => clause_name!("$first_stream"),
|
||||||
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
&SystemClauseType::FlushOutput => clause_name!("$flush_output"),
|
||||||
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
&SystemClauseType::GetByte => clause_name!("$get_byte"),
|
||||||
@@ -527,10 +521,10 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::SetSeed => clause_name!("$set_seed"),
|
&SystemClauseType::SetSeed => clause_name!("$set_seed"),
|
||||||
&SystemClauseType::StreamProperty => clause_name!("$stream_property"),
|
&SystemClauseType::StreamProperty => clause_name!("$stream_property"),
|
||||||
&SystemClauseType::SetStreamPosition => clause_name!("$set_stream_position"),
|
&SystemClauseType::SetStreamPosition => clause_name!("$set_stream_position"),
|
||||||
&SystemClauseType::StoreGlobalVar => clause_name!("$store_global_var"),
|
&SystemClauseType::StoreBacktrackableGlobalVar => {
|
||||||
&SystemClauseType::StoreGlobalVarWithOffset => {
|
clause_name!("$store_back_trackable_global_var")
|
||||||
clause_name!("$store_global_var_with_offset")
|
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::StoreGlobalVar => clause_name!("$store_global_var"),
|
||||||
&SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
|
&SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
|
||||||
&SystemClauseType::CleanUpBlock => clause_name!("$clean_up_block"),
|
&SystemClauseType::CleanUpBlock => clause_name!("$clean_up_block"),
|
||||||
&SystemClauseType::EraseBall => clause_name!("$erase_ball"),
|
&SystemClauseType::EraseBall => clause_name!("$erase_ball"),
|
||||||
@@ -539,15 +533,10 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::GetCutPoint => clause_name!("$get_cp"),
|
&SystemClauseType::GetCutPoint => clause_name!("$get_cp"),
|
||||||
&SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
|
&SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
|
||||||
&SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
|
&SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
|
||||||
// &SystemClauseType::ModuleRetractClause => clause_name!("$module_retract_clause"),
|
|
||||||
&SystemClauseType::NextEP => clause_name!("$nextEP"),
|
&SystemClauseType::NextEP => clause_name!("$nextEP"),
|
||||||
&SystemClauseType::ReadQueryTerm => clause_name!("$read_query_term"),
|
&SystemClauseType::ReadQueryTerm => clause_name!("$read_query_term"),
|
||||||
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
|
||||||
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
&SystemClauseType::ReadTermFromChars => clause_name!("$read_term_from_chars"),
|
||||||
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
|
|
||||||
&SystemClauseType::ResetGlobalVarAtOffset => {
|
|
||||||
clause_name!("$reset_global_var_at_offset")
|
|
||||||
}
|
|
||||||
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
|
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
|
||||||
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
&SystemClauseType::ResetContinuationMarker => clause_name!("$reset_cont_marker"),
|
||||||
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
&SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
|
||||||
@@ -654,9 +643,6 @@ impl SystemClauseType {
|
|||||||
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
("$peek_code", 2) => Some(SystemClauseType::PeekCode),
|
||||||
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
|
||||||
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
|
||||||
("$fetch_global_var_with_offset", 3) => {
|
|
||||||
Some(SystemClauseType::FetchGlobalVarWithOffset)
|
|
||||||
}
|
|
||||||
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
("$get_byte", 2) => Some(SystemClauseType::GetByte),
|
||||||
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
("$get_char", 2) => Some(SystemClauseType::GetChar),
|
||||||
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
("$get_n_chars", 3) => Some(SystemClauseType::GetNChars),
|
||||||
@@ -723,8 +709,6 @@ impl SystemClauseType {
|
|||||||
("$read_term_from_chars", 2) => Some(SystemClauseType::ReadTermFromChars),
|
("$read_term_from_chars", 2) => Some(SystemClauseType::ReadTermFromChars),
|
||||||
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
|
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
|
||||||
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
|
("$reset_cont_marker", 0) => Some(SystemClauseType::ResetContinuationMarker),
|
||||||
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
|
|
||||||
("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
|
|
||||||
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
|
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
|
||||||
("$set_ball", 1) => Some(SystemClauseType::SetBall),
|
("$set_ball", 1) => Some(SystemClauseType::SetBall),
|
||||||
("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
|
("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
|
||||||
@@ -737,8 +721,8 @@ impl SystemClauseType {
|
|||||||
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
("$socket_server_accept", 7) => Some(SystemClauseType::SocketServerAccept),
|
||||||
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
("$socket_server_close", 1) => Some(SystemClauseType::SocketServerClose),
|
||||||
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
|
||||||
("$store_global_var_with_offset", 2) => {
|
("$store_backtrackable_global_var", 2) => {
|
||||||
Some(SystemClauseType::StoreGlobalVarWithOffset)
|
Some(SystemClauseType::StoreBacktrackableGlobalVar)
|
||||||
}
|
}
|
||||||
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
("$term_attributed_variables", 2) => Some(SystemClauseType::TermAttributedVariables),
|
||||||
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
("$term_variables", 2) => Some(SystemClauseType::TermVariables),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
partial_string_tail/2, setup_call_cleanup/3,
|
partial_string_tail/2, setup_call_cleanup/3,
|
||||||
call_nth/2, variant/2]).
|
call_nth/2, variant/2]).
|
||||||
|
|
||||||
:- use_module(library(error), [can_be/2,domain_error/3]).
|
:- use_module(library(error), [can_be/2, domain_error/3, type_error/3]).
|
||||||
|
|
||||||
|
|
||||||
:- meta_predicate call_cleanup(0, 0).
|
:- meta_predicate call_cleanup(0, 0).
|
||||||
@@ -22,34 +22,25 @@ forall(Generate, Test) :-
|
|||||||
|
|
||||||
%% (non-)backtrackable global variables.
|
%% (non-)backtrackable global variables.
|
||||||
|
|
||||||
bb_put(Key, Value) :- atom(Key), !, '$store_global_var'(Key, Value).
|
bb_put(Key, Value) :-
|
||||||
bb_put(Key, _) :- throw(error(type_error(atom, Key), bb_put/2)).
|
( atom(Key) ->
|
||||||
|
'$store_global_var'(Key, Value)
|
||||||
|
; type_error(atom, Key, bb_put/2)
|
||||||
|
).
|
||||||
|
|
||||||
%% backtrackable global variables.
|
%% backtrackable global variables.
|
||||||
|
|
||||||
bb_b_put(Key, NewValue) :-
|
bb_b_put(Key, Value) :-
|
||||||
( '$bb_get_with_offset'(Key, OldValue, OldOffset) ->
|
( atom(Key) ->
|
||||||
call_cleanup((store_global_var_with_offset(Key, NewValue) ; false),
|
'$store_backtrackable_global_var'(Key, Value)
|
||||||
reset_global_var_at_offset(Key, OldValue, OldOffset))
|
; type_error(atom, Key, bb_b_put/2)
|
||||||
; call_cleanup((store_global_var_with_offset(Key, NewValue) ; false),
|
|
||||||
reset_global_var_at_key(Key))
|
|
||||||
).
|
).
|
||||||
|
|
||||||
store_global_var_with_offset(Key, Value) :- '$store_global_var_with_offset'(Key, Value).
|
bb_get(Key, Value) :-
|
||||||
|
( atom(Key) ->
|
||||||
store_global_var(Key, Value) :- '$store_global_var'(Key, Value).
|
'$fetch_global_var'(Key, Value)
|
||||||
|
; type_error(atom, Key, bb_get/2)
|
||||||
reset_global_var_at_key(Key) :- '$reset_global_var_at_key'(Key).
|
).
|
||||||
|
|
||||||
reset_global_var_at_offset(Key, Value, Offset) :- '$reset_global_var_at_offset'(Key, Value, Offset).
|
|
||||||
|
|
||||||
'$bb_get_with_offset'(Key, OldValue, Offset) :-
|
|
||||||
atom(Key), !, '$fetch_global_var_with_offset'(Key, OldValue, Offset).
|
|
||||||
'$bb_get_with_offset'(Key, _, _) :-
|
|
||||||
throw(error(type_error(atom, Key), bb_b_put/2)).
|
|
||||||
|
|
||||||
bb_get(Key, Value) :- atom(Key), !, '$fetch_global_var'(Key, Value).
|
|
||||||
bb_get(Key, _) :- throw(error(type_error(atom, Key), bb_get/2)).
|
|
||||||
|
|
||||||
|
|
||||||
call_cleanup(G, C) :- setup_call_cleanup(true, G, C).
|
call_cleanup(G, C) :- setup_call_cleanup(true, G, C).
|
||||||
|
|||||||
@@ -206,6 +206,11 @@ impl<T: RawBlockTraits> HeapTemplate<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
|
self.h() == 0
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn pop(&mut self) {
|
pub(crate) fn pop(&mut self) {
|
||||||
let h = self.h();
|
let h = self.h();
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ use crate::machine::partial_string::*;
|
|||||||
use crate::machine::raw_block::RawBlockTraits;
|
use crate::machine::raw_block::RawBlockTraits;
|
||||||
use crate::machine::streams::Stream;
|
use crate::machine::streams::Stream;
|
||||||
use crate::machine::term_stream::LoadStatePayload;
|
use crate::machine::term_stream::LoadStatePayload;
|
||||||
use crate::machine::Ball;
|
|
||||||
use crate::machine::CompilationTarget;
|
use crate::machine::CompilationTarget;
|
||||||
use crate::rug::{Integer, Rational};
|
use crate::rug::{Integer, Rational};
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
@@ -297,6 +296,8 @@ pub enum TrailRef {
|
|||||||
Ref(Ref),
|
Ref(Ref),
|
||||||
AttrVarHeapLink(usize),
|
AttrVarHeapLink(usize),
|
||||||
AttrVarListLink(usize, usize),
|
AttrVarListLink(usize, usize),
|
||||||
|
BlackboardEntry(usize),
|
||||||
|
BlackboardOffset(usize, usize), // key atom heap location, key value heap location
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Ref> for TrailRef {
|
impl From<Ref> for TrailRef {
|
||||||
@@ -691,13 +692,7 @@ impl SubAssign<usize> for CodePtr {
|
|||||||
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
pub type HeapVarDict = IndexMap<Rc<Var>, Addr>;
|
||||||
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
pub type AllocVarDict = IndexMap<Rc<Var>, VarData>;
|
||||||
|
|
||||||
pub type InSituCodeDir = IndexMap<PredicateKey, usize>;
|
pub type GlobalVarDir = IndexMap<ClauseName, (Ball, Option<Addr>)>;
|
||||||
pub type GlobalVarDir = IndexMap<ClauseName, (Ball, Option<usize>)>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct ModuleStub {
|
|
||||||
pub(crate) in_situ_code_dir: InSituCodeDir,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
|
pub(crate) type StreamAliasDir = IndexMap<ClauseName, Stream>;
|
||||||
pub(crate) type StreamDir = BTreeSet<Stream>;
|
pub(crate) type StreamDir = BTreeSet<Stream>;
|
||||||
|
|||||||
@@ -657,7 +657,12 @@ impl MachineState {
|
|||||||
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
pub(crate) type CallResult = Result<(), Vec<HeapCellValue>>;
|
||||||
|
|
||||||
pub(crate) trait CallPolicy: Any + fmt::Debug {
|
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 b = machine_st.b;
|
||||||
let n = machine_st
|
let n = machine_st
|
||||||
.stack
|
.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 old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
let curr_tr = machine_st.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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
@@ -708,7 +713,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
Ok(())
|
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 b = machine_st.b;
|
||||||
let n = machine_st
|
let n = machine_st
|
||||||
.stack
|
.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 old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
let curr_tr = machine_st.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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
@@ -759,7 +769,12 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
Ok(())
|
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 b = machine_st.b;
|
||||||
let n = machine_st
|
let n = machine_st
|
||||||
.stack
|
.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 old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
let curr_tr = machine_st.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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
@@ -811,7 +826,11 @@ pub(crate) trait CallPolicy: Any + fmt::Debug {
|
|||||||
Ok(())
|
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 b = machine_st.b;
|
||||||
let n = machine_st
|
let n = machine_st
|
||||||
.stack
|
.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 old_tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
let curr_tr = machine_st.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.tr = machine_st.stack.index_or_frame(b).prelude.tr;
|
||||||
|
|
||||||
machine_st.trail.truncate(machine_st.tr);
|
machine_st.trail.truncate(machine_st.tr);
|
||||||
@@ -1225,23 +1244,42 @@ impl CallPolicy for CWILCallPolicy {
|
|||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retry_me_else(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn retry_me_else(
|
||||||
self.prev_policy.retry_me_else(machine_st, offset)?;
|
&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)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn retry(
|
||||||
self.prev_policy.retry(machine_st, offset)?;
|
&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)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult {
|
fn trust_me(
|
||||||
self.prev_policy.trust_me(machine_st)?;
|
&mut self,
|
||||||
|
machine_st: &mut MachineState,
|
||||||
|
global_variables: &mut GlobalVarDir,
|
||||||
|
) -> CallResult {
|
||||||
|
self.prev_policy.trust_me(machine_st, global_variables)?;
|
||||||
self.increment(machine_st)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult {
|
fn trust(
|
||||||
self.prev_policy.trust(machine_st, offset)?;
|
&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)
|
self.increment(machine_st)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -621,6 +621,14 @@ impl MachineState {
|
|||||||
self.tr += 1;
|
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
|
// the sequence is reversed to respect the chronology of trail
|
||||||
// additions, now that deleted attributes can be undeleted by
|
// additions, now that deleted attributes can be undeleted by
|
||||||
// backtracking.
|
// backtracking.
|
||||||
@@ -665,6 +678,30 @@ impl MachineState {
|
|||||||
TrailRef::AttrVarListLink(h, l) => {
|
TrailRef::AttrVarListLink(h, l) => {
|
||||||
self.heap[h] = HeapCellValue::Addr(Addr::Lis(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,
|
&mut self,
|
||||||
indexing_lines: &Vec<IndexingLine>,
|
indexing_lines: &Vec<IndexingLine>,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
|
global_variables: &mut GlobalVarDir,
|
||||||
) {
|
) {
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
let addr = match &indexing_lines[0] {
|
let addr = match &indexing_lines[0] {
|
||||||
@@ -1372,7 +1410,12 @@ impl MachineState {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.execute_indexed_choice_instr(instrs.first().unwrap(), call_policy);
|
self.execute_indexed_choice_instr(
|
||||||
|
instrs.first().unwrap(),
|
||||||
|
call_policy,
|
||||||
|
global_variables,
|
||||||
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2989,6 +3032,7 @@ impl MachineState {
|
|||||||
&mut self,
|
&mut self,
|
||||||
instr: &IndexedChoiceInstruction,
|
instr: &IndexedChoiceInstruction,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
|
global_variables: &mut GlobalVarDir,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&IndexedChoiceInstruction::Try(offset) => {
|
&IndexedChoiceInstruction::Try(offset) => {
|
||||||
@@ -3018,10 +3062,10 @@ impl MachineState {
|
|||||||
self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset));
|
self.p = CodePtr::Local(dir_entry!(self.p.local().abs_loc() + offset));
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::Retry(l) => {
|
&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) => {
|
&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,
|
&mut self,
|
||||||
instr: &ChoiceInstruction,
|
instr: &ChoiceInstruction,
|
||||||
call_policy: &mut Box<dyn CallPolicy>,
|
call_policy: &mut Box<dyn CallPolicy>,
|
||||||
|
global_variables: &mut GlobalVarDir,
|
||||||
) {
|
) {
|
||||||
match instr {
|
match instr {
|
||||||
&ChoiceInstruction::TryMeElse(offset) => {
|
&ChoiceInstruction::TryMeElse(offset) => {
|
||||||
@@ -3059,17 +3104,17 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
&ChoiceInstruction::DefaultRetryMeElse(offset) => {
|
&ChoiceInstruction::DefaultRetryMeElse(offset) => {
|
||||||
let mut call_policy = DefaultCallPolicy {};
|
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(_) => {
|
&ChoiceInstruction::DefaultTrustMe(_) => {
|
||||||
let mut call_policy = DefaultCallPolicy {};
|
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) => {
|
&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(_) => {
|
&ChoiceInstruction::TrustMe(_) => {
|
||||||
try_or_fail!(self, call_policy.trust_me(self))
|
try_or_fail!(self, call_policy.trust_me(self, global_variables))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -560,7 +560,11 @@ impl MachineState {
|
|||||||
match instr {
|
match instr {
|
||||||
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
&Line::Arithmetic(ref arith_instr) => self.execute_arith_instr(arith_instr),
|
||||||
&Line::Choice(ref choice_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) => {
|
&Line::Cut(ref cut_instr) => {
|
||||||
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
self.execute_cut_instr(cut_instr, &mut policies.cut_policy)
|
||||||
@@ -579,10 +583,18 @@ impl MachineState {
|
|||||||
self.p += 1;
|
self.p += 1;
|
||||||
}
|
}
|
||||||
&Line::IndexingCode(ref indexing_lines) => {
|
&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) => {
|
&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) => {
|
&Line::Query(ref query_instr) => {
|
||||||
self.execute_query_instr(&query_instr);
|
self.execute_query_instr(&query_instr);
|
||||||
|
|||||||
@@ -1850,12 +1850,10 @@ impl MachineState {
|
|||||||
self.copy_term(AttrVarPolicy::StripAttributes);
|
self.copy_term(AttrVarPolicy::StripAttributes);
|
||||||
}
|
}
|
||||||
&SystemClauseType::FetchGlobalVar => {
|
&SystemClauseType::FetchGlobalVar => {
|
||||||
let key = self[temp_v!(1)];
|
let (key_h, key) = match self.store(self.deref(self[temp_v!(1)])) {
|
||||||
|
|
||||||
let key = match self.store(self.deref(key)) {
|
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
||||||
atom.clone()
|
(h, atom.clone())
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -1868,52 +1866,24 @@ impl MachineState {
|
|||||||
let addr = self[temp_v!(2)];
|
let addr = self[temp_v!(2)];
|
||||||
|
|
||||||
match indices.global_variables.get_mut(&key) {
|
match indices.global_variables.get_mut(&key) {
|
||||||
Some((ref mut ball, None)) => {
|
Some((ref ball, ref mut loc)) => {
|
||||||
let h = self.heap.h();
|
match loc {
|
||||||
let stub = ball.copy_and_align(h);
|
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.heap.extend(stub.into_iter());
|
||||||
self.unify(addr, Addr::HeapCell(h));
|
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)];
|
|
||||||
|
|
||||||
let key = match self.store(self.deref(key)) {
|
if !self.fail {
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
*loc = Some(Addr::HeapCell(h));
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
self.trail(TrailRef::BlackboardEntry(key_h));
|
||||||
atom.clone()
|
}
|
||||||
} else {
|
}
|
||||||
unreachable!()
|
_ => self.fail = true,
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => self.fail = true,
|
None => self.fail = true,
|
||||||
@@ -3572,6 +3542,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
&SystemClauseType::ResetGlobalVarAtKey => {
|
&SystemClauseType::ResetGlobalVarAtKey => {
|
||||||
let key = self[temp_v!(1)];
|
let key = self[temp_v!(1)];
|
||||||
|
|
||||||
@@ -3626,6 +3597,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
&SystemClauseType::ResetAttrVarState => {
|
&SystemClauseType::ResetAttrVarState => {
|
||||||
self.attr_var_init.reset();
|
self.attr_var_init.reset();
|
||||||
}
|
}
|
||||||
@@ -4539,9 +4511,7 @@ impl MachineState {
|
|||||||
self.unify(self[temp_v!(3)], property);
|
self.unify(self[temp_v!(3)], property);
|
||||||
}
|
}
|
||||||
&SystemClauseType::StoreGlobalVar => {
|
&SystemClauseType::StoreGlobalVar => {
|
||||||
let key = self[temp_v!(1)];
|
let key = match self.store(self.deref(self[temp_v!(1)])) {
|
||||||
|
|
||||||
let key = match self.store(self.deref(key)) {
|
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
||||||
atom.clone()
|
atom.clone()
|
||||||
@@ -4567,13 +4537,11 @@ impl MachineState {
|
|||||||
|
|
||||||
indices.global_variables.insert(key, (ball, None));
|
indices.global_variables.insert(key, (ball, None));
|
||||||
}
|
}
|
||||||
&SystemClauseType::StoreGlobalVarWithOffset => {
|
&SystemClauseType::StoreBacktrackableGlobalVar => {
|
||||||
let key = self[temp_v!(1)];
|
let (key_h, key) = match self.store(self.deref(self[temp_v!(1)])) {
|
||||||
|
|
||||||
let key = match self.store(self.deref(key)) {
|
|
||||||
Addr::Con(h) if self.heap.atom_at(h) => {
|
Addr::Con(h) if self.heap.atom_at(h) => {
|
||||||
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
|
||||||
atom.clone()
|
(h, atom.clone())
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -4583,24 +4551,27 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = self[temp_v!(2)];
|
let new_value = self.store(self.deref(self[temp_v!(2)]));
|
||||||
let mut ball = Ball::new();
|
|
||||||
let h = self.heap.h();
|
|
||||||
|
|
||||||
ball.boundary = h;
|
match indices.global_variables.get_mut(&key) {
|
||||||
|
Some((_, ref mut loc)) => {
|
||||||
copy_term(
|
match loc {
|
||||||
CopyBallTerm::new(&mut self.stack, &mut self.heap, &mut ball.stub),
|
Some(ref mut value) => {
|
||||||
value,
|
let old_value_loc = self.heap.push(HeapCellValue::Addr(*value));
|
||||||
AttrVarPolicy::DeepCopy,
|
self.trail(TrailRef::BlackboardOffset(key_h, old_value_loc));
|
||||||
);
|
*value = new_value;
|
||||||
|
}
|
||||||
let stub = ball.copy_and_align(h);
|
loc @ None => {
|
||||||
self.heap.extend(stub.into_iter());
|
self.trail(TrailRef::BlackboardEntry(key_h));
|
||||||
|
*loc = Some(new_value);
|
||||||
indices.global_variables.insert(key, (ball, Some(h)));
|
}
|
||||||
|
}
|
||||||
self.unify(value, Addr::HeapCell(h));
|
}
|
||||||
|
None => {
|
||||||
|
self.trail(TrailRef::BlackboardEntry(key_h));
|
||||||
|
indices.global_variables.insert(key, (Ball::new(), Some(new_value)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&SystemClauseType::Succeed => {}
|
&SystemClauseType::Succeed => {}
|
||||||
&SystemClauseType::TermAttributedVariables => {
|
&SystemClauseType::TermAttributedVariables => {
|
||||||
|
|||||||
Reference in New Issue
Block a user