]> Repositorios git - scryer-prolog.git/commitdiff
add catch/throw support, make exceptions and arithmetic tests pass.
authorMark Thom <[email protected]>
Thu, 10 May 2018 07:43:36 +0000 (01:43 -0600)
committerMark Thom <[email protected]>
Thu, 10 May 2018 07:43:36 +0000 (01:43 -0600)
src/main.rs
src/prolog/ast.rs
src/prolog/io.rs
src/prolog/lib/builtins.pl
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/system_calls.rs
src/prolog/toplevel.rs
src/tests.rs

index 1e4a7e29d173a3f1496bdd95d3c2441a5e3a1ea5..a220f41a5c567d5e03534565f9df657c39e67e94 100644 (file)
@@ -11,7 +11,6 @@ use prolog::machine::*;
 #[cfg(test)]
 mod tests;
 
-pub static BUILTINS: &str = include_str!("./prolog/lib/builtins.pl");
 pub static LISTS: &str   = include_str!("./prolog/lib/lists.pl");
 pub static CONTROL: &str = include_str!("./prolog/lib/control.pl");
 pub static QUEUES: &str = include_str!("./prolog/lib/queues.pl");
@@ -27,20 +26,6 @@ fn parse_and_compile_line(wam: &mut Machine, buffer: &str)
     }
 }
 
-fn load_init_str(wam: &mut Machine, src_str: &str)
-{
-    match compile_listing(wam, src_str) {
-        EvalSession::Error(_) => panic!("failed to parse batch from string."),
-        _ => {}
-    }
-}
-
-fn load_init_str_and_include(wam: &mut Machine, src_str: &str, module: &'static str)
-{
-    load_init_str(wam, src_str);
-    wam.use_module_in_toplevel(clause_name!(module));
-}
-
 fn prolog_repl() {
     let mut wam = Machine::new();
 
index 34623fee7128fd2233d1110b9c324cc37062a08c..f4d47303005fb96615abaa53e63b4c58eb9469f1 100644 (file)
@@ -711,13 +711,31 @@ pub struct Rule {
 
 #[derive(Copy, Clone, PartialEq)]
 pub enum SystemClauseType {
-    SkipMaxList
+    CleanUpBlock,
+    EraseBall,
+    Fail,
+    GetBall,
+    GetCurrentBlock,
+    InstallNewBlock,
+    ResetBlock,
+    SetBall,
+    SkipMaxList,
+    UnwindStack
 }
 
 impl SystemClauseType {
     pub fn arity(&self) -> usize {
         match self {
-            &SystemClauseType::SkipMaxList => 4
+            &SystemClauseType::CleanUpBlock => 1,
+            &SystemClauseType::EraseBall => 0,
+            &SystemClauseType::Fail => 0,
+            &SystemClauseType::GetBall => 1,
+            &SystemClauseType::GetCurrentBlock => 1,
+            &SystemClauseType::InstallNewBlock => 1,
+            &SystemClauseType::ResetBlock => 1,
+            &SystemClauseType::SetBall => 1,
+            &SystemClauseType::SkipMaxList => 4,
+            &SystemClauseType::UnwindStack => 0
         }
     }
     
@@ -727,13 +745,31 @@ impl SystemClauseType {
     
     pub fn name(&self) -> ClauseName {
         match self {
+            &SystemClauseType::CleanUpBlock => clause_name!("$clean_up_block"),
+            &SystemClauseType::EraseBall => clause_name!("$erase_ball"),
+            &SystemClauseType::Fail => clause_name!("$fail"),
+            &SystemClauseType::GetBall => clause_name!("$get_ball"),
+            &SystemClauseType::GetCurrentBlock => clause_name!("$get_current_block"),
+            &SystemClauseType::InstallNewBlock => clause_name!("$install_new_block"),
+            &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
+            &SystemClauseType::SetBall => clause_name!("$set_ball"),
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
+            &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
         }
     }
 
     pub fn from(name: &str, arity: usize) -> Option<SystemClauseType> {
         match (name, arity) {
+            ("$clean_up_block", 1) => Some(SystemClauseType::CleanUpBlock),
+            ("$erase_ball", 0) => Some(SystemClauseType::EraseBall),
+            ("$fail", 0) => Some(SystemClauseType::Fail),
+            ("$get_ball", 1) => Some(SystemClauseType::GetBall),
+            ("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
+            ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
+            ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
+            ("$set_ball", 1) => Some(SystemClauseType::SetBall),
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
+            ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
             _ => None
         }
     }
index 52876615f3b6397a512bc39a1b12fe1b683ed601..974876a8563a663b114e3a9c24cb98e38ae47046 100644 (file)
@@ -601,6 +601,22 @@ pub fn compile_packet(wam: &mut Machine, tl: TopLevelPacket) -> EvalSession
     }
 }
 
+pub static BUILTINS: &str = include_str!("./lib/builtins.pl");
+
+pub fn load_init_str(wam: &mut Machine, src_str: &str)
+{
+    match compile_listing(wam, src_str) {
+        EvalSession::Error(_) => panic!("failed to parse batch from string."),
+        _ => {}
+    }
+}
+
+pub fn load_init_str_and_include(wam: &mut Machine, src_str: &str, module: &'static str)
+{
+    load_init_str(wam, src_str);
+    wam.use_module_in_toplevel(clause_name!(module));
+}
+
 pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession
 {
     fn get_module_name(module: &Option<Module>) -> ClauseName {
index 7a46bf8d6b1b2b0e689378b64db33f5aae390d0e..2d1856e89e1d64760cea0f7ee632d4651da4b657 100644 (file)
@@ -1,8 +1,9 @@
 :- op(400, yfx, /).
 
-:- module(builtins, [(+)/2, (*)/2, (-)/2, (/)/2, (/\)/2, (\/)/2, (is)/2,
-       (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2, (mod)/2,
-       (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (>=)/2, (=<)/2]).
+:- module(builtins, [(=)/2, (+)/2, (*)/2, (-)/2, (/)/2, (/\)/2,
+       (\/)/2, (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2,
+       (>>)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (-)/1,
+       (>=)/2, (=<)/2, (->)/2, (;)/2, catch/3, throw/1, true/0, false/0]).
 
 % arithmetic operators.
 :- op(700, xfx, is).
@@ -19,6 +20,7 @@
 :- op(400, yfx, >>).
 :- op(400, yfx, mod).
 :- op(400, yfx, rem).
+:- op(200, fy, -).
 
 % arithmetic comparison operators.
 :- op(700, xfx, >).
 :- op(700, xfx, =:=).
 :- op(700, xfx, >=).
 :- op(700, xfx, =<).
+
+% conditional operators.
+:- op(1050, xfy, ->).
+:- op(1100, xfy, ;).
+
+% unify.
+:- op(700, xfx, =).
+
+% unify.
+X = X.
+
+true.
+
+false :- '$fail'.
+
+% conditions.
+/*
+','(G1, G2) :- get_cp(B), ','(G1, G2, B).
+
+','(!, ','(G1, G2), B) :- set_cp(B), ','(G1, G2, B).
+','(!, !, B) :- set_cp(B).
+','(!, G, B) :- set_cp(B), G.
+','(G, ','(G2, G3), B) :- !, G, ','(G2, G3, B).
+','(G, !, B) :- !, G, set_cp(B).
+','(G1, G2, _) :- G1, G2.
+
+;(G1, G2) :- get_cp(B), ;(G1, G2, B).
+
+;(G1 -> G2, _, B) :- ->(G1, G2, B).
+;(_  -> _ , G, B) :- set_cp(B), G.
+;(!, _, B) :- set_cp(B).
+;(_, !, B) :- set_cp(B).
+;(G, _, _) :- G.
+;(_, G, _) :- G.
+
+G1 -> G2 :- get_cp(B), ->(G1, G2, B).
+
+->(G1, !, B)  :- call(G1), set_cp(B).
+->(G1, G2, B) :- call(G1), set_cp(B), call(G2).
+*/
+
+% exceptions.
+catch(G,C,R) :- '$get_current_block'(Bb), catch(G,C,R,Bb).
+
+catch(G,C,R,Bb) :- '$install_new_block'(NBb), call(G), end_block(Bb, NBb).
+catch(G,C,R,Bb) :- '$reset_block'(Bb), '$get_ball'(Ball), handle_ball(Ball, C, R).
+
+end_block(Bb, NBb) :- '$clean_up_block'(NBb), '$reset_block'(Bb).
+end_block(Bb, NBb) :- '$reset_block'(NBb), '$fail'.
+
+handle_ball(Ball, C, R) :- Ball = C, !, '$erase_ball', call(R).
+handle_ball(_, _, _) :- '$unwind_stack'.
+
+throw(Ball) :- '$set_ball'(Ball), '$unwind_stack'.
index 7913137abff62a0c0a410e91b0a52d223cfaca8e..55d22ed975763d21c86911248e97970a3c793019 100644 (file)
@@ -400,37 +400,35 @@ pub(crate) trait CallPolicy: Any {
         Ok(())
     }
 
-    fn call_n<'a>(&mut self, machine_st: &mut MachineState, arity: usize,
+    fn call_n<'a>(&mut self, machine_st: &mut MachineState, mut arity: usize,
                   code_dirs: CodeDirs<'a>, lco: bool)
                   -> CallResult
     {
-        loop {
-            if let Some((name, mut arity)) = machine_st.setup_call_n(arity) {
-                let user = clause_name!("user");
-
-                if machine_st.fail {
-                    return Ok(());
-                }
-                
-                match ClauseType::from(name.clone(), arity, None) {
-                    ClauseType::CallN => {                        
-                        machine_st.num_of_args = arity;
-                        machine_st.handle_internal_call_n();
-                                                
-                        continue;
-                    },
-                    ClauseType::BuiltIn(built_in) =>
-                        machine_st.setup_built_in_call(built_in, lco),
-                    ClauseType::Inlined(inlined) =>
-                        machine_st.execute_inlined(&inlined),
-                    ClauseType::Op(..) | ClauseType::Named(..) =>
-                        if let Some(idx) = code_dirs.get(name.clone(), arity, user) {
-                            self.context_call(machine_st, name, arity, idx, lco)?;
-                        } else {
-                            return Err(machine_st.existence_error(name, arity));
-                        }
-                };
-            }
+        while let Some((name, inner_arity)) = machine_st.setup_call_n(arity) {
+            let user = clause_name!("user");
+
+            match ClauseType::from(name.clone(), inner_arity, None) {
+                ClauseType::CallN => {
+                    machine_st.handle_internal_call_n(inner_arity);
+                    
+                    if machine_st.fail {
+                        return Ok(());
+                    }
+                    
+                    arity = inner_arity;
+                    continue;
+                },
+                ClauseType::BuiltIn(built_in) =>
+                    machine_st.setup_built_in_call(built_in, lco),
+                ClauseType::Inlined(inlined) =>
+                    machine_st.execute_inlined(&inlined),
+                ClauseType::Op(..) | ClauseType::Named(..) =>
+                    if let Some(idx) = code_dirs.get(name.clone(), inner_arity, user) {
+                        self.context_call(machine_st, name, inner_arity, idx, lco)?;
+                    } else {
+                        return Err(machine_st.existence_error(name, inner_arity));
+                    }
+            };
 
             break;
         }
@@ -441,10 +439,82 @@ pub(crate) trait CallPolicy: Any {
     fn system_call(&mut self, machine_st: &mut MachineState, ct: &SystemClauseType) -> CallResult
     {
         match ct {
+            &SystemClauseType::CleanUpBlock => {
+                let nb = machine_st.store(machine_st.deref(machine_st[temp_v!(1)].clone()));
+
+                match nb {
+                    Addr::Con(Constant::Usize(nb)) => {
+                        let b = machine_st.b - 1;
+
+                        if nb > 0 && machine_st.or_stack[b].b == nb {
+                            machine_st.b = machine_st.or_stack[nb - 1].b;
+                            machine_st.or_stack.truncate(machine_st.b);
+                        }                        
+                    },
+                    _ => machine_st.fail = true
+                };
+
+                Ok(())
+            },
+            &SystemClauseType::EraseBall => {
+                machine_st.ball.reset();
+                Ok(())
+            },
+            &SystemClauseType::Fail => {
+                machine_st.fail = true;
+                Ok(())
+            },
+            &SystemClauseType::GetBall => {
+                let addr = machine_st.store(machine_st.deref(machine_st[temp_v!(1)].clone()));
+                let h = machine_st.heap.h;
+
+                if machine_st.ball.stub.len() > 0 {
+                    machine_st.copy_and_align_ball_to_heap();
+                } else {
+                    machine_st.fail = true;
+                    return Ok(());
+                }
+
+                let ball = machine_st.heap[h].as_addr(h);
+
+                match addr.as_var() {
+                    Some(r) => machine_st.bind(r, ball),                    
+                    _ => machine_st.fail = true
+                };
+
+                Ok(())
+            },
+            &SystemClauseType::GetCurrentBlock => {
+                let c = Constant::Usize(machine_st.block);
+                let addr = machine_st[temp_v!(1)].clone();
+
+                machine_st.write_constant_to_var(addr, c);
+                Ok(())
+            },
+            &SystemClauseType::InstallNewBlock => {
+                machine_st.block = machine_st.b;
+                
+                let c = Constant::Usize(machine_st.block);
+                let addr = machine_st[temp_v!(1)].clone();
+
+                machine_st.write_constant_to_var(addr, c);
+                Ok(())
+            },
+            &SystemClauseType::ResetBlock => {
+                let addr = machine_st.deref(machine_st[temp_v!(1)].clone());
+                machine_st.reset_block(addr);
+                Ok(())
+            },
+            &SystemClauseType::SetBall => {
+                machine_st.set_ball();
+                Ok(())
+            },
             &SystemClauseType::SkipMaxList => {
                 machine_st.skip_max_list()?;
-                machine_st.p += 1;
-
+                Ok(())
+            },
+            &SystemClauseType::UnwindStack => {
+                machine_st.unwind_stack();
                 Ok(())
             }
         }
@@ -549,7 +619,7 @@ pub(crate) trait CallPolicy: Any {
 
                 let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
                 let heap_addr = Addr::HeapCell(machine_st.to_list(key_pairs));
-
+                
                 let r2 = machine_st[temp_v!(2)].clone();
                 machine_st.unify(r2, heap_addr);
 
@@ -564,8 +634,10 @@ pub(crate) trait CallPolicy: Any {
 
                 Ok(())
             },
-            &BuiltInClauseType::System(ref ct) =>
-                self.system_call(machine_st, ct),
+            &BuiltInClauseType::System(ref ct) => {
+                self.system_call(machine_st, ct)?;
+                return_from_clause!(lco, machine_st)
+            }
         }
     }
 }
index bc12c399b30f1e66ae8109a6e6d3edaabfa944d2..1e368c5ff0d00dda4926786db15cef600bf32def 100644 (file)
@@ -80,7 +80,7 @@ impl MachineState {
         };
     }
 
-    fn bind(&mut self, r1: Ref, a2: Addr) {
+    pub(super) fn bind(&mut self, r1: Ref, a2: Addr) {
         let t2 = self.store(a2);
 
         match r1 {
@@ -273,7 +273,7 @@ impl MachineState {
         }
     }
 
-    fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
+    pub(super) fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
         let addr = self.deref(addr);
 
         match self.store(addr) {
@@ -1011,9 +1011,9 @@ impl MachineState {
         }
     }
 
-    pub(super) fn handle_internal_call_n(&mut self)
+    pub(super) fn handle_internal_call_n(&mut self, arity: usize)
     {
-        let arity = self.num_of_args + 1;
+        let arity = arity + 1;
         let pred  = self.registers[1].clone();
 
         for i in 2 .. arity {
@@ -1310,12 +1310,9 @@ impl MachineState {
         Ordering::Equal
     }
 
-    fn reset_block(&mut self, addr: Addr) {
+    pub(super) fn reset_block(&mut self, addr: Addr) {
         match self.store(addr) {
-            Addr::Con(Constant::Usize(b)) => {
-                self.block = b;
-                self.p += 1;
-            },
+            Addr::Con(Constant::Usize(b)) => self.block = b,
             _ => self.fail = true
         };
     }
index 7f0238b28a299394d6743bbfbe01c9c3252cd538..1d1c55b15aa0bc025c0078d287cf7b93fdd95747 100644 (file)
@@ -152,11 +152,5 @@ impl MachineState {
         };
 
         Ok(())
-    }
-    
-    pub(super) fn execute_system(&mut self, ct: &SystemClauseType) -> Result<(), MachineError> {
-        match ct {
-            &SystemClauseType::SkipMaxList => self.skip_max_list()
-        }
-    }
+    }    
 }
index addb26e92b38ce4948f4342891b66a2388cfc60b..27986de45f3c7c3051b924445cfc91f10cf0c133 100644 (file)
@@ -393,7 +393,7 @@ impl RelationWorker {
                 if name.as_str() == "!" || name.as_str() == "blocked_!" {
                     Ok(QueryTerm::BlockedCut)
                 } else {
-                    Ok(QueryTerm::Clause(r, ClauseType::Named(name, CodeIndex::default()), vec![]))
+                    Ok(QueryTerm::Clause(r, ClauseType::from(name, 0, None), vec![]))
                 },
             Term::Var(_, ref v) if v.as_str() == "!" =>
                 Ok(QueryTerm::UnblockedCut(Cell::default())),
index df7cbae2a3cbc3520ea474a02470d5382f900c2e..f965a3888eeba454210ea8d309c36696ebffef16 100644 (file)
@@ -934,10 +934,96 @@ fn test_queries_on_call_n()
 }
 
 #[test]
-fn test_queries_on_exceptions()
+fn test_queries_on_arithmetic()
 {
     let mut wam = Machine::new();
+    load_init_str_and_include(&mut wam, BUILTINS, "builtins");
+    
+    assert_prolog_success!(&mut wam, "?- X is 1, X is X.", [["X = 1"]]);
+    assert_prolog_failure!(&mut wam, "?- X is 1, X is X + 1.");
+    assert_prolog_success!(&mut wam, "?- X is 1, X is X + 0.", [["X = 1"]]);
+    assert_prolog_success!(&mut wam, "?- X is 1, X is X * 1.", [["X = 1"]]);
+    assert_prolog_failure!(&mut wam, "?- X is 1, X is X * 2.");
+
+    assert_prolog_failure!(&mut wam, "?- X is 1 + a.");
+    assert_prolog_failure!(&mut wam, "?- X is 1 + Y.");
+    assert_prolog_success!(&mut wam, "?- Y is 2 + 2 - 2, X is 1 + Y, X = 3.",
+                           [["X = 3", "Y = 2"]]);
+    assert_prolog_failure!(&mut wam, "?- Y is 2 + 2 - 2, X is 1 + Y, X = 2.");
+
+    assert_prolog_success!(&mut wam, "?- 6 is 6.");
+    assert_prolog_success!(&mut wam, "?- 6 is 3 + 3.");
+    assert_prolog_success!(&mut wam, "?- 6 is 3 * 2.");
+    assert_prolog_failure!(&mut wam, "?- 7 is 3 * 2.");
+    assert_prolog_failure!(&mut wam, "?- 7 is 3.5 * 2.");
+    assert_prolog_success!(&mut wam, "?- 7.0 is 3.5 * 2.");
+    assert_prolog_success!(&mut wam, "?- 7.0 is 14 / 2.");
+    assert_prolog_failure!(&mut wam, "?- 4.666 is 14.0 / 3.");
+    assert_prolog_success!(&mut wam, "?- 4.0 is 8.0 / 2.");
+
+    submit(&mut wam, "f(X) :- X is 5 // 0.");
+
+    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+                           [["E = zero_divisor", "X = _1"]]);
+
+    submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0.");
+
+    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+                           [["E = zero_divisor", "X = _1"]]);
+
+    submit(&mut wam, "f(X) :- X is 5.0 / 0.");
+
+    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
+                           [["E = zero_divisor", "X = _1"]]);
+
+    assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
+                           [["Y = 4", "X = 4", "Z = 8"]]);
+
+    assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.",
+                           [["Y = 4", "X = 4", "Z = 8"]]);
+
+    assert_prolog_success!(&mut wam, "?- X is (3 rdiv 4) / 2, Y is 3 rdiv 8, X = Y.",
+                           [["X = 3/8", "Y = 3/8"]]);
+
+    assert_prolog_success!(&mut wam, "?- X is 10 xor -4, X is -10.", [["X = -10"]]);
+    assert_prolog_success!(&mut wam, "?- X is 4 xor -7, X is -3.", [["X = -3"]]);
+    assert_prolog_success!(&mut wam, "?- X is 10 xor 5 + 55, X = 70.", [["X = 70"]]);
+
+    assert_prolog_success!(&mut wam, "?- X is 10 rem -3, X = 1.",   [["X = 1"]]);
+    assert_prolog_success!(&mut wam, "?- X is 10 mod -3, X is -2.", [["X = -2"]]);
+
+    assert_prolog_success!(&mut wam, "?- call(is, X, 3 + 4).", [["X = 7"]]);
 
+    assert_prolog_success!(&mut wam, "?- Y is 3 + 3, call(is, X, Y + 4).", [["Y = 6", "X = 10"]]);
+    assert_prolog_success!(&mut wam, "?- call(is, X, 3 + 4.5).", [["X = 7.5"]]);
+    assert_prolog_success!(&mut wam, "?- X is 2 rdiv 3, call(is, Y, X*X).", [["X = 2/3", "Y = 4/9"]]);
+
+    assert_prolog_failure!(&mut wam, "?- call(>, 3, 3 + 3).");
+    assert_prolog_failure!(&mut wam, "?- X is 3 + 3, call(>, 3, X).");
+
+    assert_prolog_success!(&mut wam, "?- X is 3 + 3, call(<, 3, X).", [["X = 6"]]);
+    assert_prolog_success!(&mut wam, "?- X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]);
+
+    assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 0), error(E, _), true).",
+                           [["X = _5", "E = evaluation_error(zero_divisor)"]]);
+
+    assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]);
+
+    submit(&mut wam, "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ;
+                                     var(X) -> Sum = 1, X = 1 ).");
+
+    assert_prolog_success!(&mut wam, "?- f(X, Sum).", [["X = 1", "Sum = 1"]]);
+    assert_prolog_success!(&mut wam, "?- f(5, Sum).", [["Sum = 33"]]);
+    assert_prolog_success!(&mut wam, "?- f(5, 33).");
+    assert_prolog_failure!(&mut wam, "?- f(5, 32).");
+}
+
+#[test]
+fn test_queries_on_exceptions()
+{
+    let mut wam = Machine::new();
+    load_init_str_and_include(&mut wam, BUILTINS, "builtins");
+    
     submit(&mut wam, "f(a). f(_) :- throw(stuff).");
     submit(&mut wam, "handle(stuff).");
 
@@ -1037,91 +1123,7 @@ fn test_queries_on_exceptions()
                             ["E = an_error_1", "X = _1"],
                             ["E = an_error_2", "X = _1"]]);
 }
-
-#[test]
-fn test_queries_on_arithmetic()
-{
-    let mut wam = Machine::new();
-
-    assert_prolog_success!(&mut wam, "?- X is 1, X is X.", [["X = 1"]]);
-    assert_prolog_failure!(&mut wam, "?- X is 1, X is X + 1.");
-    assert_prolog_success!(&mut wam, "?- X is 1, X is X + 0.", [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is 1, X is X * 1.", [["X = 1"]]);
-    assert_prolog_failure!(&mut wam, "?- X is 1, X is X * 2.");
-
-    assert_prolog_failure!(&mut wam, "?- X is 1 + a.");
-    assert_prolog_failure!(&mut wam, "?- X is 1 + Y.");
-    assert_prolog_success!(&mut wam, "?- Y is 2 + 2 - 2, X is 1 + Y, X = 3.",
-                           [["X = 3", "Y = 2"]]);
-    assert_prolog_failure!(&mut wam, "?- Y is 2 + 2 - 2, X is 1 + Y, X = 2.");
-
-    assert_prolog_success!(&mut wam, "?- 6 is 6.");
-    assert_prolog_success!(&mut wam, "?- 6 is 3 + 3.");
-    assert_prolog_success!(&mut wam, "?- 6 is 3 * 2.");
-    assert_prolog_failure!(&mut wam, "?- 7 is 3 * 2.");
-    assert_prolog_failure!(&mut wam, "?- 7 is 3.5 * 2.");
-    assert_prolog_success!(&mut wam, "?- 7.0 is 3.5 * 2.");
-    assert_prolog_success!(&mut wam, "?- 7.0 is 14 / 2.");
-    assert_prolog_failure!(&mut wam, "?- 4.666 is 14.0 / 3.");
-    assert_prolog_success!(&mut wam, "?- 4.0 is 8.0 / 2.");
-
-    submit(&mut wam, "f(X) :- X is 5 // 0.");
-
-    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
-                           [["E = zero_divisor", "X = _1"]]);
-
-    submit(&mut wam, "f(X) :- X is (5 rdiv 1) / 0.");
-
-    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
-                           [["E = zero_divisor", "X = _1"]]);
-
-    submit(&mut wam, "f(X) :- X is 5.0 / 0.");
-
-    assert_prolog_success!(&mut wam, "?- catch(f(X), error(evaluation_error(E), _), true), E = zero_divisor.",
-                           [["E = zero_divisor", "X = _1"]]);
-
-    assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z is X+Y.",
-                           [["Y = 4", "X = 4", "Z = 8"]]);
-
-    assert_prolog_success!(&mut wam, "?- X is ((3 + 4) // 2) + 2 - 1 // 1, Y is 2+2, Z = 8, Y is 4.",
-                           [["Y = 4", "X = 4", "Z = 8"]]);
-
-    assert_prolog_success!(&mut wam, "?- X is (3 rdiv 4) / 2, Y is 3 rdiv 8, X = Y.",
-                           [["X = 3/8", "Y = 3/8"]]);
-
-    assert_prolog_success!(&mut wam, "?- X is 10 xor -4, X is -10.", [["X = -10"]]);
-    assert_prolog_success!(&mut wam, "?- X is 4 xor -7, X is -3.", [["X = -3"]]);
-    assert_prolog_success!(&mut wam, "?- X is 10 xor 5 + 55, X = 70.", [["X = 70"]]);
-
-    assert_prolog_success!(&mut wam, "?- X is 10 rem -3, X = 1.",   [["X = 1"]]);
-    assert_prolog_success!(&mut wam, "?- X is 10 mod -3, X is -2.", [["X = -2"]]);
-
-    assert_prolog_success!(&mut wam, "?- call(is, X, 3 + 4).", [["X = 7"]]);
-
-    assert_prolog_success!(&mut wam, "?- Y is 3 + 3, call(is, X, Y + 4).", [["Y = 6", "X = 10"]]);
-    assert_prolog_success!(&mut wam, "?- call(is, X, 3 + 4.5).", [["X = 7.5"]]);
-    assert_prolog_success!(&mut wam, "?- X is 2 rdiv 3, call(is, Y, X*X).", [["X = 2/3", "Y = 4/9"]]);
-
-    assert_prolog_failure!(&mut wam, "?- call(>, 3, 3 + 3).");
-    assert_prolog_failure!(&mut wam, "?- X is 3 + 3, call(>, 3, X).");
-
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3, call(<, 3, X).", [["X = 6"]]);
-    assert_prolog_success!(&mut wam, "?- X is 3 + 3, X =:= 3 + 3.", [["X = 6"]]);
-
-    assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 0), error(E, _), true).",
-                           [["X = _5", "E = evaluation_error(zero_divisor)"]]);
-
-    assert_prolog_success!(&mut wam, "?- catch(call(is, X, 3 // 3), _, true).", [["X = 1"]]);
-
-    submit(&mut wam, "f(X, Sum) :- ( integer(X) -> Sum is X + X * X + 3 ;
-                                     var(X) -> Sum = 1, X = 1 ).");
-
-    assert_prolog_success!(&mut wam, "?- f(X, Sum).", [["X = 1", "Sum = 1"]]);
-    assert_prolog_success!(&mut wam, "?- f(5, Sum).", [["Sum = 33"]]);
-    assert_prolog_success!(&mut wam, "?- f(5, 33).");
-    assert_prolog_failure!(&mut wam, "?- f(5, 32).");
-}
-
+/*
 #[test]
 fn test_queries_on_conditionals()
 {
@@ -1714,3 +1716,4 @@ fn test_queries_on_skip_max_list() {
     assert_prolog_success!(&mut wam, "?- '$skip_max_list'(N, 9, non_list, Xs).",
                            [["Xs = non_list", "N = 0"]]);
 }
+*/