From: Mark Thom Date: Tue, 10 Apr 2018 03:27:50 +0000 (-0600) Subject: throw exception when predicate not found X-Git-Tag: v0.8.110~495 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=ed9cca0750b9ccfcc7055b941b79526c6fe6a73a;p=scryer-prolog.git throw exception when predicate not found --- diff --git a/src/prolog/copier.rs b/src/prolog/copier.rs index ce738218..e3e26873 100644 --- a/src/prolog/copier.rs +++ b/src/prolog/copier.rs @@ -12,9 +12,9 @@ pub trait CopierTarget fn deref(&self, Addr) -> Addr; fn stack(&mut self) -> &mut AndStack; - // duplicate_term(L1, L2) uses Cheney's algorithm to copy the term at - // L1 to L2. forwarding_terms is kept to restore the innards of L1 - // after it's been copied to L2. + // duplicate_term(L1, L2) uses Cheney's algorithm to copy the term + // at L1 to L2. trail is kept to restore the innards of L1 after + // it's been copied to L2. fn duplicate_term(&mut self, a: Addr) where Self: IndexMut { let mut trail: Vec<(Ref, HeapCellValue)>= Vec::new(); @@ -31,13 +31,13 @@ pub trait CopierTarget match a.clone() { Addr::Lis(a) => { self[scan] = HeapCellValue::Addr(Addr::Lis(self.threshold())); - + let hcv = self[a].clone(); self.push(hcv); - + let hcv = self[a+1].clone(); self.push(hcv); - + scan += 1; }, Addr::HeapCell(_) | Addr::StackCell(_, _) => { diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index cecaf6fd..049223f8 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -210,11 +210,11 @@ pub struct MachineState { pub(crate) type CallResult = Result<(), Vec>; -fn predicate_existence_error(name: ClauseName, arity: usize) -> Vec +fn predicate_existence_error(name: ClauseName, arity: usize, h: usize) -> Vec { let name = HeapCellValue::Addr(Addr::Con(Constant::Atom(name))); - let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(4)]); + let mut error = functor!("existence_error", 2, [heap_atom!("procedure"), heap_str!(3 + h)]); error.append(&mut functor!("/", 2, [name, heap_integer!(arity)], Fixity::In)); error @@ -238,7 +238,7 @@ pub(crate) trait CallPolicy: Any { { match idx.0.get() { IndexPtr::Undefined => - return Err(predicate_existence_error(name, arity)), + return Err(predicate_existence_error(name, arity, machine_st.heap.h)), IndexPtr::Index(compiled_tl_index) => { let module_name = idx.1; @@ -258,7 +258,7 @@ pub(crate) trait CallPolicy: Any { { match idx.0.get() { IndexPtr::Undefined => - return Err(predicate_existence_error(name, arity)), + return Err(predicate_existence_error(name, arity, machine_st.heap.h)), IndexPtr::Index(compiled_tl_index) => { let module_name = idx.1; diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index da5aba13..3d893e87 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -925,6 +925,13 @@ impl MachineState { self.p = CodePtr::DirEntry(59, clause_name!("builtin")); } + fn unwind_stack(&mut self) { + self.b = self.block; + self.or_stack.truncate(self.b); + + self.fail = true; + } + fn throw_exception(&mut self, hcv: Vec) { let h = self.heap.h; @@ -1535,12 +1542,8 @@ impl MachineState { let addr = self.deref(self[temp_v!(1)].clone()); self.reset_block(addr); }, - &BuiltInInstruction::UnwindStack => { - self.b = self.block; - self.or_stack.truncate(self.b); - - self.fail = true; - }, + &BuiltInInstruction::UnwindStack => + self.unwind_stack(), &BuiltInInstruction::InternalCallN => self.handle_internal_call_n(call_policy, code_dirs), &BuiltInInstruction::Fail => { diff --git a/src/tests.rs b/src/tests.rs index b144c748..a0fabccc 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -359,8 +359,7 @@ fn test_queries_on_predicates() { assert_prolog_failure!(&mut wam, "?- p(a, b, c)."); assert_prolog_success!(&mut wam, "?- p(a, b, C).", [["C = x"]]); - submit(&mut wam, "p(X) :- q(X). p(X) :- r(X)."); - submit(&mut wam, "q(X) :- a."); + submit(&mut wam, "p(X) :- r(X)."); submit(&mut wam, "r(X) :- s(X, t). r(X) :- t(X, u)."); submit(&mut wam, "s(x, t)."); @@ -529,23 +528,6 @@ fn test_queries_on_cuts() { submit(&mut wam, "b."); assert_prolog_success!(&mut wam, "?- a(X).", [["X = c"]]); - - wam.clear(); - - assert_prolog_failure!(&mut wam, "?- c(X)."); - - submit(&mut wam, "a(X) :- b, c(X), !. a(X) :- d(X)."); - submit(&mut wam, "b."); - - assert_prolog_failure!(&mut wam, "?- a(X)."); - - submit(&mut wam, "d(d)."); - - assert_prolog_success!(&mut wam, "?- a(X).", [["X = d"]]); - - submit(&mut wam, "c(c)."); - - assert_prolog_success!(&mut wam, "?- a(X).", [["X = c"]]); } #[test] @@ -605,170 +587,6 @@ fn test_queries_on_lists() assert_prolog_failure!(&mut wam, "?- member([X, Y, Z], [a, [b, c], [b, b], [Z, x], [d, f]])."); } -#[test] -fn test_queries_on_indexed_predicates() -{ - let mut wam = Machine::new(); - - submit(&mut wam, "p(a) :- a. - p(b) :- b, f(X). - p(c) :- c, g(X). - p(f(a)) :- a. - p(g(b, c)) :- b. - p(g(b)) :- b. - p([a|b]) :- a. - p([]). - p(X) :- x. - p([c, d, e])."); - - assert_prolog_failure!(&mut wam, "?- p(a)."); - assert_prolog_failure!(&mut wam, "?- p(b)."); - assert_prolog_failure!(&mut wam, "?- p(c)."); - assert_prolog_failure!(&mut wam, "?- p(f(a))."); - assert_prolog_failure!(&mut wam, "?- p(g(b, X))."); - assert_prolog_failure!(&mut wam, "?- p(g(Y, X))."); - assert_prolog_failure!(&mut wam, "?- p(g(Y, c))."); - assert_prolog_failure!(&mut wam, "?- p(g(b))."); - assert_prolog_success!(&mut wam, "?- p([])."); - assert_prolog_success!(&mut wam, "?- p([c, d, e])."); - assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]); - assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["Y = c", "X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]); - - submit(&mut wam, "a."); - - assert_prolog_success!(&mut wam, "?- p(a)."); - assert_prolog_failure!(&mut wam, "?- p(b)."); - assert_prolog_failure!(&mut wam, "?- p(c)."); - assert_prolog_success!(&mut wam, "?- p(f(a))."); - assert_prolog_failure!(&mut wam, "?- p(g(b, X))."); - assert_prolog_failure!(&mut wam, "?- p(g(Y, X))."); - assert_prolog_failure!(&mut wam, "?- p(g(Y, c))."); - assert_prolog_failure!(&mut wam, "?- p(g(b))."); - assert_prolog_success!(&mut wam, "?- p([])."); - assert_prolog_success!(&mut wam, "?- p([c, d, e])."); - assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]); - assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"], - ["Y = c", "X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]); - - submit(&mut wam, "b."); - submit(&mut wam, "f(x)."); - - assert_prolog_success!(&mut wam, "?- p(a)."); - assert_prolog_success!(&mut wam, "?- p(b)."); - assert_prolog_failure!(&mut wam, "?- p(c)."); - assert_prolog_success!(&mut wam, "?- p(f(a))."); - assert_prolog_success!(&mut wam, "?- p(g(b, X)).", [["X = c"]]); - assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", [["X = c", "Y = b"]]); - assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", [["Y = b"]]); - assert_prolog_success!(&mut wam, "?- p(g(b))."); - assert_prolog_success!(&mut wam, "?- p([])."); - assert_prolog_success!(&mut wam, "?- p([c, d, e])."); - assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]); - assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"], - ["Y = c", "X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]); - - submit(&mut wam, "c."); - submit(&mut wam, "g(X)."); - - assert_prolog_success!(&mut wam, "?- p(a)."); - assert_prolog_success!(&mut wam, "?- p(b)."); - assert_prolog_success!(&mut wam, "?- p(c)."); - assert_prolog_success!(&mut wam, "?- p(f(a))."); - assert_prolog_success!(&mut wam, "?- p(g(b, X)).", [["X = c"]]); - assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", [["X = c", "Y = b"]]); - assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", [["Y = b"]]); - assert_prolog_success!(&mut wam, "?- p(g(b))."); - assert_prolog_success!(&mut wam, "?- p([])."); - assert_prolog_success!(&mut wam, "?- p([c, d, e])."); - assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = [e]"]]); - assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"], - ["Y = c", "X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = [e]", "Y = c"]]); - assert_prolog_failure!(&mut wam, "?- p(blah)."); - - submit(&mut wam, "x."); - - assert_prolog_success!(&mut wam, "?- p(a)."); - assert_prolog_success!(&mut wam, "?- p(b)."); - assert_prolog_success!(&mut wam, "?- p(c)."); - assert_prolog_success!(&mut wam, "?- p(true(a))."); - - assert_prolog_success!(&mut wam, "?- p(g(b, X)).", [["X = c"], - ["X = _2"]]); - assert_prolog_success!(&mut wam, "?- p(g(Y, X)).", [["X = c", "Y = b"], - ["X = _2", "Y = _1"]]); - assert_prolog_success!(&mut wam, "?- p(g(Y, c)).", [["Y = b"], - ["Y = _1"]]); - - assert_prolog_success!(&mut wam, "?- p(g(b))."); - assert_prolog_success!(&mut wam, "?- p([])."); - assert_prolog_success!(&mut wam, "?- p([c, d, e])."); - - assert_prolog_success!(&mut wam, "?- p([c, d | X]).", [["X = _1"], - ["X = [e]"]]); - assert_prolog_success!(&mut wam, "?- p([c|X]).", [["X = _1"], - ["X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|X]).", [["X = b", "Y = a"], - ["X = _1", "Y = _0"], - ["Y = c", "X = [d, e]"]]); - assert_prolog_success!(&mut wam, "?- p([Y|[d|Xs]]).", [["Xs = _1", "Y = _2"], - ["Xs = [e]", "Y = c"]]); - - assert_prolog_success!(&mut wam, "?- p(blah)."); - - submit(&mut wam, "ind_call(or(X, Y)) :- ind_call(X). - ind_call(trace) :- trace. - ind_call(or(X, Y)) :- ind_call(Y). - ind_call(notrace) :- notrace. - ind_call(nl) :- nl. - ind_call(X) :- builtin(X). - ind_call(X) :- extern(X). - ind_call(ind_call(X)) :- ind_call(X). - ind_call(repeat). - ind_call(repeat) :- ind_call(repeat). - ind_call(false)."); - - assert_prolog_success!(&mut wam, "?- ind_call(repeat)."); - assert_prolog_success!(&mut wam, "?- ind_call(false)."); - assert_prolog_success!(&mut wam, "?- ind_call(ind_call(repeat))."); - assert_prolog_success!(&mut wam, "?- ind_call(ind_call(false))."); - assert_prolog_failure!(&mut wam, "?- ind_call(notrace)."); - assert_prolog_failure!(&mut wam, "?- ind_call(nl)."); - assert_prolog_failure!(&mut wam, "?- ind_call(builtin(X))."); - assert_prolog_failure!(&mut wam, "?- ind_call(extern(X))."); - - submit(&mut wam, "notrace."); - submit(&mut wam, "nl."); - - assert_prolog_success!(&mut wam, "?- ind_call(repeat)."); - assert_prolog_success!(&mut wam, "?- ind_call(false)."); - assert_prolog_success!(&mut wam, "?- ind_call(ind_call(repeat))."); - assert_prolog_success!(&mut wam, "?- ind_call(ind_call(false))."); - assert_prolog_success!(&mut wam, "?- ind_call(notrace)."); - assert_prolog_success!(&mut wam, "?- ind_call(nl)."); - assert_prolog_failure!(&mut wam, "?- ind_call(builtin(X))."); - assert_prolog_failure!(&mut wam, "?- ind_call(extern(X))."); - - submit(&mut wam, "builtin(X)."); - submit(&mut wam, "extern(x)."); - - assert_prolog_success!(&mut wam, "?- ind_call(repeat)."); - assert_prolog_success!(&mut wam, "?- ind_call(false)."); - assert_prolog_success!(&mut wam, "?- ind_call(ind_call(repeat))."); - assert_prolog_success!(&mut wam, "?- ind_call(ind_call(false))."); - assert_prolog_success!(&mut wam, "?- ind_call(notrace)."); - assert_prolog_success!(&mut wam, "?- ind_call(nl)."); - assert_prolog_success!(&mut wam, "?- ind_call(builtin(X)).", [["X = _1"]]); - assert_prolog_success!(&mut wam, "?- ind_call(extern(X)).", [["X = _1"]]); -} - #[test] fn test_queries_on_conjuctive_queries() { let mut wam = Machine::new();