[package]
name = "scryer-prolog"
-version = "0.8.108"
+version = "0.8.109"
build = "build.rs"
repository = "https://github.com/mthom/scryer-prolog"
ExpandGoal,
ExpandTerm,
FetchGlobalVar,
+ FetchGlobalVarWithOffset,
GetChar,
TruncateIfNoLiftedHeapGrowthDiff,
TruncateIfNoLiftedHeapGrowth,
RemoveCallPolicyCheck,
RemoveInferenceCounter,
ResetGlobalVarAtKey,
+ ResetGlobalVarAtOffset,
RetractClause,
RestoreCutPolicy,
SetCutPoint(RegType),
StoreGlobalVar,
+ StoreGlobalVarWithOffset,
InferenceLevel,
CleanUpBlock,
EraseBall,
&SystemClauseType::ExpandTerm => clause_name!("$expand_term"),
&SystemClauseType::ExpandGoal => clause_name!("$expand_goal"),
&SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
+ &SystemClauseType::FetchGlobalVarWithOffset => {
+ clause_name!("$fetch_global_var_with_offset")
+ }
&SystemClauseType::GetChar => clause_name!("$get_char"),
&SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
clause_name!("$truncate_if_no_lh_growth")
&SystemClauseType::RestoreCutPolicy => clause_name!("$restore_cut_policy"),
&SystemClauseType::SetCutPoint(_) => clause_name!("$set_cp"),
&SystemClauseType::StoreGlobalVar => clause_name!("$store_global_var"),
+ &SystemClauseType::StoreGlobalVarWithOffset => {
+ clause_name!("$store_global_var_with_offset")
+ }
&SystemClauseType::InferenceLevel => clause_name!("$inference_level"),
&SystemClauseType::CleanUpBlock => clause_name!("$clean_up_block"),
&SystemClauseType::EraseBall => clause_name!("$erase_ball"),
&SystemClauseType::ReadQueryTerm => clause_name!("$read_query_term"),
&SystemClauseType::ReadTerm => clause_name!("$read_term"),
&SystemClauseType::ResetGlobalVarAtKey => clause_name!("$reset_global_var_at_key"),
+ &SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"),
&SystemClauseType::RetractClause => clause_name!("$retract_clause"),
&SystemClauseType::ResetBlock => clause_name!("$reset_block"),
&SystemClauseType::ReturnFromAttributeGoals => {
("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
+ ("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
("$get_char", 1) => Some(SystemClauseType::GetChar),
("$truncate_if_no_lh_growth", 1) => {
Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth)
("$read_term", 2) => Some(SystemClauseType::ReadTerm),
("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
+ ("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
("$return_from_attribute_goals", 0) => Some(SystemClauseType::ReturnFromAttributeGoals),
("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
+ ("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
("$submit_query_and_print_results", 2) => Some(SystemClauseType::REPL(
REPLCodePtr::SubmitQueryAndPrintResults,
)),
%% (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)).
+%% backtrackable global variables.
+
bb_b_put(Key, NewValue) :-
- ( bb_get(Key, OldValue) ->
- call_cleanup((store_global_var(Key, NewValue) ; false), store_global_var(Key, OldValue))
- ; call_cleanup((store_global_var(Key, NewValue) ; false), reset_global_var_at_key(Key))
+ ( '$bb_get_with_offset'(Key, OldValue, OldOffset) ->
+ call_cleanup((store_global_var_with_offset(Key, NewValue) ; false),
+ reset_global_var_at_offset(Key, OldValue, OldOffset))
+ ; call_cleanup((store_global_var(Key, NewValue, _) ; false),
+ reset_global_var_at_key(Key))
).
+store_global_var_with_offset(Key, Value) :- '$store_global_var_with_offset'(Key, Value).
+
store_global_var(Key, Value) :- '$store_global_var'(Key, Value).
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)).
// key type: module name, predicate indicator.
pub type DynamicCodeDir = IndexMap<(ClauseName, ClauseName, usize), DynamicPredicateInfo>;
-pub type GlobalVarDir = IndexMap<ClauseName, Ball>;
+pub type GlobalVarDir = IndexMap<ClauseName, (Ball, Option<usize>)>;
pub struct IndexStore {
pub(super) atom_tbl: TabledData<Atom>,
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
+ // necessary because of restore_snapshot. similarly for other choice instructions.
+ machine_st.num_of_args = n;
machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
+ machine_st.num_of_args = n;
machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
+ machine_st.num_of_args = n;
machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
machine_st.registers[i] = machine_st.or_stack[b][i].clone();
}
+ machine_st.num_of_args = n;
machine_st.e = machine_st.or_stack[b].e;
machine_st.cp = machine_st.or_stack[b].cp.clone();
}
#[allow(dead_code)]
- pub fn print_heap(&self) {
- for h in 0..self.heap.h {
+ pub fn print_heap(&self, start: usize) {
+ for h in start .. self.heap.h {
println!("{} : {}", h, self.heap[h]);
}
}
for i in 1..narity + 1 {
self.registers[i] = self.heap[a + i].as_addr(a + i);
}
-
+
(name, narity)
} else {
self.fail = true;
let gi = self.next_global_index();
self.p += 1;
-
+
if self.e + 1 < self.and_stack.len() {
let and_gi = self.and_stack[self.e].global_index;
let or_gi = self
self.machine_st.p = top_level_code_ptr!(cn, p);
}
-
+
self.machine_st.query_stepper(
&mut self.indices,
&mut self.policies,
}
}
}
-
+
#[inline]
fn install_new_block(&mut self, r: RegType) -> usize {
self.block = self.b;
let addr = self[temp_v!(2)].clone();
- match indices.global_variables.get(&key) {
- Some(ref ball) => {
+ match indices.global_variables.get_mut(&key) {
+ Some((ref mut ball, 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));
}
+ Some((_, Some(h))) => {
+ self.unify(addr, Addr::HeapCell(*h))
+ }
None => self.fail = true,
};
}
+ &SystemClauseType::FetchGlobalVarWithOffset => {
+ let key = self[temp_v!(1)].clone();
+
+ let key = match self.store(self.deref(key)) {
+ Addr::Con(Constant::Atom(atom, _)) => atom,
+ _ => unreachable!(),
+ };
+
+ let addr = self[temp_v!(2)].clone();
+
+ 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)].clone();
+
+ self.unify(offset, Addr::Con(Constant::Usize(*h)));
+
+ if !self.fail {
+ self.unify(addr, Addr::HeapCell(*h));
+ }
+ }
+ None => {
+ self.fail = true
+ }
+ };
+ }
&SystemClauseType::GetChar => {
let result = current_input_stream.next();
let a1 = self[temp_v!(1)].clone();
} else {
tail
};
-
+
self.heap[l1 + 1] = HeapCellValue::Addr(tail);
self.trail(TrailRef::AttrVarLink(l1 + 1, old_addr));
}
&SystemClauseType::GetAttributedVariableList => {
let attr_var = self.store(self.deref(self[temp_v!(1)].clone()));
let attr_var_list = match attr_var {
- Addr::AttrVar(h) => h + 1,
+ Addr::AttrVar(h) => h + 1,
attr_var @ Addr::HeapCell(_) | attr_var @ Addr::StackCell(..) => {
// create an AttrVar in the heap.
let h = self.heap.h;
indices.global_variables.swap_remove(&key);
}
+ &SystemClauseType::ResetGlobalVarAtOffset => {
+ let key = self[temp_v!(1)].clone();
+
+ let key = match self.store(self.deref(key)) {
+ Addr::Con(Constant::Atom(atom, _)) => atom,
+ _ => unreachable!(),
+ };
+
+ let value = self[temp_v!(2)].clone();
+ let mut ball = Ball::new();
+ let h = self.heap.h;
+
+ ball.boundary = h;
+ copy_term(
+ CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
+ value,
+ );
+
+ let offset = self[temp_v!(3)].clone();
+
+ match self.store(self.deref(offset)) {
+ Addr::Con(Constant::Usize(offset)) => {
+ indices.global_variables.insert(key, (ball, Some(offset)))
+ }
+ _ => {
+ indices.global_variables.insert(key, (ball, None))
+ }
+ };
+ },
&SystemClauseType::RemoveCallPolicyCheck => {
let restore_default = match call_policy.downcast_mut::<CWILCallPolicy>().ok() {
Some(call_policy) => {
if let &Addr::Con(Constant::Usize(num_of_args)) = &self.and_stack[e][frame_len] {
self.num_of_args = num_of_args;
}
-
+
self.deallocate();
self.p = CodePtr::Local(self.and_stack[e].interrupt_cp);
-
+
return Ok(());
}
&SystemClauseType::RestoreCutPolicy => {
&SystemClauseType::SkipMaxList =>
if let Err(err) = self.skip_max_list() {
return Err(err);
- },
+ },
&SystemClauseType::StoreGlobalVar => {
let key = self[temp_v!(1)].clone();
_ => unreachable!(),
};
- let value = self[temp_v!(2)].clone();
+ let value = self[temp_v!(2)].clone();
let mut ball = Ball::new();
-
+
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);
+
+ indices.global_variables.insert(key, (ball, None));
+ }
+ &SystemClauseType::StoreGlobalVarWithOffset => {
+ let key = self[temp_v!(1)].clone();
+
+ let key = match self.store(self.deref(key)) {
+ Addr::Con(Constant::Atom(atom, _)) => atom,
+ _ => unreachable!(),
+ };
+
+ let value = self[temp_v!(2)].clone();
+ let mut ball = Ball::new();
+ let h = self.heap.h;
+
+ ball.boundary = h;
+ copy_term(
+ CopyBallTerm::new(&mut self.and_stack, &mut self.heap, &mut ball.stub),
+ value.clone(),
+ );
+
+ 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));
}
&SystemClauseType::Succeed => {}
&SystemClauseType::TermVariables => {