copy terms to global variable blackboard, fix attribute_goals//1

This commit is contained in:
Mark Thom
2019-10-09 14:11:31 -06:00
parent 3409db010f
commit f898b98b06
12 changed files with 113 additions and 76 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.104" version = "0.8.105"
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

@@ -13,8 +13,10 @@
of a particular module, as a list of terms of the form of a particular module, as a list of terms of the form
Module:put_atts(V, ListOfAtts). */ Module:put_atts(V, ListOfAtts). */
'$default_attr_list'(Module, V) --> '$default_attr_list'(Module, V) -->
{ Module:get_atts(V, Attributes) }, ( { Module:get_atts(V, Attributes) } ->
'$default_attr_list'(Attributes, Module, V). '$default_attr_list'(Attributes, Module, V)
; []
).
'$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)]

View File

@@ -12,7 +12,9 @@ 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) :- atom(Key),
!,
'$store_global_var'(Key, Value).
bb_put(Key, _) :- throw(error(type_error(atom, Key), bb_put/2)). bb_put(Key, _) :- throw(error(type_error(atom, Key), bb_put/2)).
bb_b_put(Key, NewValue) :- bb_b_put(Key, NewValue) :-

View File

@@ -1070,14 +1070,19 @@ pub fn compile_special_form<R: Read>(
wam: &mut Machine, wam: &mut Machine,
src: ParsingStream<R>, src: ParsingStream<R>,
listing_src: ClauseName, listing_src: ClauseName,
) -> Result<Code, SessionError> { ) -> Result<usize, SessionError> {
let mut indices = default_index_store!(wam.indices.atom_tbl.clone()); let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
setup_indices(wam, clause_name!("builtins"), &mut indices)?; setup_indices(wam, clause_name!("builtins"), &mut indices)?;
let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src); let mut compiler = ListingCompiler::new(&wam.code_repo, true, listing_src);
let results = compiler.gather_items(wam, src, &mut indices)?; let results = compiler.gather_items(wam, src, &mut indices)?;
compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0) let code = compiler.generate_code(results.worker_results, wam, &mut indices.code_dir, 0)?;
let p = wam.code_repo.code.len();
add_toplevel_code(wam, code, indices);
Ok(p)
} }
#[inline] #[inline]

View File

@@ -15,7 +15,7 @@ pub(crate) trait CopierTarget: IndexMut<usize, Output = HeapCellValue> {
pub(crate) fn copy_term<T: CopierTarget>(target: T, addr: Addr) { pub(crate) fn copy_term<T: CopierTarget>(target: T, addr: Addr) {
let mut copy_term_state = CopyTermState::new(target); let mut copy_term_state = CopyTermState::new(target);
copy_term_state.copy_term_impl(addr); copy_term_state.copy_term_impl(addr);
} }
struct CopyTermState<T: CopierTarget> { struct CopyTermState<T: CopierTarget> {

View File

@@ -4,6 +4,7 @@ use prolog_parser::tabled_rc::*;
use prolog::clause_types::*; use prolog::clause_types::*;
use prolog::fixtures::*; use prolog::fixtures::*;
use prolog::forms::*; use prolog::forms::*;
use prolog::machine::Ball;
use indexmap::IndexMap; use indexmap::IndexMap;
@@ -454,7 +455,7 @@ pub type InSituCodeDir = IndexMap<PredicateKey, usize>;
// key type: module name, predicate indicator. // key type: module name, predicate indicator.
pub type DynamicCodeDir = IndexMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>; pub type DynamicCodeDir = IndexMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>;
pub type GlobalVarDir = IndexMap<ClauseName, Addr>; pub type GlobalVarDir = IndexMap<ClauseName, Ball>;
pub struct IndexStore { pub struct IndexStore {
pub(super) atom_tbl: TabledData<Atom>, pub(super) atom_tbl: TabledData<Atom>,

View File

@@ -21,7 +21,7 @@ use std::io::{stdout, Write};
use std::mem; use std::mem;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
pub(super) struct Ball { pub struct Ball {
pub(super) boundary: usize, // ball.0 pub(super) boundary: usize, // ball.0
pub(super) stub: MachineStub, // ball.1 pub(super) stub: MachineStub, // ball.1
} }
@@ -48,6 +48,22 @@ impl Ball {
stub: mem::replace(&mut self.stub, vec![]), stub: mem::replace(&mut self.stub, vec![]),
} }
} }
pub(super) fn copy_and_align(&self, h: usize) -> MachineStub {
let diff = self.boundary as i64 - h as i64;
let mut stub = vec![];
for index in 0..self.stub.len() {
let heap_value = self.stub[index].clone();
stub.push(match heap_value {
HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
_ => heap_value,
});
}
stub
}
} }
pub(super) struct CopyTerm<'a> { pub(super) struct CopyTerm<'a> {

View File

@@ -173,7 +173,7 @@ impl MachineState {
} }
_ => { _ => {
self.push_attr_var_binding(h, addr.clone()); self.push_attr_var_binding(h, addr.clone());
self.heap[h] = HeapCellValue::Addr(addr); self.heap[h] = HeapCellValue::Addr(addr);
self.trail(TrailRef::Ref(Ref::AttrVar(h))); self.trail(TrailRef::Ref(Ref::AttrVar(h)));
} }
} }
@@ -201,7 +201,8 @@ impl MachineState {
self.heap[h] = HeapCellValue::Addr(t1); self.heap[h] = HeapCellValue::Addr(t1);
self.trail(TrailRef::Ref(Ref::HeapCell(h))); self.trail(TrailRef::Ref(Ref::HeapCell(h)));
} }
Some(Ref::AttrVar(h)) => return self.bind_attr_var(h, t1), Some(Ref::AttrVar(h)) =>
self.bind_attr_var(h, t1),
None => {} None => {}
} }
} }
@@ -2091,26 +2092,6 @@ impl MachineState {
self.fail = true; self.fail = true;
} }
fn heap_ball_boundary_diff(&self) -> i64 {
self.ball.boundary as i64 - self.heap.h as i64
}
pub(super) fn copy_and_align_ball(&self) -> MachineStub {
let diff = self.heap_ball_boundary_diff();
let mut stub = vec![];
for index in 0..self.ball.stub.len() {
let heap_value = self.ball.stub[index].clone();
stub.push(match heap_value {
HeapCellValue::Addr(addr) => HeapCellValue::Addr(addr - diff),
_ => heap_value,
});
}
stub
}
pub(crate) fn is_cyclic_term(&self, addr: Addr) -> bool { pub(crate) fn is_cyclic_term(&self, addr: Addr) -> bool {
let mut seen = IndexSet::new(); let mut seen = IndexSet::new();
let mut fail = false; let mut fail = false;
@@ -2264,7 +2245,8 @@ impl MachineState {
} }
// returns true on failure. // returns true on failure.
pub(super) fn eq_test(&self, a1: Addr, a2: Addr) -> bool { pub(super)
fn eq_test(&self, a1: Addr, a2: Addr) -> bool {
let mut iter = self.zipped_acyclic_pre_order_iter(a1, a2); let mut iter = self.zipped_acyclic_pre_order_iter(a1, a2);
while let Some((v1, v2)) = iter.next() { while let Some((v1, v2)) = iter.next() {

View File

@@ -179,18 +179,16 @@ impl Machine {
match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes()), verify_attrs_src) match compile_special_form(self, parsing_stream(VERIFY_ATTRS.as_bytes()), verify_attrs_src)
{ {
Ok(code) => { Ok(p) => {
self.machine_st.attr_var_init.verify_attrs_loc = self.code_repo.code.len(); self.machine_st.attr_var_init.verify_attrs_loc = p;
self.code_repo.code.extend(code.into_iter());
} }
Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"), Err(_) => panic!("Machine::compile_special_forms() failed at VERIFY_ATTRS"),
} }
match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes()), project_attrs_src) match compile_special_form(self, parsing_stream(PROJECT_ATTRS.as_bytes()), project_attrs_src)
{ {
Ok(code) => { Ok(p) => {
self.machine_st.attr_var_init.project_attrs_loc = self.code_repo.code.len(); self.machine_st.attr_var_init.project_attrs_loc = p;
self.code_repo.code.extend(code.into_iter());
} }
Err(e) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS: {}", e), Err(e) => panic!("Machine::compile_special_forms() failed at PROJECT_ATTRS: {}", e),
} }
@@ -602,7 +600,9 @@ impl Machine {
self.machine_st.absorb_snapshot(snapshot); self.machine_st.absorb_snapshot(snapshot);
self.machine_st.ball = ball; self.machine_st.ball = ball;
let stub = self.machine_st.copy_and_align_ball(); let h = self.machine_st.heap.h;
let stub = self.machine_st.ball.copy_and_align(h);
self.machine_st.throw_exception(stub); self.machine_st.throw_exception(stub);
return; return;

View File

@@ -15,16 +15,20 @@ enqueue_goals(Goals0) :-
enqueue_goals(Goals). enqueue_goals(Goals).
enqueue_goals(_). enqueue_goals(_).
'$print_exception'(E) :- '$print_project_attributes_exception'(Module, E) :-
write_term('caught: ', [quoted(false)]), ( E = error(evaluation_error((Module:project_attributes)/2), project_attributes/2) ->
writeq(E), true
nl. ; write_term('caught: ', [quoted(false)]),
writeq(E),
nl
).
call_project_attributes([], _, _). call_project_attributes([], _, _).
call_project_attributes([Module|Modules], QueryVars, AttrVars) :- call_project_attributes([Module|Modules], QueryVars, AttrVars) :-
( catch(Module:project_attributes(QueryVars, AttrVars), ( catch(Module:project_attributes(QueryVars, AttrVars),
E, %error(evaluation_error((Module:project_attributes)/2), project_attributes/2), E,
'$print_exception'(E)) -> true '$print_project_attributes_exception'(Module, E))
-> true
; true ; true
), ),
call_project_attributes(Modules, QueryVars, AttrVars). call_project_attributes(Modules, QueryVars, AttrVars).
@@ -35,12 +39,25 @@ call_attribute_goals([Module | Modules], AttrVars) :-
enqueue_goals(Goals), enqueue_goals(Goals),
call_attribute_goals(Modules, AttrVars). call_attribute_goals(Modules, AttrVars).
'$print_attribute_goals_exception'(Module, E) :-
( E = error(evaluation_error((Module:attribute_goals)/3), attribute_goals/3)
-> true
; write_term('caught: ', [quoted(false)]),
writeq(E),
nl
).
call_goals([], _, []). call_goals([], _, []).
call_goals([AttrVar|AttrVars], Module, Goals) :- call_goals([AttrVar|AttrVars], Module, Goals) :-
( catch(Module:attribute_goals(AttrVar, Goals, RGoals), ( catch(( Module:attribute_goals(AttrVar, Goals, RGoals0),
E, %error(evaluation_error((Module:attribute_goals)/3), attribute_goals/3), atts:'$default_attr_list'(Module, AttrVar, RGoals0, RGoals)
('$print_exception'(E), atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals))) -> true ),
; true E,
( '$print_attribute_goals_exception'(Module, E),
atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals)
))
-> true
; atts:'$default_attr_list'(Module, AttrVar, Goals, RGoals)
), ),
call_goals(AttrVars, Module, RGoals). call_goals(AttrVars, Module, RGoals).

View File

@@ -840,8 +840,14 @@ impl MachineState {
let addr = self[temp_v!(2)].clone(); let addr = self[temp_v!(2)].clone();
match indices.global_variables.get(&key).cloned() { match indices.global_variables.get(&key) {
Some(sought_addr) => self.unify(addr, sought_addr), Some(ref ball) => {
let h = self.heap.h;
let stub = ball.copy_and_align(h);
self.heap.extend(stub.into_iter());
self.unify(addr, Addr::HeapCell(h));
}
None => self.fail = true, None => self.fail = true,
}; };
} }
@@ -1671,7 +1677,7 @@ impl MachineState {
let h = self.heap.h; let h = self.heap.h;
if self.ball.stub.len() > 0 { if self.ball.stub.len() > 0 {
let stub = self.copy_and_align_ball(); let stub = self.ball.copy_and_align(h);
self.heap.append(stub); self.heap.append(stub);
} else { } else {
self.fail = true; self.fail = true;
@@ -1759,9 +1765,16 @@ impl MachineState {
_ => unreachable!(), _ => unreachable!(),
}; };
let value = self[temp_v!(2)].clone(); let value = self[temp_v!(2)].clone();
let mut ball = Ball::new();
indices.global_variables.insert(key, value);
ball.boundary = self.heap.h;
copy_term(
CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
value,
);
indices.global_variables.insert(key, ball);
} }
&SystemClauseType::Succeed => {} &SystemClauseType::Succeed => {}
&SystemClauseType::TermVariables => { &SystemClauseType::TermVariables => {

View File

@@ -713,25 +713,9 @@ impl RelationWorker {
let mut query_terms = vec![]; let mut query_terms = vec![];
let mut work_queue = VecDeque::from(terms); let mut work_queue = VecDeque::from(terms);
let mut machine_st = MachineState::new(); let mut machine_st = MachineState::new();
while let Some(term) = work_queue.pop_front() { while let Some(term) = work_queue.pop_front() {
let mut term = *term; let term = *term;
if let Term::Clause(cell, name, terms, op_spec) = term {
if name.as_str() == "," {
let term = Term::Clause(cell, name, terms, op_spec);
let mut subterms = unfold_by_str(term, ",");
while let Some(subterm) = subterms.pop() {
work_queue.push_front(Box::new(subterm));
}
continue;
} else {
term = Term::Clause(cell, name, terms, op_spec);
}
}
let op_dir = op_dir(&indices.index_src); let op_dir = op_dir(&indices.index_src);
let mut expanded_terms = indices.term_stream.expand_goals( let mut expanded_terms = indices.term_stream.expand_goals(
@@ -739,14 +723,29 @@ impl RelationWorker {
op_dir.as_ref(), op_dir.as_ref(),
VecDeque::from(vec![term]) VecDeque::from(vec![term])
)?; )?;
while let Some(term) = expanded_terms.pop() { while let Some(term) = expanded_terms.pop() {
work_queue.push_front(Box::new(term)); work_queue.push_front(Box::new(term));
} }
if let Some(term) = work_queue.pop_front() { if let Some(term) = work_queue.pop_front() {
let mut term = *term; let mut term = *term;
if let Term::Clause(cell, name, terms, op_spec) = term {
if name.as_str() == "," {
let term = Term::Clause(cell, name, terms, op_spec);
let mut subterms = unfold_by_str(term, ",");
while let Some(subterm) = subterms.pop() {
work_queue.push_front(Box::new(subterm));
}
continue;
} else {
term = Term::Clause(cell, name, terms, op_spec);
}
}
if !blocks_cuts { if !blocks_cuts {
mark_cut_variable(&mut term); mark_cut_variable(&mut term);
} }
@@ -754,7 +753,7 @@ impl RelationWorker {
query_terms.push(self.pre_query_term(indices, term)?); query_terms.push(self.pre_query_term(indices, term)?);
} }
} }
Ok(query_terms) Ok(query_terms)
} }