#[macro_use] mod test_utils;
use prolog::io::*;
-use prolog::lib::control::*;
-use prolog::lib::lists::*;
use prolog::machine::*;
#[cfg(test)]
mod tests;
+pub static LISTS: &str = include_str!("./prolog/lib/lists.pl");
+pub static CONTROL: &str = include_str!("./prolog/lib/control.pl");
+
fn process_buffer(wam: &mut Machine, buffer: &str)
{
match parse_code(wam, buffer) {
GetCutPoint(RegType),
InferenceLevel,
InstallCleaner,
- InstallInferenceCounter(RegType),
+ InstallInferenceCounter(RegType, RegType, RegType),
InstallNewBlock,
InternalCallN,
IsAtomic(RegType),
IsRational(RegType),
IsString(RegType),
IsVar(RegType),
- RemoveInferenceCounter(RegType),
+ RemoveCallPolicyCheck,
+ RemoveInferenceCounter(RegType, RegType),
ResetBlock,
RestoreCutPolicy,
SetBall,
compare_term_execute!(term_cmp_lt!()), // (@<)/2, 390.
compare_term_execute!(term_cmp_eq!()), // (=@=)/2, 391.
compare_term_execute!(term_cmp_ne!()), // (\=@=)/2, 392.
- allocate!(4), // call_with_inference_limit/3, 393.
- fact![get_var_in_fact!(perm_v!(3), 1),
- get_var_in_fact!(perm_v!(2), 2),
- get_var_in_fact!(perm_v!(1), 3)],
- query![put_var!(perm_v!(4), 1)],
+ allocate!(5), // call_with_inference_limit/3, 393.
+ fact![get_var_in_fact!(perm_v!(4), 1),
+ get_var_in_fact!(perm_v!(3), 2),
+ get_var_in_fact!(perm_v!(2), 3)],
+ query![put_var!(perm_v!(5), 1)],
get_current_block!(),
- query![put_value!(perm_v!(3), 1),
- put_value!(perm_v!(2), 2),
- put_value!(perm_v!(1), 3),
- put_value!(perm_v!(4), 4)],
+ get_cp!(perm_v!(1)),
+ query![put_value!(perm_v!(4), 1),
+ put_value!(perm_v!(3), 2),
+ put_value!(perm_v!(2), 3),
+ put_value!(perm_v!(5), 4),
+ put_value!(perm_v!(1), 5)],
+ goto_call!(404, 5), // goto call_with_inference_limit/4, 404.
+ query![put_value!(perm_v!(1), 1)],
deallocate!(),
- goto_execute!(400, 4), // goto call_with_inference_limit/4, 400.
- try_me_else!(16), // call_with_inference_limit/4, 400.
- allocate!(7),
- fact![get_var_in_fact!(perm_v!(6), 1),
- get_var_in_fact!(perm_v!(7), 2),
- get_var_in_fact!(perm_v!(4), 3),
- get_var_in_fact!(perm_v!(3), 4)],
+ remove_call_policy_check!(),
+ proceed!(),
+ try_me_else!(18), // call_with_inference_limit/5, 404.
+ allocate!(9),
+ fact![get_var_in_fact!(perm_v!(9), 1),
+ get_var_in_fact!(perm_v!(6), 2),
+ get_var_in_fact!(perm_v!(5), 3),
+ get_var_in_fact!(perm_v!(3), 4),
+ get_var_in_fact!(perm_v!(4), 5)],
query![put_var!(perm_v!(1), 1)],
install_new_block!(),
- install_inference_counter!(perm_v!(7)),
- get_cp!(perm_v!(5)),
- query![put_value!(perm_v!(6), 1)],
+ install_inference_counter!(perm_v!(4), perm_v!(6), perm_v!(8)),
+ query![put_value!(perm_v!(9), 1)],
call_n!(1),
- query![put_var!(perm_v!(2), 3)],
- remove_inference_counter!(perm_v!(2)),
- query![put_value!(perm_v!(4), 1),
- put_value!(perm_v!(5), 2)],
+ remove_inference_counter!(perm_v!(4), perm_v!(7)),
+ sub!(ArithmeticTerm::Reg(perm_v!(7)),
+ ArithmeticTerm::Reg(perm_v!(8)),
+ 1),
+ sub!(ArithmeticTerm::Reg(perm_v!(6)),
+ ArithmeticTerm::Interm(1),
+ 1),
+ query![put_value!(perm_v!(2), 1)],
+ is_call!(temp_v!(1), ArithmeticTerm::Interm(1)),
+ query![put_value!(perm_v!(5), 1),
+ put_value!(perm_v!(4), 2)],
inference_level!(),
- query![put_value!(perm_v!(3), 1),
- put_value!(perm_v!(1), 2),
- put_value!(perm_v!(2), 3)],
+ query![put_value!(perm_v!(4), 1),
+ put_value!(perm_v!(3), 2),
+ put_value!(perm_v!(1), 3),
+ put_value!(perm_v!(2), 4)],
deallocate!(),
- goto_execute!(436, 3), // goto end_block/3, 436.
- default_trust_me!(), // 416.
- allocate!(2),
- fact![get_var_in_fact!(perm_v!(1), 3)],
+ goto_execute!(442, 4), // goto end_block/4, 442.
+ default_trust_me!(), // 422.
+ allocate!(3),
+ fact![get_var_in_fact!(perm_v!(1), 3),
+ get_var_in_fact!(perm_v!(3), 5)],
query![put_value!(temp_v!(4), 1)],
reset_block!(),
- query![put_var!(temp_v!(2), 1)],
- remove_inference_counter!(temp_v!(1)),
+ query![put_var!(temp_v!(3), 2)],
+ remove_inference_counter!(perm_v!(3), temp_v!(2)),
query![put_var!(perm_v!(2), 1)],
get_ball!(),
erase_ball!(),
- query![put_unsafe_value!(2, 1),
- put_value!(perm_v!(1), 2)],
+ query![put_value!(perm_v!(3), 1),
+ put_unsafe_value!(2, 2),
+ put_value!(perm_v!(1), 3)],
deallocate!(),
- goto_execute!(429, 2), // goto handle_ile/2, 429.
- try_me_else!(5), // handle_ile/2, 429.
- switch_on_term!(1, 1, 0, 0),
- fact![get_constant!(atom!("inference_limit_exceeded", atom_tbl), temp_v!(1)),
- get_constant!(atom!("inference_limit_exceeded", atom_tbl), temp_v!(2))],
+ goto_execute!(435, 3), // goto handle_ile/3, 435.
+ try_me_else!(4), // handle_ile/3, 435.
+ fact![get_structure!(atom_tbl, "inference_limit_exceeded", 1, temp_v!(2), None),
+ unify_value!(temp_v!(1)),
+ get_constant!(atom!("inference_limit_exceeded", atom_tbl), temp_v!(3))],
neck_cut!(),
proceed!(),
default_trust_me!(),
- goto_execute!(59, 1), // goto throw/1, 59.
- try_me_else!(9), // end_block/3, 436.
- allocate!(1),
- fact![get_var_in_fact!(perm_v!(1), 1)],
query![put_value!(temp_v!(2), 1)],
+ goto_execute!(59, 1), // goto throw/1, 59.
+ try_me_else!(6), // end_block/4, 442.
+ query![put_value!(temp_v!(3), 1)],
clean_up_block!(),
- query![put_value!(perm_v!(1), 1)],
- deallocate!(),
+ query![put_value!(temp_v!(2), 1)],
reset_block!(),
proceed!(),
default_trust_me!(),
- install_inference_counter!(temp_v!(3)),
- query![put_value!(temp_v!(2), 1)],
+ query![put_value!(temp_v!(4), 2),
+ put_var!(temp_v!(4), 4)],
+ install_inference_counter!(temp_v!(1), temp_v!(2), temp_v!(4)),
+ query![put_value!(temp_v!(3), 1)],
reset_block!(),
fail!()
]
write!(f, "clean_up_block"),
&BuiltInInstruction::DefaultTrustMe =>
write!(f, "default_trust_me"),
- &BuiltInInstruction::InstallInferenceCounter(r) =>
- write!(f, "install_inference_counter {}", r),
+ &BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) =>
+ write!(f, "install_inference_counter {}, {}, {}", r1, r2, r3),
&BuiltInInstruction::EraseBall =>
write!(f, "erase_ball"),
&BuiltInInstruction::Fail =>
write!(f, "number_test {}, {}, {} ", cmp, at_1, at_2),
&BuiltInInstruction::DynamicCompareNumber(cmp) =>
write!(f, "dynamic_number_test {}", cmp),
- &BuiltInInstruction::RemoveInferenceCounter(r) =>
- write!(f, "remove_inference_counter {}", r)
+ &BuiltInInstruction::RemoveCallPolicyCheck =>
+ write!(f, "remove_call_policy_check"),
+ &BuiltInInstruction::RemoveInferenceCounter(r1, r2) =>
+ write!(f, "remove_inference_counter {}, {}", r1, r2)
}
}
}
--- /dev/null
+:- op(700, xfx, \=).
+
+once(G) :- G, !.
+
+\=(X, X) :- !, false.
+\=(_, _).
+
+between(Lower, Upper, Lower) :-
+ Lower =< Upper.
+between(Lower1, Upper, X) :-
+ Lower1 < Upper,
+ Lower2 is Lower1 + 1,
+ between(Lower2, Upper, X).
+++ /dev/null
-pub static CONTROL: &str = ":- op(700, xfx, \\=).
-
- once(G) :- G, !.
-
- \\=(X, X) :- !, false.
- \\=(_, _).
-
- between(Lower, Upper, Lower) :-
- Lower =< Upper.
- between(Lower1, Upper, X) :-
- Lower1 < Upper,
- Lower2 is Lower1 + 1,
- between(Lower2, Upper, X).";
--- /dev/null
+member(X, [X|_]).
+member(X, [_|Xs]) :- member(X, Xs).
+
+select(X, [X|Xs], Xs).
+select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
+
+append([], R, R).
+append([X|L], R, [X|S]) :- append(L, R, S).
+
+memberchk(X, Xs) :- member(X, Xs), !.
+
+reverse(Xs, Ys) :- var(Ys), !, reverse(Xs, [], Ys).
+reverse(Ys, Xs) :- reverse(Xs, [], Ys).
+
+reverse([], Ys, Ys).
+reverse([H|T], Ps, Rs) :-
+ reverse(T, [H|Ps], Rs).
+
+maplist(_, []).
+maplist(Cont1, [E1|E1s]) :-
+ call(Cont1, E1),
+ maplist(Cont1, E1s).
+
+maplist(_, [], []).
+maplist(Cont2, [E1|E1s], [E2|E2s]) :-
+ call(Cont2, E1, E2),
+ maplist(Cont2, E1s, E2s).
+
+maplist(_, [], [], []).
+maplist(Cont3, [E1|E1s], [E2|E2s], [E3|E3s]) :-
+ call(Cont3, E1, E2, E3),
+ maplist(Cont3, E1s, E2s, E3s).
+
+maplist(_, [], [], [], []).
+maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s]) :-
+ call(Cont, E1, E2, E3, E4),
+ maplist(Cont, E1s, E2s, E3s, E4s).
+
+maplist(_, [], [], [], [], []).
+maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s]) :-
+ call(Cont, E1, E2, E3, E4, E5),
+ maplist(Cont, E1s, E2s, E3s, E4s, E5s).
+
+maplist(_, [], [], [], [], [], []).
+maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s]) :-
+ call(Cont, E1, E2, E3, E4, E5, E6),
+ maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s).
+
+maplist(_, [], [], [], [], [], [], []).
+maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s], [E7|E7s]) :-
+ call(Cont, E1, E2, E3, E4, E5, E6, E7),
+ maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s, E7s).
+
+maplist(_, [], [], [], [], [], [], [], []).
+maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s], [E7|E7s], [E8|E8s]) :-
+ call(Cont, E1, E2, E3, E4, E5, E6, E7),
+ maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s, E7s, E8s).
+++ /dev/null
-pub static LISTS: &str = "member(X, [X|_]).
- member(X, [_|Xs]) :- member(X, Xs).
-
- select(X, [X|Xs], Xs).
- select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
-
- append([], R, R).
- append([X|L], R, [X|S]) :- append(L, R, S).
-
- memberchk(X, Xs) :- member(X, Xs), !.
-
- reverse(Xs, Ys) :- var(Ys), !, reverse(Xs, [], Ys).
- reverse(Ys, Xs) :- reverse(Xs, [], Ys).
-
- reverse([], Ys, Ys).
- reverse([H|T], Ps, Rs) :-
- reverse(T, [H|Ps], Rs).
-
- maplist(_, []).
- maplist(Cont1, [E1|E1s]) :-
- call(Cont1, E1),
- maplist(Cont1, E1s).
-
- maplist(_, [], []).
- maplist(Cont2, [E1|E1s], [E2|E2s]) :-
- call(Cont2, E1, E2),
- maplist(Cont2, E1s, E2s).
-
- maplist(_, [], [], []).
- maplist(Cont3, [E1|E1s], [E2|E2s], [E3|E3s]) :-
- call(Cont3, E1, E2, E3),
- maplist(Cont3, E1s, E2s, E3s).
-
- maplist(_, [], [], [], []).
- maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s]) :-
- call(Cont, E1, E2, E3, E4),
- maplist(Cont, E1s, E2s, E3s, E4s).
-
- maplist(_, [], [], [], [], []).
- maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s]) :-
- call(Cont, E1, E2, E3, E4, E5),
- maplist(Cont, E1s, E2s, E3s, E4s, E5s).
-
- maplist(_, [], [], [], [], [], []).
- maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s]) :-
- call(Cont, E1, E2, E3, E4, E5, E6),
- maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s).
-
- maplist(_, [], [], [], [], [], [], []).
- maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s], [E7|E7s]) :-
- call(Cont, E1, E2, E3, E4, E5, E6, E7),
- maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s, E7s).
-
- maplist(_, [], [], [], [], [], [], [], []).
- maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s], [E7|E7s], [E8|E8s]) :-
- call(Cont, E1, E2, E3, E4, E5, E6, E7),
- maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s, E7s, E8s).";
+++ /dev/null
-pub mod control;
-pub mod lists;
-
use prolog::builtins::CodeDir;
use prolog::ast::*;
use prolog::copier::*;
-use prolog::num::{BigInt, BigUint, Zero, One};
+use prolog::num::{BigInt, Zero, One};
use prolog::or_stack::*;
use prolog::tabled_rc::*;
use downcast::Any;
-use std::cmp::Ordering;
-use std::collections::binary_heap::BinaryHeap;
use std::mem::swap;
use std::ops::{Index, IndexMut};
use std::rc::Rc;
machine_st.hb = machine_st.heap.h;
machine_st.p += 1;
-
+
Ok(())
}
}
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
- {
+ {
let b = machine_st.b - 1;
let n = machine_st.or_stack[b].num_args();
impl CallPolicy for DefaultCallPolicy {}
-#[derive(Clone, Eq, PartialEq)]
-struct InferenceLimit(BigUint);
-
-// ensure the heap behaves as a min-heap.
-impl Ord for InferenceLimit {
- fn cmp(&self, other: &InferenceLimit) -> Ordering {
- other.0.cmp(&self.0)
- }
-}
-
-impl PartialOrd for InferenceLimit {
- fn partial_cmp(&self, other: &InferenceLimit) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
pub(crate) struct CallWithInferenceLimitCallPolicy {
atom_tbl: TabledData<Atom>,
pub(crate) prev_policy: Box<CallPolicy>,
- count: BigUint,
- limits: BinaryHeap<InferenceLimit>
+ count: BigInt,
+ limits: Vec<(Rc<BigInt>, usize)>
}
impl CallWithInferenceLimitCallPolicy {
pub(crate) fn new_in_place(atom_tbl: TabledData<Atom>, policy: &mut Box<CallPolicy>)
{
let mut prev_policy: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
- swap(&mut prev_policy, policy);
-
- let new_policy = CallWithInferenceLimitCallPolicy { atom_tbl, prev_policy,
- count: BigUint::zero(),
- limits: BinaryHeap::new() };
+ swap(&mut prev_policy, policy);
+ let new_policy = CallWithInferenceLimitCallPolicy { atom_tbl, prev_policy,
+ count: BigInt::zero(),
+ limits: vec![] };
*policy = Box::new(new_policy);
}
- fn increment(&mut self) -> CallResult {
- if let Some(ref limit) = self.limits.peek() {
- if self.count == limit.0 {
- return Err(vec![heap_atom!("inference_limit_exceeded", self.atom_tbl)])
+ fn increment(&mut self) -> CallResult {
+ if let Some(&(ref limit, bp)) = self.limits.last() {
+ if self.count == **limit {
+ return Err(functor!(self.atom_tbl,
+ "inference_limit_exceeded",
+ 1,
+ [HeapCellValue::Addr(Addr::Con(Constant::Usize(bp)))]));
} else {
- self.count = BigUint::one() + &self.count;
+ self.count = BigInt::one() + &self.count;
}
}
Ok(())
}
- pub(crate) fn add_limit(&mut self, limit: Rc<BigInt>) {
- match limit.to_biguint() {
- Some(limit) => self.limits.push(InferenceLimit(limit + &self.count)),
- _ => panic!("add_limit: expected unsigned integer.")
+ // returns the count.
+ pub(crate) fn add_limit(&mut self, limit: Rc<BigInt>, b: usize) -> Rc<BigInt> {
+ let limit = Rc::new(&*limit + &self.count);
+
+ match self.limits.last().cloned() {
+ Some((ref inner_limit, _)) if *inner_limit <= limit => {},
+ _ => self.limits.push((limit, b))
};
+
+ Rc::new(self.count.clone())
}
- pub(crate) fn remove_limit(&mut self) -> Option<BigUint> {
- self.limits.pop().map(|i| i.0 - &self.count)
+ // returns the count.
+ pub(crate) fn remove_limit(&mut self, b: usize) -> Rc<BigInt> {
+ if let Some((_, bp)) = self.limits.last().cloned() {
+ if bp == b {
+ self.limits.pop();
+ }
+ }
+
+ Rc::new(self.count.clone())
}
pub(crate) fn is_empty(&self) -> bool {
self.limits.is_empty()
}
-
+
pub(crate) fn into_inner(&mut self) -> Box<CallPolicy> {
let mut new_inner: Box<CallPolicy> = Box::new(DefaultCallPolicy {});
swap(&mut self.prev_policy, &mut new_inner);
self.prev_policy.retry_me_else(machine_st, offset)?;
self.increment()
}
-
+
fn retry(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
{
self.prev_policy.retry(machine_st, offset)?;
self.increment()
}
-
+
fn trust_me(&mut self, machine_st: &mut MachineState) -> CallResult
{
self.prev_policy.trust_me(machine_st)?;
self.increment()
}
-
+
fn trust(&mut self, machine_st: &mut MachineState, offset: usize) -> CallResult
{
self.prev_policy.trust(machine_st, offset)?;
},
&BuiltInInstruction::InferenceLevel => { // X1 = R, X2 = B.
let a1 = self[temp_v!(1)].clone();
- let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
+ let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
match a2 {
Addr::Con(Constant::Usize(bp)) =>
- if self.b <= bp {
+ if self.b <= bp + 1 {
let a2 = Addr::Con(atom!("!", self.atom_tbl));
self.unify(a1, a2);
} else {
},
_ => self.fail = true
};
-
+
self.p += 1;
},
&BuiltInInstruction::InstallCleaner => {
{
Some(cut_policy) => cut_policy.push_cont_pt(addr, b, block),
None => panic!("install_cleaner: should have installed \\
-SetupCallCleanupCutPolicy.")
+ SetupCallCleanupCutPolicy.")
};
self.p += 1;
},
- &BuiltInInstruction::InstallInferenceCounter(r) => {
- let addr = self.store(self.deref(self[r].clone()));
-
+ &BuiltInInstruction::InstallInferenceCounter(r1, r2, r3) => { // A1 = B, A2 = L
+ let a1 = self.store(self.deref(self[r1].clone()));
+ let a2 = self.store(self.deref(self[r2].clone()));
+
if call_policy.downcast_ref::<CallWithInferenceLimitCallPolicy>().is_err() {
- CallWithInferenceLimitCallPolicy::new_in_place(self.atom_tbl.clone(), call_policy);
+ CallWithInferenceLimitCallPolicy::new_in_place(self.atom_tbl.clone(),
+ call_policy);
}
self.p += 1;
-
- match addr {
- Addr::Con(Constant::Number(Number::Integer(n))) =>
+
+ match (a1, a2) {
+ (Addr::Con(Constant::Usize(bp)),
+ Addr::Con(Constant::Number(Number::Integer(n)))) =>
match call_policy.downcast_mut::<CallWithInferenceLimitCallPolicy>().ok() {
- Some(call_policy) => call_policy.add_limit(n),
+ Some(call_policy) => {
+ let count = call_policy.add_limit(n, bp);
+ self[r3] = Addr::Con(Constant::Number(Number::Integer(count)));
+ },
None => panic!("install_inference_counter: should have installed \\
CallWithInferenceLimitCallPolicy.")
},
_ => {
- let atom_tbl = self.atom_tbl.clone();
+ let atom_tbl = self.atom_tbl.clone();
self.throw_exception(functor!(atom_tbl,
"type_error",
1,
[heap_atom!("integer_expected", atom_tbl)]))
}
- };
+ };
},
&BuiltInInstruction::IsAtomic(r) => {
let d = self.store(self.deref(self[r].clone()));
_ => self.fail = true
};
},
- &BuiltInInstruction::RemoveInferenceCounter(r) => {
+ &BuiltInInstruction::RemoveCallPolicyCheck => {
let restore_default =
match call_policy.downcast_mut::<CallWithInferenceLimitCallPolicy>().ok() {
Some(call_policy) => {
- if let Some(diff) = call_policy.remove_limit() {
- let addr = self[r].clone();
- self.unify(addr, Addr::Con(integer!(diff)));
- } else {
- panic!("remove_inference_counters: no limit found.");
- }
-
- if call_policy.is_empty() {
- Some(call_policy.into_inner())
+ let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
+
+ if let Addr::Con(Constant::Usize(bp)) = a1 {
+ if call_policy.is_empty() && bp == self.b {
+ Some(call_policy.into_inner())
+ } else {
+ None
+ }
} else {
- None
+ panic!("remove_inference_counter: expected Usize in A1.");
}
},
None => panic!("remove_inference_counters: requires \\
self.p += 1;
},
+ &BuiltInInstruction::RemoveInferenceCounter(r1, r2) => { // A1 = B, A2 = Count.
+ match call_policy.downcast_mut::<CallWithInferenceLimitCallPolicy>().ok() {
+ Some(call_policy) => {
+ let a1 = self.store(self.deref(self[r1].clone()));
+
+ if let Addr::Con(Constant::Usize(bp)) = a1 {
+ let count = call_policy.remove_limit(bp);
+ self[r2] = Addr::Con(Constant::Number(Number::Integer(count)));
+
+ } else {
+ panic!("remove_inference_counter: expected Usize in A1.");
+ }
+ },
+ None => panic!("remove_inference_counters: requires \\
+ CallWithInferenceLimitCallPolicy.")
+ };
+
+ self.p += 1;
+ },
&BuiltInInstruction::RestoreCutPolicy => {
let restore_default =
if let Ok(cut_policy) = cut_policy.downcast_ref::<SetupCallCleanupCutPolicy>() {
)
}
+macro_rules! sub {
+ ($at_1:expr, $at_2:expr, $o:expr) => (
+ Line::Arithmetic(ArithmeticInstruction::Sub($at_1, $at_2, $o))
+ )
+}
+
macro_rules! get_arg_call {
() => (
Line::BuiltIn(BuiltInInstruction::GetArgCall)
}
macro_rules! install_inference_counter {
- ($r:expr) => (
- Line::BuiltIn(BuiltInInstruction::InstallInferenceCounter($r))
+ ($r1:expr, $r2:expr, $r3:expr) => (
+ Line::BuiltIn(BuiltInInstruction::InstallInferenceCounter($r1, $r2, $r3))
)
}
macro_rules! remove_inference_counter {
- ($r:expr) => (
- Line::BuiltIn(BuiltInInstruction::RemoveInferenceCounter($r))
+ ($r1:expr, $r2:expr) => (
+ Line::BuiltIn(BuiltInInstruction::RemoveInferenceCounter($r1, $r2))
)
}
Line::BuiltIn(BuiltInInstruction::DefaultTrustMe)
)
}
+
+macro_rules! remove_call_policy_check {
+ () => (
+ Line::BuiltIn(BuiltInInstruction::RemoveCallPolicyCheck)
+ )
+}
pub mod indexing;
pub mod io;
pub mod iterators;
-pub mod lib;
pub mod machine;
pub mod or_stack;
pub mod parser;