2 Commits

14 changed files with 163 additions and 122 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.113" version = "0.8.115"
authors = ["Mark Thom <markjordanthom@gmail.com>"] authors = ["Mark Thom <markjordanthom@gmail.com>"]
build = "build.rs" build = "build.rs"
repository = "https://github.com/mthom/scryer-prolog" repository = "https://github.com/mthom/scryer-prolog"

View File

@@ -93,7 +93,7 @@ strings.
First, install the latest stable version of First, install the latest stable version of
[Rust](https://www.rust-lang.org/en-US/install.html) using your [Rust](https://www.rust-lang.org/en-US/install.html) using your
preferred method. Then install the latest Scryer Prolog with cargo, preferred method. Then install Scryer Prolog with cargo,
like so: like so:
``` ```
@@ -101,13 +101,27 @@ $> cargo install scryer-prolog
``` ```
cargo will download and install the libraries Scryer Prolog uses cargo will download and install the libraries Scryer Prolog uses
automatically. You can find the `scryer-prolog` executable in automatically from crates.io. You can find the `scryer-prolog`
`~/.cargo/bin`. executable in `~/.cargo/bin`.
Publishing Rust crates to crates.io and pushing to git are entirely
distinct, independent processes, so to be sure you have the latest
commit, it is recommended to clone directly from this git repository,
which can be done as follows:
```
$> git clone https://github.com/mthom/scryer-prolog
$> cd scryer-prolog
$> cargo run [--release]
```
The optional `--release` flag will perform various optimizations,
producing a faster executable.
Note on compatibility: Scryer Prolog should work on Linux, Mac OS X, Note on compatibility: Scryer Prolog should work on Linux, Mac OS X,
and BSD variants on which Rust runs. Windows support hinges on and BSD variants on which Rust runs. Windows support hinges on
rustyline and Termion being functional in that environment, which to rustyline and Termion being functional in that environment, which to
my knowledge is not currently the case. my knowledge is not presently the case.
## Built-in predicates ## Built-in predicates

View File

@@ -20,7 +20,7 @@
'$default_attr_list'([PG | PGs], Module, AttrVar) --> '$default_attr_list'([PG | PGs], Module, AttrVar) -->
( { '$module_of'(Module, PG) } -> [Module:put_atts(AttrVar, PG)] ( { '$module_of'(Module, PG) } -> [Module:put_atts(AttrVar, PG)]
; true ; { true }
), ),
'$default_attr_list'(PGs, Module, AttrVar). '$default_attr_list'(PGs, Module, AttrVar).
'$default_attr_list'([], _, _) --> []. '$default_attr_list'([], _, _) --> [].

View File

@@ -1159,7 +1159,7 @@ labeling_var(V) :- V == 1, !.
labeling_var(V) :- domain_error(clpb_variable, V). labeling_var(V) :- domain_error(clpb_variable, V).
variables_in_index_order(Vs0, Vs) :- variables_in_index_order(Vs0, Vs) :-
maplist(var_with_index, Vs0, IVs0), maplist(var_with_index, Vs0, IVs0),
keysort(IVs0, IVs), keysort(IVs0, IVs),
pairs_values(IVs, Vs). pairs_values(IVs, Vs).
@@ -1245,7 +1245,7 @@ bdd_count(Node, VNum, Count) :-
bdd_pow(Low, V, VNum, LPow), bdd_pow(Low, V, VNum, LPow),
bdd_pow(High, V, VNum, HPow), bdd_pow(High, V, VNum, HPow),
Count0 is LPow*LCount + HPow*HCount, Count0 is LPow*LCount + HPow*HCount,
Count = Count0 Count0 = Count
) )
). ).
@@ -1358,7 +1358,7 @@ weighted_maximum(Ws, Vars, Max) :-
pairs_values(IVs1, VarsIndexOrder), pairs_values(IVs1, VarsIndexOrder),
% Pairs is a list of Var-Weight terms, in index order of Vars % Pairs is a list of Var-Weight terms, in index order of Vars
pairs_keys_values(Pairs, VarsIndexOrder, WeightsIndexOrder), pairs_keys_values(Pairs, VarsIndexOrder, WeightsIndexOrder),
bdd_maximum(BDD, Pairs, Max), bdd_maximum(BDD, Pairs, Max), %% A,B are in BDD, but not C; A,B,C *are* in Pairs.
max_labeling(BDD, Pairs). max_labeling(BDD, Pairs).
max_labeling(1, Pairs) :- max_upto(Pairs, _, _). max_labeling(1, Pairs) :- max_upto(Pairs, _, _).
@@ -1509,7 +1509,7 @@ max_variable_node(Node, V0-N0, V-N) :-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ands_fusion(Ands0, Ands) :- ands_fusion(Ands0, Ands) :-
maplist(with_variables, Ands0, Pairs0), maplist(with_variables, Ands0, Pairs0),
keysort(Pairs0, Pairs), keysort(Pairs0, Pairs),
group_pairs_by_key(Pairs, Groups), group_pairs_by_key(Pairs, Groups),
pairs_values(Groups, Andss), pairs_values(Groups, Andss),

View File

@@ -51,4 +51,5 @@ gather_dif_goals([(X \== Y) | Goals]) -->
attribute_goals(X) --> attribute_goals(X) -->
{ get_atts(X, +dif(Goals)) }, { get_atts(X, +dif(Goals)) },
gather_dif_goals(Goals). gather_dif_goals(Goals),
{ put_atts(X, -dif(_)) }.

View File

@@ -26,6 +26,7 @@ gather_freeze_goals(Attrs, _) -->
!. !.
gather_freeze_goals([frozen(X) | _], Var) --> gather_freeze_goals([frozen(X) | _], Var) -->
[freeze(Var, X)], [freeze(Var, X)],
{ put_atts(Var, -frozen(_)) },
!. !.
gather_freeze_goals([_ | Attrs], Var) --> gather_freeze_goals([_ | Attrs], Var) -->
gather_freeze_goals(Attrs, Var). gather_freeze_goals(Attrs, Var).

View File

@@ -3,6 +3,7 @@
maplist/4, maplist/5, maplist/6, maplist/7, maplist/4, maplist/5, maplist/6, maplist/7,
maplist/8, maplist/9]). maplist/8, maplist/9]).
length(Xs, N) :- length(Xs, N) :-
var(N), !, var(N), !,
'$skip_max_list'(M, -1, Xs, Xs0), '$skip_max_list'(M, -1, Xs, Xs0),
@@ -30,17 +31,22 @@ length_rundown([_|Xs], N) :-
N1 is N-1, N1 is N-1,
length_rundown(Xs, N1). length_rundown(Xs, N1).
member(X, [X|_]). member(X, [X|_]).
member(X, [_|Xs]) :- member(X, Xs). member(X, [_|Xs]) :- member(X, Xs).
select(X, [X|Xs], Xs). select(X, [X|Xs], Xs).
select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys). select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
append([], R, R). append([], R, R).
append([X|L], R, [X|S]) :- append(L, R, S). append([X|L], R, [X|S]) :- append(L, R, S).
memberchk(X, Xs) :- member(X, Xs), !. memberchk(X, Xs) :- member(X, Xs), !.
reverse(Xs, Ys) :- reverse(Xs, Ys) :-
( nonvar(Xs) -> reverse(Xs, Ys, [], Xs) ( nonvar(Xs) -> reverse(Xs, Ys, [], Xs)
; reverse(Ys, Xs, [], Ys) ; reverse(Ys, Xs, [], Ys)
@@ -50,6 +56,7 @@ reverse([], [], YsRev, YsRev).
reverse([X1|Xs], [Y1|Ys], YsPreludeRev, Xss) :- reverse([X1|Xs], [Y1|Ys], YsPreludeRev, Xss) :-
reverse(Xs, Ys, [Y1|YsPreludeRev], Xss). reverse(Xs, Ys, [Y1|YsPreludeRev], Xss).
maplist(_, []). maplist(_, []).
maplist(Cont1, [E1|E1s]) :- maplist(Cont1, [E1|E1s]) :-
call(Cont1, E1), call(Cont1, E1),

View File

@@ -130,11 +130,12 @@ variant(X, Y) :- '$variant'(X, Y).
maybe :- '$maybe'. maybe :- '$maybe'.
set_random(Seed) :- set_random(Seed) :-
( nonvar(Seed) -> ( nonvar(Seed) ->
( Seed = seed(S) -> ( Seed = seed(S) ->
( integer(S) -> '$set_seed'(S) ( var(S) -> throw(error(instantiation_error, set_random/1))
; integer(S) -> '$set_seed'(S)
; throw(error(type_error(integer(S), set_random/1))) ; throw(error(type_error(integer(S), set_random/1)))
) )
) )
; throw(error(instantiation_error, set_random/1)) ; throw(error(instantiation_error, set_random/1))
). ).

View File

@@ -25,6 +25,7 @@ verify_attrs([], _, _, []).
call_verify_attributes(Attrs, _, _, []) :- call_verify_attributes(Attrs, _, _, []) :-
var(Attrs), !. var(Attrs), !.
call_verify_attributes([], _, _, []).
call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :- call_verify_attributes([Attr|Attrs], Var, Value, ListOfGoalLists) :-
gather_modules([Attr|Attrs], Modules0), gather_modules([Attr|Attrs], Modules0),
sort(Modules0, Modules), sort(Modules0, Modules),

View File

@@ -14,6 +14,7 @@ pub(super) struct AttrVarInitializer {
pub(super) attr_var_queue: Vec<usize>, pub(super) attr_var_queue: Vec<usize>,
pub(super) bindings: Bindings, pub(super) bindings: Bindings,
pub(super) cp: LocalCodePtr, pub(super) cp: LocalCodePtr,
pub(super) instigating_p: LocalCodePtr,
pub(super) verify_attrs_loc: usize, pub(super) verify_attrs_loc: usize,
pub(super) project_attrs_loc: usize, pub(super) project_attrs_loc: usize,
} }
@@ -24,6 +25,7 @@ impl AttrVarInitializer {
attribute_goals: vec![], attribute_goals: vec![],
attr_var_queue: vec![], attr_var_queue: vec![],
bindings: vec![], bindings: vec![],
instigating_p: LocalCodePtr::default(),
cp: LocalCodePtr::default(), cp: LocalCodePtr::default(),
verify_attrs_loc, verify_attrs_loc,
project_attrs_loc, project_attrs_loc,
@@ -41,10 +43,12 @@ impl AttrVarInitializer {
impl MachineState { impl MachineState {
pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) { pub(super) fn push_attr_var_binding(&mut self, h: usize, addr: Addr) {
if self.attr_var_init.bindings.is_empty() { if self.attr_var_init.bindings.is_empty() {
self.attr_var_init.instigating_p = self.p.local();
if self.last_call { if self.last_call {
self.attr_var_init.cp = self.cp; self.attr_var_init.cp = self.cp;
} else { } else {
self.attr_var_init.cp = self.p.local(); self.attr_var_init.cp = self.p.local() + 1;
} }
self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc); self.p = CodePtr::VerifyAttrInterrupt(self.attr_var_init.verify_attrs_loc);
@@ -127,24 +131,17 @@ impl MachineState {
} }
pub(super) fn verify_attr_interrupt(&mut self, p: usize) { pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
let rs = MAX_ARITY; self.allocate(self.num_of_args + 2);
// store temp vars in perm vars slots along with self.b0 and
// self.num_of_args. why self.b0? if we return to a NeckCut
// after finishing the interrupt, it won't work correctly if
// self.b == self.b0. we must change it back when we return,
// as if nothing happened.
self.allocate(rs + 2);
let e = self.e; let e = self.e;
self.and_stack[e].interrupt_cp = self.attr_var_init.cp; self.and_stack[e].interrupt_cp = self.attr_var_init.cp;
for i in 1..rs + 1 { for i in 1 .. self.num_of_args + 1 {
self.and_stack[e][i] = self[RegType::Temp(i)].clone(); self.and_stack[e][i] = self[RegType::Temp(i)].clone();
} }
self.and_stack[e][rs + 1] = Addr::Con(Constant::Usize(self.b0)); self.and_stack[e][self.num_of_args + 1] = Addr::Con(Constant::Usize(self.b0));
self.and_stack[e][rs + 2] = Addr::Con(Constant::Usize(self.num_of_args)); self.and_stack[e][self.num_of_args + 2] = Addr::Con(Constant::Usize(self.num_of_args));
self.verify_attributes(); self.verify_attributes();
@@ -201,7 +198,7 @@ impl Machine {
&mut self.code_repo, &mut self.code_repo,
&mut readline::input_stream(), &mut readline::input_stream(),
); );
self.machine_st self.machine_st
.print_attribute_goals_string(&self.indices.op_dir) .print_attribute_goals_string(&self.indices.op_dir)
} }

View File

@@ -469,6 +469,12 @@ pub struct IndexStore {
} }
impl IndexStore { impl IndexStore {
pub fn reset_global_variable_offsets(&mut self) {
for (_, ref mut offset) in self.global_variables.values_mut() {
*offset = None;
}
}
pub fn predicate_exists( pub fn predicate_exists(
&self, &self,
name: ClauseName, name: ClauseName,

View File

@@ -741,29 +741,21 @@ impl MachineState {
} }
let b = self.b - 1; let b = self.b - 1;
let mut i = self.or_stack[b].tr; let hb = self.hb;
let mut offset = 0;
while i < self.tr { for i in self.or_stack[b].tr .. self.tr {
let tr_i = self.trail[i]; match self.trail[i] {
let hb = self.hb;
match tr_i {
TrailRef::Ref(Ref::AttrVar(tr_i)) TrailRef::Ref(Ref::AttrVar(tr_i))
| TrailRef::Ref(Ref::HeapCell(tr_i)) | TrailRef::Ref(Ref::HeapCell(tr_i))
| TrailRef::AttrVarHeapLink(tr_i) | TrailRef::AttrVarHeapLink(tr_i)
| TrailRef::AttrVarListLink(tr_i, _) => { | TrailRef::AttrVarListLink(tr_i, _) =>
if tr_i < hb { if tr_i >= hb {
i += 1; offset += 1;
} else { } else {
let tr = self.tr; self.trail[i - offset] = self.trail[i];
let val = self.trail[tr - 1].clone(); },
self.trail[i] = val;
self.trail.pop();
self.tr -= 1;
}
}
TrailRef::Ref(Ref::StackCell(fr, _)) => { TrailRef::Ref(Ref::StackCell(fr, _)) => {
let b = self.b - 1;
let fr_gi = self.and_stack[fr].global_index; let fr_gi = self.and_stack[fr].global_index;
let b_gi = if !self.or_stack.is_empty() { let b_gi = if !self.or_stack.is_empty() {
self.or_stack[b].global_index self.or_stack[b].global_index
@@ -771,18 +763,17 @@ impl MachineState {
0 0
}; };
if fr_gi < b_gi { if fr_gi >= b_gi {
i += 1; offset += 1;
} else { } else {
let tr = self.tr; self.trail[i - offset] = self.trail[i];
let val = self.trail[tr - 1];
self.trail[i] = val;
self.trail.pop();
self.tr -= 1;
} }
} }
}; }
} }
self.tr -= offset;
self.trail.truncate(self.tr);
} }
#[inline] #[inline]
@@ -1675,7 +1666,7 @@ impl MachineState {
} else if s.is_expandable() { } else if s.is_expandable() {
self.heap self.heap
.push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone()))));
self.s = h; self.s = h;
self.mode = MachineMode::Read; self.mode = MachineMode::Read;
} else { } else {
@@ -3240,6 +3231,8 @@ impl MachineState {
) )
), ),
}; };
self.last_call = false;
} }
pub(super) fn execute_ctrl_instr( pub(super) fn execute_ctrl_instr(
@@ -3275,7 +3268,7 @@ impl MachineState {
self.b0 = self.b; self.b0 = self.b;
self.p += offset; self.p += offset;
} }
&ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone()), &ControlInstruction::Proceed => self.p = CodePtr::Local(self.cp.clone())
}; };
} }
@@ -3434,56 +3427,4 @@ impl MachineState {
self.heap_locs.clear(); self.heap_locs.clear();
self.lifted_heap.clear(); self.lifted_heap.clear();
} }
pub(super) fn sink_to_snapshot(&mut self) -> MachineState {
let mut snapshot = MachineState::with_capacity(0);
snapshot.hb = self.hb;
snapshot.e = self.e;
snapshot.b = self.b;
snapshot.b0 = self.b0;
snapshot.s = self.s;
snapshot.tr = self.tr;
snapshot.pstr_tr = self.pstr_tr;
snapshot.num_of_args = self.num_of_args;
snapshot.fail = self.fail;
snapshot.trail = mem::replace(&mut self.trail, vec![]);
snapshot.pstr_trail = mem::replace(&mut self.pstr_trail, vec![]);
snapshot.heap = self.heap.take();
snapshot.mode = self.mode;
snapshot.and_stack = self.and_stack.take();
snapshot.or_stack = self.or_stack.take();
snapshot.registers = mem::replace(&mut self.registers, vec![]);
snapshot.block = self.block;
snapshot.ball = self.ball.take();
snapshot.lifted_heap = mem::replace(&mut self.lifted_heap, vec![]);
snapshot
}
pub(super) fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
self.hb = snapshot.hb;
self.e = snapshot.e;
self.b = snapshot.b;
self.b0 = snapshot.b0;
self.s = snapshot.s;
self.tr = snapshot.tr;
self.pstr_tr = snapshot.pstr_tr;
self.num_of_args = snapshot.num_of_args;
self.fail = snapshot.fail;
self.trail = mem::replace(&mut snapshot.trail, vec![]);
self.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]);
self.heap = snapshot.heap.take();
self.mode = snapshot.mode;
self.and_stack = snapshot.and_stack.take();
self.or_stack = snapshot.or_stack.take();
self.registers = mem::replace(&mut snapshot.registers, vec![]);
self.block = snapshot.block;
self.ball = snapshot.ball.take();
self.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
}
} }

View File

@@ -6,6 +6,7 @@ use crate::prolog::fixtures::*;
use crate::prolog::forms::*; use crate::prolog::forms::*;
use crate::prolog::heap_print::*; use crate::prolog::heap_print::*;
use crate::prolog::instructions::*; use crate::prolog::instructions::*;
use crate::prolog::machine::heap::Heap;
use crate::prolog::read::*; use crate::prolog::read::*;
use crate::prolog::write::{next_keypress, ContinueResult}; use crate::prolog::write::{next_keypress, ContinueResult};
@@ -71,6 +72,7 @@ impl MachinePolicies {
pub struct Machine { pub struct Machine {
pub(super) machine_st: MachineState, pub(super) machine_st: MachineState,
pub(super) inner_heap: Heap,
pub(super) policies: MachinePolicies, pub(super) policies: MachinePolicies,
pub(super) indices: IndexStore, pub(super) indices: IndexStore,
pub(super) code_repo: CodeRepo, pub(super) code_repo: CodeRepo,
@@ -227,13 +229,13 @@ impl Machine {
} }
pub fn run_init_code(&mut self, code: Code) { pub fn run_init_code(&mut self, code: Code) {
let old_machine_st = self.machine_st.sink_to_snapshot(); let old_machine_st = self.sink_to_snapshot();
self.machine_st.reset(); self.machine_st.reset();
self.code_repo.cached_query = code; self.code_repo.cached_query = code;
self.run_query(&AllocVarDict::new()); self.run_query(&AllocVarDict::new());
self.machine_st.absorb_snapshot(old_machine_st); self.absorb_snapshot(old_machine_st);
} }
pub fn run_top_level(&mut self) { pub fn run_top_level(&mut self) {
@@ -260,6 +262,7 @@ impl Machine {
pub fn new(prolog_stream: PrologStream) -> Self { pub fn new(prolog_stream: PrologStream) -> Self {
let mut wam = Machine { let mut wam = Machine {
machine_st: MachineState::new(), machine_st: MachineState::new(),
inner_heap: Heap::with_capacity(256 * 256),
policies: MachinePolicies::new(), policies: MachinePolicies::new(),
indices: IndexStore::new(), indices: IndexStore::new(),
code_repo: CodeRepo::new(), code_repo: CodeRepo::new(),
@@ -570,9 +573,14 @@ impl Machine {
}; };
let stream = parsing_stream(s.as_bytes()); let stream = parsing_stream(s.as_bytes());
let snapshot = self.sink_to_snapshot();
let policies = mem::replace(&mut self.policies, MachinePolicies::new());
let snapshot = self.machine_st.sink_to_snapshot();
self.machine_st.reset(); self.machine_st.reset();
self.machine_st.heap = mem::replace(
&mut self.inner_heap,
Heap::with_capacity(0),
);
let result = match stream_to_toplevel(stream, self) { let result = match stream_to_toplevel(stream, self) {
Ok(packet) => compile_term(self, packet), Ok(packet) => compile_term(self, packet),
@@ -580,6 +588,8 @@ impl Machine {
}; };
self.handle_eval_session(result, snapshot); self.handle_eval_session(result, snapshot);
self.indices.reset_global_variable_offsets();
self.policies = policies;
} }
REPLCodePtr::UseModule => REPLCodePtr::UseModule =>
self.use_module(ModuleSource::Library), self.use_module(ModuleSource::Library),
@@ -594,10 +604,66 @@ impl Machine {
self.machine_st.p = CodePtr::Local(p); self.machine_st.p = CodePtr::Local(p);
} }
fn sink_to_snapshot(&mut self) -> MachineState {
let mut snapshot = MachineState::with_capacity(0);
snapshot.hb = self.machine_st.hb;
snapshot.e = self.machine_st.e;
snapshot.b = self.machine_st.b;
snapshot.b0 = self.machine_st.b0;
snapshot.s = self.machine_st.s;
snapshot.tr = self.machine_st.tr;
snapshot.pstr_tr = self.machine_st.pstr_tr;
snapshot.num_of_args = self.machine_st.num_of_args;
snapshot.fail = self.machine_st.fail;
snapshot.trail = mem::replace(&mut self.machine_st.trail, vec![]);
snapshot.pstr_trail = mem::replace(&mut self.machine_st.pstr_trail, vec![]);
snapshot.heap = self.machine_st.heap.take();
snapshot.mode = self.machine_st.mode;
snapshot.and_stack = self.machine_st.and_stack.take();
snapshot.or_stack = self.machine_st.or_stack.take();
snapshot.registers = mem::replace(&mut self.machine_st.registers, vec![]);
snapshot.block = self.machine_st.block;
snapshot.ball = self.machine_st.ball.take();
snapshot.lifted_heap = mem::replace(&mut self.machine_st.lifted_heap, vec![]);
snapshot
}
fn absorb_snapshot(&mut self, mut snapshot: MachineState) {
self.machine_st.hb = snapshot.hb;
self.machine_st.e = snapshot.e;
self.machine_st.b = snapshot.b;
self.machine_st.b0 = snapshot.b0;
self.machine_st.s = snapshot.s;
self.machine_st.tr = snapshot.tr;
self.machine_st.pstr_tr = snapshot.pstr_tr;
self.machine_st.num_of_args = snapshot.num_of_args;
self.machine_st.fail = snapshot.fail;
self.machine_st.trail = mem::replace(&mut snapshot.trail, vec![]);
self.machine_st.pstr_trail = mem::replace(&mut snapshot.pstr_trail, vec![]);
self.inner_heap = self.machine_st.heap.take();
self.inner_heap.truncate(0);
self.machine_st.heap = snapshot.heap.take();
self.machine_st.mode = snapshot.mode;
self.machine_st.and_stack = snapshot.and_stack.take();
self.machine_st.or_stack = snapshot.or_stack.take();
self.machine_st.registers = mem::replace(&mut snapshot.registers, vec![]);
self.machine_st.block = snapshot.block;
self.machine_st.ball = snapshot.ball.take();
self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
}
fn propagate_exception_to_toplevel(&mut self, snapshot: MachineState) { fn propagate_exception_to_toplevel(&mut self, snapshot: MachineState) {
let ball = self.machine_st.ball.take(); let ball = self.machine_st.ball.take();
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
self.machine_st.ball = ball; self.machine_st.ball = ball;
let h = self.machine_st.heap.h; let h = self.machine_st.heap.h;
@@ -617,7 +683,7 @@ impl Machine {
}; };
let attr_goals = self.attribute_goals(); let attr_goals = self.attribute_goals();
if !(self.machine_st.b > 0) { if !(self.machine_st.b > 0) {
if bindings.is_empty() { if bindings.is_empty() {
let space = if requires_space(&attr_goals, ".") { let space = if requires_space(&attr_goals, ".") {
@@ -632,7 +698,7 @@ impl Machine {
println!("true."); println!("true.");
} }
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
return; return;
} }
} else if bindings.is_empty() && attr_goals.is_empty() { } else if bindings.is_empty() && attr_goals.is_empty() {
@@ -664,7 +730,7 @@ impl Machine {
} }
ContinueResult::Conclude => { ContinueResult::Conclude => {
print!(" ...\r\n"); print!(" ...\r\n");
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
return; return;
} }
}; };
@@ -676,12 +742,12 @@ impl Machine {
return; return;
} else { } else {
print!("false.\r\n"); print!("false.\r\n");
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
return; return;
} }
} }
EvalSession::Error(err) => { EvalSession::Error(err) => {
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
self.throw_session_error(err, (clause_name!("repl"), 0)); self.throw_session_error(err, (clause_name!("repl"), 0));
return; return;
} }
@@ -712,7 +778,7 @@ impl Machine {
} }
}, },
EvalSession::Error(err) => { EvalSession::Error(err) => {
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
self.throw_session_error(err, (clause_name!("repl"), 0)); self.throw_session_error(err, (clause_name!("repl"), 0));
return; return;
} }
@@ -725,7 +791,7 @@ impl Machine {
_ => println!("true.") _ => println!("true.")
} }
self.machine_st.absorb_snapshot(snapshot); self.absorb_snapshot(snapshot);
} }
pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) { pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
@@ -1046,9 +1112,15 @@ impl MachineState {
match self.p { match self.p {
CodePtr::VerifyAttrInterrupt(_) => { CodePtr::VerifyAttrInterrupt(_) => {
self.p = CodePtr::Local(self.attr_var_init.cp); self.p = CodePtr::Local(self.attr_var_init.cp);
if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) { let instigating_p = CodePtr::Local(self.attr_var_init.instigating_p);
let instigating_instr = code_repo.lookup_instr(false, &instigating_p).unwrap();
if !instigating_instr.as_ref().is_head_instr() {
let cp = self.p.local();
self.run_verify_attr_interrupt(cp);
} else if !self.verify_attr_stepper(indices, policies, code_repo, prolog_stream) {
if self.fail { if self.fail {
break; break;
} }

View File

@@ -1686,7 +1686,7 @@ impl MachineState {
return Ok(()); return Ok(());
} }
&SystemClauseType::ReturnFromAttributeGoals => { &SystemClauseType::ReturnFromAttributeGoals => {
self.deallocate(); self.deallocate();
self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0)); self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
return Ok(()); return Ok(());
} }