From de88fdc4dcc12ac6d89a51d06f8d806731f98e9a Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 17 Nov 2019 20:18:11 -0400 Subject: [PATCH 01/21] correct failure to observe last call position in queries' --- src/prolog/machine/code_repo.rs | 2 +- src/prolog/machine/machine_indices.rs | 6 +++--- src/prolog/machine/machine_state.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/prolog/machine/code_repo.rs b/src/prolog/machine/code_repo.rs index df80644f..fee126e9 100644 --- a/src/prolog/machine/code_repo.rs +++ b/src/prolog/machine/code_repo.rs @@ -134,7 +134,7 @@ impl CodeRepo { ); Some(RefOrOwned::Owned(call_clause)) } - &CodePtr::CallN(arity, _) => { + &CodePtr::CallN(arity, _, last_call) => { let call_clause = call_clause!(ClauseType::CallN, arity, 0, last_call); Some(RefOrOwned::Owned(call_clause)) } diff --git a/src/prolog/machine/machine_indices.rs b/src/prolog/machine/machine_indices.rs index ef3b7d2c..384bd3fc 100644 --- a/src/prolog/machine/machine_indices.rs +++ b/src/prolog/machine/machine_indices.rs @@ -309,7 +309,7 @@ pub enum REPLCodePtr { #[derive(Clone, PartialEq)] pub enum CodePtr { BuiltInClause(BuiltInClauseType, LocalCodePtr), // local is the successor call. - CallN(usize, LocalCodePtr), // arity, local. + CallN(usize, LocalCodePtr, bool), // arity, local, last call. Local(LocalCodePtr), DynamicTransaction(DynamicTransactionType, LocalCodePtr), // the type of transaction, the return pointer. REPL(REPLCodePtr, LocalCodePtr), // the REPL code, the return pointer. @@ -320,7 +320,7 @@ impl CodePtr { pub fn local(&self) -> LocalCodePtr { match self { &CodePtr::BuiltInClause(_, ref local) - | &CodePtr::CallN(_, ref local) + | &CodePtr::CallN(_, ref local, _) | &CodePtr::Local(ref local) => local.clone(), &CodePtr::VerifyAttrInterrupt(p) => LocalCodePtr::DirEntry(p), &CodePtr::REPL(_, p) | &CodePtr::DynamicTransaction(_, p) => p, @@ -418,7 +418,7 @@ impl Add for CodePtr { | p @ CodePtr::VerifyAttrInterrupt(_) | p @ CodePtr::DynamicTransaction(..) => p, CodePtr::Local(local) => CodePtr::Local(local + rhs), - CodePtr::CallN(_, local) | CodePtr::BuiltInClause(_, local) => { + CodePtr::CallN(_, local, _) | CodePtr::BuiltInClause(_, local) => { CodePtr::Local(local + rhs) } } diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 8bcd2018..edb5f419 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -854,7 +854,7 @@ pub(crate) trait CallPolicy: Any { return Ok(()); } - machine_st.p = CodePtr::CallN(arity, machine_st.p.local()); + machine_st.p = CodePtr::CallN(arity, machine_st.p.local(), machine_st.last_call); } ClauseType::BuiltIn(built_in) => { machine_st.setup_built_in_call(built_in.clone()); From 6f9477f0bb4e6d84a1bf4e2a1e46930eb7c931dc Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 17 Nov 2019 21:07:16 -0400 Subject: [PATCH 02/21] rollback changes in snapshot handling --- src/prolog/machine/mod.rs | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 051ad296..527a2301 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -560,12 +560,6 @@ impl Machine { snapshot.s = self.machine_st.s; snapshot.tr = self.machine_st.tr; snapshot.pstr_tr = self.machine_st.pstr_tr; - snapshot.p = self.machine_st.p.clone(); - snapshot.cp = self.machine_st.cp; - snapshot.attr_var_init = mem::replace( - &mut self.machine_st.attr_var_init, - AttrVarInitializer::new(0, 0) - ); snapshot.num_of_args = self.machine_st.num_of_args; snapshot.fail = self.machine_st.fail; @@ -579,7 +573,6 @@ impl Machine { snapshot.block = self.machine_st.block; snapshot.ball = self.machine_st.ball.take(); - snapshot.heap_locs = mem::replace(&mut self.machine_st.heap_locs, IndexMap::new()); snapshot.lifted_heap = mem::replace(&mut self.machine_st.lifted_heap, vec![]); snapshot @@ -593,9 +586,6 @@ impl Machine { self.machine_st.s = snapshot.s; self.machine_st.tr = snapshot.tr; self.machine_st.pstr_tr = snapshot.pstr_tr; - self.machine_st.p = snapshot.p; - self.machine_st.cp = snapshot.cp; - self.machine_st.attr_var_init = snapshot.attr_var_init; self.machine_st.num_of_args = snapshot.num_of_args; self.machine_st.fail = snapshot.fail; @@ -613,7 +603,6 @@ impl Machine { self.machine_st.block = snapshot.block; self.machine_st.ball = snapshot.ball.take(); - self.machine_st.heap_locs = mem::replace(&mut snapshot.heap_locs, IndexMap::new()); self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]); } @@ -637,37 +626,19 @@ impl Machine { // so hold onto it locally and restore it after the compiler has finished. self.machine_st.fail = false; let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]); + self.dynamic_transaction(trans_type, p); + self.code_repo.cached_query = cached_query; if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p { - self.code_repo.cached_query = cached_query; break; } - - self.code_repo.cached_query = cached_query; } _ => break }; } } - - #[cfg(test)] - pub fn test_heap_view(&self, mut output: Outputter) -> Outputter - where - Outputter: HCValueOutputter, - { - for (var, addr) in self.machine_st.heap_locs.iter() { - output = self.machine_st.print_var_eq( - var.clone(), - addr.clone(), - &self.indices.op_dir, - output, - ); - } - - output - } } impl MachineState { From 66bebff01eb14c5a8273fec3875aa535731d44e5 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 18 Nov 2019 23:17:56 -0700 Subject: [PATCH 03/21] add setup_call_cleanup tests, expand builtins tests --- src/tests/builtins.pl | 73 +++++++++++++++++++++++++++++++-- src/tests/setup_call_cleanup.pl | 27 ++++++++++++ 2 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/tests/setup_call_cleanup.pl diff --git a/src/tests/builtins.pl b/src/tests/builtins.pl index 47d1e509..4b614023 100644 --- a/src/tests/builtins.pl +++ b/src/tests/builtins.pl @@ -1,5 +1,6 @@ :- use_module(library(lists)). +:- use_module(library(non_iso)). test_queries_on_builtins :- \+ atom(_), @@ -20,7 +21,7 @@ test_queries_on_builtins :- atomic(0.0), \+ atomic([a,b,c]), \+ atomic(atop(the_trees)), - ( var(X), X = 3, atomic(X) ), + findall(X, ( var(X), X = 3, atomic(X) ), [3]), \+ ( var(X), X = 3, var(X) ), arg(1, f(a,b,c,d), a), arg(2, f(a,b,c,d), b), @@ -36,7 +37,6 @@ test_queries_on_builtins :- length([a,b,c], 3), copy_term([[[[X,Y],Y],X]],[[[[Z,V],V],Z]]), \+ ( X = g(X,Y), Y = f(X), copy_term(Y,g(Z)) ), - (X = g(X,Y), Y = f(X), copy_term(Y,f(Z))), float(3.14159269), \+ float(3), \+ float("sdfsa"), @@ -44,7 +44,7 @@ test_queries_on_builtins :- \+ float([1,2,3]), \+ float([1,2,_]), \+ (X is 3 rdiv 4, float(X)), - ( X is 3 rdiv 4, rational(X) ), + \+ \+ (X is 3 rdiv 4, rational(X)), \+ rational(3), \+ rational(f(_)), \+ rational("sdfa"), @@ -59,6 +59,71 @@ test_queries_on_builtins :- \+ compound(3.14159269), \+ compound(3), \+ compound("sdfsa"), - \+ compound(atom). + \+ compound(atom), + \+ string(functor(string)), + \+ string(3.14159269), + \+ string(3), + \+ string(f(X)), + string("sdfsa"), + \+ string(atom), + \+ string([1,2,3]), + \+ string([1,2,X]), + \+ \+ ( X = nonvar, nonvar(X) ), + \+ nonvar(X), + \+ \+ nonvar(f(X)), + nonvar(functor(nonvar)), + nonvar(3.14159269), + nonvar(3), + nonvar("sdfsa"), + nonvar(atom), + nonvar([1,2,3]), + \+ \+ nonvar([1,2,X]), + \+ \+ (A = f(A), ground(f(f(A))),ground(f(A)),ground(A)), + \+ (B = f(A),ground(B)), + \+ (B = f(A),ground(A)), + \+ \+ ( ground(x),ground(f(x)),X = f(x),ground(g(f(X),[a,b])) ), + \+ \+ (A = f(A),g(A,B) == g(f(A),B)), + \+ (A = f(A),g(A,B) == g(f(A),b)), + \+ (A == B), + \+ (A == 12.1), + \+ \+ (X = x,f(X,x) == f(x,X)), + \+ (A = f(A),g(A,B) \== g(f(A),B)), + \+ \+ (A = f(A),g(A,B) \== g(f(A),b)), + \+ \+ (A \== B), + \+ \+ (A \== 12.1), + \+ (X = x,f(X,x) \== f(x,X)), + \+ \+ (X @=< Y), + \+ (X @>= Y), + \+ (X @> Y), + \+ \+ (X @>= X), + \+ (atom @=< "string"), + \+ \+ (atom @=< atom), + \+ (atom @=< aaa), + \+ \+ (atom @>= "string"), + \+ \+ (X is 3 + 3,X @>= Y), + \+ \+ (f(X) @>= f(X)), + \+ \+ (f(X) @>= a), + \+ (f(X) @=< a), + [1,2] @=< [1,2], + \+ ([1,2,3] @=< [1,2]), + \+ \+ ([] @=< [1,2]), + \+ ([] @< 1), + \+ ([] @< "string"), + \+ ([] @< atom), + atom @< [], + 1.1 @< 1, + 1.0 @=< 1, + 1 @=< 1.0, + \+ \+ (variant(X, Y)), + \+ (variant(f(X), f(x))), + \+ \+ (variant(X, X)), + \+ \+ (variant(f(x), f(x))), + \+ (variant([X,Y,Z], [V,W,V])), + \+ \+ (variant([X,Y,Z], [V,W,Z])), + \+ \+ (variant([X,Y,X], [V,W,V])), + \+ \+ (g(B) = B, g(A) = A, variant(A, B)), + keysort([1-1,1-1],[1-1,1-1]), + findall(Sorted, keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted), [[1-a,1-z,1-a,2-99,2-44,3-f(_)]]), + findall(X, keysort([X-1,1-1],[2-1,1-1]), [2]). :- initialization(test_queries_on_builtins). diff --git a/src/tests/setup_call_cleanup.pl b/src/tests/setup_call_cleanup.pl new file mode 100644 index 00000000..b3c6a9bb --- /dev/null +++ b/src/tests/setup_call_cleanup.pl @@ -0,0 +1,27 @@ + +:- use_module(library(non_iso)). + +test_queries_on_setup_call_cleanup :- + \+ setup_call_cleanup(false, _, _), + catch(setup_call_cleanup(true, throw(unthrown), _), error(instantiation_error, _), true), + setup_call_cleanup(true, true, (true ; throw(x))), + findall(X, setup_call_cleanup(true, X = 1, X = 2), [1]), + findall(X, setup_call_cleanup(true, true, X = 2), [2]), + findall(E, catch(setup_call_cleanup(true, X=true, X), error(E, _), true), [instantiation_error]), + catch(setup_call_cleanup(X=throw(ex), true, X), ex, true), + findall([S,G,C], setup_call_cleanup(S = 1, G = 2, C = 3), [[1,2,3]]), + findall([S,G,C], setup_call_cleanup((S=1;S=2), G=3, C=4), [[1,3,4]]), + findall([S,G], setup_call_cleanup(S=1, G=2, writeq(S+G)), [[1,2]]), + findall([S,G], setup_call_cleanup(S=1, (G=2;G=3), writeq(S+G)), [[1,2],[1,3]]), + findall([S,G], (setup_call_cleanup(S=1, G=2, writeq(S+G>A+B)), A = 3, B = 4), [[1,2]]), + findall([S,G,E], catch(setup_call_cleanup(S=1, (G=2;G=3,throw(x)), writeq(S+G)), E, true), [[1,2,_],[_,_,x]]), + findall([S,B,G], (setup_call_cleanup(S=1, (G=2;G=3),writeq(S+G>B)), B=4, !), [[1,4,2]]), + findall([S,G,B], (setup_call_cleanup(S=1,G=2,writeq(S+G>B)),B=3,!), [[1,2,3]]), + findall([S,G,B], (setup_call_cleanup(S=1,(G=2;false),writeq(S+G>B)),B=3,!), [[1,2,3]]), + findall([S,G,B], (setup_call_cleanup(S=1,(G=2;S=2),writeq(S+G>B)), B=3, !), [[1,2,3]]), + catch((setup_call_cleanup(S=1,(G=2;G=3), writeq(S+G>B)), B=4, !, throw(x)), x, true), + findall(Pat, catch(setup_call_cleanup(true,throw(goal),throw(cl)), Pat, true), [goal]), + findall(Pat, catch(( setup_call_cleanup(true,(G=1;G=2),throw(cl)), throw(cont)), Pat, true), [cont]), + findall([X,Y], (setup_call_cleanup(true, (X=1;X=2), writeq(a)), setup_call_cleanup(true,(Y=1;Y=2),writeq(b)), !), [[1,1]]). + +:- initialization(test_queries_on_setup_call_cleanup). From c0a49b6a664d773415a1348e8e50827f646f752b Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Tue, 19 Nov 2019 18:48:46 +0800 Subject: [PATCH 04/21] Fix README formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b8b564c..d6c31433 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Extend Scryer Prolog to include the following, among other features: - [x] Backtrackable and non-backtrackable global variables via `bb_get/2` `bb_put/2` (non-backtrackable) and `bb_b_put/2` (backtrackable). -- [ ] clp(B) and clp($\mathbb{Z}$) as builtin libraries (_in progress_). +- [ ] clp(B) and clp(ℤ) as builtin libraries (_in progress_). - [ ] Streams and predicates for stream control (_in progress_). - [ ] An incremental compacting garbage collector satisfying the five properties of "Precise Garbage Collection in Prolog." @@ -388,4 +388,4 @@ local_member(X, Xs) :- member(X, Xs). ``` The user listing can also be terminated by placing `end_of_file.` at -the end of the stream. \ No newline at end of file +the end of the stream. From 17f9695ab2bea20615228ff33b3153fc031d9735 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 19 Nov 2019 10:13:59 -0400 Subject: [PATCH 05/21] remove tests.rs module from main.rs --- src/main.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 60e553d3..c44f9379 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,9 +20,6 @@ use crate::prolog::read::*; use std::sync::atomic::Ordering; -#[cfg(test)] -mod tests; - extern fn handle_sigint(signal: libc::c_int) { let signal = signal::Signal::from_c_int(signal).unwrap(); if signal == signal::Signal::SIGINT { From 2b625b1094b6dc506fb1650ccd9de2edff57ea7f Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 19 Nov 2019 20:08:52 -0700 Subject: [PATCH 06/21] commit Cargo.lock --- .gitignore | 1 - Cargo.lock | 564 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 564 insertions(+), 1 deletion(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index c7653cce..eafdaf52 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ target/ -Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..75f81231 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,564 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrayref" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "blake2b_simd" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byteorder" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crossbeam-utils" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dirs" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dirs-sys" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "downcast" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "failure" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "gmp-mpfr-sys" +version = "1.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "indexmap" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lexical" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lexical-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.62" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nix" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "nodrop" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ordered-float" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "prolog_parser" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_users" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ref_thread_local" +version = "0.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rug" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gmp-mpfr-sys 1.1.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rust-argon2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustyline" +version = "5.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ryu" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "scryer-prolog" +version = "0.8.116" +dependencies = [ + "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "downcast 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "prolog_parser 0.8.34 (registry+https://github.com/rust-lang/crates.io-index)", + "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stackvector" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "static_assertions" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synstructure" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" +"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55" +"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" +"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" +"checksum blake2b_simd 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bf775a81bb2d464e20ff170ac20316c7b08a43d11dbc72f0f82e8e8d3d6d0499" +"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" +"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +"checksum downcast 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum gmp-mpfr-sys 1.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72592cd7513feefa5e41414825c42e839120d2f09e10c6094105d066072955fb" +"checksum indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6d89e0948bf10c08b9ecc8ac5b83f07f857ebe2c0cbe38de15b4e4f510356" +"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +"checksum lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c106ed999697325a540c43d66a8d5175668cd96d7eb0bdba03a3bd98256cd698" +"checksum lexical-core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e82e023e062f1d25f807ad182008fba1b46538e999f908a08cc0c29e084462e" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +"checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +"checksum prolog_parser 0.8.34 (registry+https://github.com/rust-lang/crates.io-index)" = "3aa04502f866acaf7b448890160fba0437eb399058f984ff896a6c8ec52399a5" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" +"checksum ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6" +"checksum rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "592f3a1bba452fcfb91127354012c2b3aa580b266caef1923b16638057c038b5" +"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" +"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +"checksum rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4795e277e6e57dec9df62b515cd4991371daa80e8dc8d80d596e58722b89c417" +"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" +"checksum stackvector 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c049c77bf85fbc036484c97b008276d539d9ebff9dfbde37b632ebcd5b8746b6" +"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" +"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" +"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" From 5aaba8534fbd88200f766005be962c2177784454 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 19 Nov 2019 20:09:28 -0700 Subject: [PATCH 07/21] bump prolog_parser to version 0.8.35 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e3aea95a..e80d3c34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ lazy_static = "1.4.0" libc = "0.2.62" nix = "0.15.0" ordered-float = "0.5.0" -prolog_parser = "0.8.34" +prolog_parser = "0.8.35" ref_thread_local = "0.0.0" rug = "1.4.0" rustyline = "5.0.3" From f82c6f3fedce809b471672e4eac7eabc30a72272 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 20 Nov 2019 10:50:33 -0400 Subject: [PATCH 08/21] avoid overwriting IndexPtr's for clauses already declared dynamic (#227) --- Cargo.lock | 6 +++--- src/prolog/machine/compile.rs | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75f81231..dcef9728 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,7 +261,7 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -395,7 +395,7 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "prolog_parser 0.8.34 (registry+https://github.com/rust-lang/crates.io-index)", + "prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -533,7 +533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum prolog_parser 0.8.34 (registry+https://github.com/rust-lang/crates.io-index)" = "3aa04502f866acaf7b448890160fba0437eb399058f984ff896a6c8ec52399a5" +"checksum prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1bc16334ea998d54f73cda14254fe546c57ae0c6c990263d50f7efd6ae10ea9d" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 0f959a6e..55a916bf 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -824,8 +824,9 @@ impl ListingCompiler { .entry((name.clone(), arity)) .or_insert(vec![]); - indices.code_dir.insert((name.clone(), arity), - CodeIndex::dynamic_undefined(self.get_module_name())); + indices.code_dir + .entry((name.clone(), arity)) + .or_insert(CodeIndex::dynamic_undefined(self.get_module_name())); } &Declaration::Hook(hook, _, ref queue) if self.module.is_none() => worker .term_stream From 37ff4a821c84c5ea1d775933d1bc21c0b900a271 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Thu, 1 Aug 2019 08:25:24 -0300 Subject: [PATCH 09/21] Add feature num to use num crate in place of rug. --- .travis.yml | 1 + Cargo.lock | 67 +++++++++++++++++++++++++++--- Cargo.toml | 13 +++--- src/prolog/machine/system_calls.rs | 6 +-- src/prolog/mod.rs | 5 ++- 5 files changed, 76 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0549d16c..6d526e4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,3 +11,4 @@ matrix: script: - cargo build --verbose --all - cargo test --verbose --all + - cargo test --verbose --all --no-default-features --features num diff --git a/Cargo.lock b/Cargo.lock index dcef9728..48178a56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,6 +13,11 @@ dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" version = "0.3.35" @@ -230,17 +235,62 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "num-traits" -version = "0.1.43" +name = "num-bigint" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rug-adapter" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.6" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "ordered-float" @@ -265,6 +315,7 @@ version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -394,6 +445,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -501,6 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" +"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55" "checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" @@ -529,8 +582,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3b2e0b4f3320ed72aaedb9a5ac838690a8047c7b275da22711fddff4f8a14229" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a" +"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454" +"checksum num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab3f405f69d14cdcf0ca44599eb074093633a53ec3d402be0bf1e57709c7502" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6" "checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1bc16334ea998d54f73cda14254fe546c57ae0c6c990263d50f7efd6ae10ea9d" diff --git a/Cargo.toml b/Cargo.toml index e80d3c34..676e1707 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,10 @@ edition = "2018" [build-dependencies] indexmap = "1.0.2" +[features] +default = ["rug", "prolog_parser/rug"] +num = ["num-rug-adapter", "prolog_parser/num"] + [dependencies] dirs = "2.0.2" downcast = "0.10.0" @@ -18,11 +22,10 @@ indexmap = "1.0.2" lazy_static = "1.4.0" libc = "0.2.62" nix = "0.15.0" +num-rug-adapter = { optional = true, version = "0.1.1" } ordered-float = "0.5.0" -prolog_parser = "0.8.35" +prolog_parser = { version = "0.8.35", default-features = false } ref_thread_local = "0.0.0" -rug = "1.4.0" +rug = { version = "1.4.0", optional = true } rustyline = "5.0.3" - -[dependencies.termion] -version = "1.4.0" +termion = "1.4.0" diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index cd494313..7a52632b 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1302,11 +1302,7 @@ impl MachineState { let result = { let mut rand = RANDOM_STATE.borrow_mut(); - if rand.bits(1) == 0 { - true - } else { - false - } + rand.bits(1) == 0 }; self.fail = result; diff --git a/src/prolog/mod.rs b/src/prolog/mod.rs index 3ec028e4..bce7eba3 100644 --- a/src/prolog/mod.rs +++ b/src/prolog/mod.rs @@ -1,8 +1,11 @@ extern crate dirs; extern crate ordered_float; extern crate prolog_parser; +#[cfg(feature = "rug")] extern crate rug; -extern crate rustyline; +#[cfg(feature = "num-rug-adapter")] +extern crate num_rug_adapter as rug; +extern crate rustyline; #[macro_use] mod macros; From 1139b3b4c19d72e99522a17703639813a2320101 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 20 Nov 2019 23:50:51 -0700 Subject: [PATCH 10/21] small test updates --- src/prolog/toplevel.pl | 1 + src/tests/builtins.pl | 8 +++---- src/tests/rules.pl | 52 ++++++++++++++++++++++++------------------ 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index f9eba5dd..f5a8f484 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -30,6 +30,7 @@ ; consult(Item) ) ; catch(throw(error(type_error(atom, Item), repl/0)), + E, '$print_exception_with_check'(E)) ). '$instruction_match'(Term, VarList) :- diff --git a/src/tests/builtins.pl b/src/tests/builtins.pl index 4b614023..9b3760d1 100644 --- a/src/tests/builtins.pl +++ b/src/tests/builtins.pl @@ -21,7 +21,7 @@ test_queries_on_builtins :- atomic(0.0), \+ atomic([a,b,c]), \+ atomic(atop(the_trees)), - findall(X, ( var(X), X = 3, atomic(X) ), [3]), + \+ \+ findall(X, ( var(X), X = 3, atomic(X) ), [3]), \+ ( var(X), X = 3, var(X) ), arg(1, f(a,b,c,d), a), arg(2, f(a,b,c,d), b), @@ -35,7 +35,7 @@ test_queries_on_builtins :- catch(functor(_,"sdf",3),error(type_error(atom,[s,d,f]),_),true), f(1,2,3) =.. [f,1,2,3], length([a,b,c], 3), - copy_term([[[[X,Y],Y],X]],[[[[Z,V],V],Z]]), + \+ \+ copy_term([[[[X,Y],Y],X]],[[[[Z,V],V],Z]]), \+ ( X = g(X,Y), Y = f(X), copy_term(Y,g(Z)) ), float(3.14159269), \+ float(3), @@ -123,7 +123,7 @@ test_queries_on_builtins :- \+ \+ (variant([X,Y,X], [V,W,V])), \+ \+ (g(B) = B, g(A) = A, variant(A, B)), keysort([1-1,1-1],[1-1,1-1]), - findall(Sorted, keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted), [[1-a,1-z,1-a,2-99,2-44,3-f(_)]]), - findall(X, keysort([X-1,1-1],[2-1,1-1]), [2]). + \+ \+ findall(Sorted, keysort([2-99,1-a,3-f(_),1-z,1-a,2-44],Sorted), [[1-a,1-z,1-a,2-99,2-44,3-f(_)]]), + \+ \+ findall(X, keysort([X-1,1-1],[2-1,1-1]), [2]). :- initialization(test_queries_on_builtins). diff --git a/src/tests/rules.pl b/src/tests/rules.pl index 2931d6f6..45bfaf6d 100644 --- a/src/tests/rules.pl +++ b/src/tests/rules.pl @@ -10,46 +10,54 @@ q(q, s). r(s, t). test_queries_on_rules :- - findall([X,Y], p(X, Y), [[q, t]]), + \+ \+ findall([X,Y], p(X, Y), [[q, t]]), p(q, t), \+ p(t, q), - findall(T, p(q, T), [t]), + \+ \+ findall(T, p(q, T), [t]), \+ p(t, t), - retract((p(X,Y) :- q(X,Z), r(Z, Y))), + \+ \+ retract((p(X,Y) :- q(X,Z), r(Z, Y))), retract(q(_,_)), - assertz((p(X,_) :- q(f(f(X)), _), r(_, _))), - assertz(q(f(f(X)), r)), + \+ \+ assertz((p(X,_) :- q(f(f(X)), _), r(_, _))), + \+ \+ assertz(q(f(f(X)), r)), p(_,_), retract(q(_,_)), assertz(q(f(f(x)), r)), - findall(X, p(X,_), [x]), - retract((p(X,_) :- q(f(f(X)), _), r(_, _))), + \+ \+ findall(X, p(X,_), [x]), + \+ \+ retract((p(X,_) :- q(f(f(X)), _), r(_, _))), retract(q(_,_)), - assertz((p(X, Y) :- q(X, Y), r(X, Y))), + \+ \+ assertz((p(X, Y) :- q(X, Y), r(X, Y))), assertz(q(s, t)), retract(r(_,_)), - assertz((r(X, Y) :- r(a))), + \+ \+ assertz((r(X, Y) :- r(a))), assertz(r(a)), - findall([X,Y], p(X, Y), [[s,t]]), + \+ \+ findall([X,Y], p(X, Y), [[s,t]]), \+ p(t, _), - findall(T, p(s, T), [t]), - findall(S, p(S, t), [s]), - assertz((p(f(f(a), g(b), X), g(b), h) :- q(X, Y))), + \+ \+ findall(T, p(s, T), [t]), + \+ \+ findall(S, p(S, t), [s]), + \+ \+ assertz((p(f(f(a), g(b), X), g(b), h) :- q(X, _))), retract(q(_,_)), assertz(q(_,_)), - findall([X,Y,Z], p(f(X, Y, Z), g(b), h), [[f(a), g(b), _]]), + \+ \+ findall([X,Y,Z], p(f(X, Y, Z), g(b), h), [[f(a), g(b), _]]), \+ p(f(X, g(_), Z), g(Z), X), - findall([X,Y,Z], p(f(X, g(Y), Z), g(Z), h), [[f(a), b, b]]), - findall([X,Y,Z], p(Z, Y, X), [[h, g(b), f(f(a),g(b),_)]]), - findall([X,Y,Z], p(f(X, Y, Z), Y, h), [[f(a), g(b), _]]), - retract((p(X, Y) :- q(X, Y), r(X, Y))), - retract((p(f(f(a), g(b), X), g(b), h) :- q(X, _))), - assertz((p(_, f(_, Y, _)) :- h(Y))), + \+ \+ findall([X,Y,Z], p(f(X, g(Y), Z), g(Z), h), [[f(a), b, b]]), + \+ \+ findall([X,Y,Z], p(Z, Y, X), [[h, g(b), f(f(a),g(b),_)]]), + \+ \+ findall([X,Y,Z], p(f(X, Y, Z), Y, h), [[f(a), g(b), _]]), + \+ \+ retract((p(X, Y) :- q(X, Y), r(X, Y))), + \+ \+ retract((p(f(f(a), g(b), X), g(b), h) :- q(X, _))), + \+ \+ assertz((p(_, f(_, Y, _)) :- h(Y))), assertz(h(y)), - findall(Y, p(_, f(_, Y, _)), [y]). + \+ \+ findall(Y, p(_, f(_, Y, _)), [y]). p(_, f(_, y, _)), \+ p(_, f(_, z, _)), - retract((p(_, f(_, Y, _)) :- h(Y))). + \+ \+ retract((p(_, f(_, Y, _)) :- h(Y))), + cleanup. + +cleanup :- abolish(p/3), + abolish(p/2), + abolish(q/2), + abolish(r/2), + abolish(r/1), + abolish(h/1). :- initialization(test_queries_on_rules). From b31b23e41ca26e9a5d85e0d9a47ddb43c4fde7d5 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 21 Nov 2019 16:26:00 -0400 Subject: [PATCH 11/21] add conditional bracketing to equations printed by toplevel --- src/prolog/machine/machine_state.rs | 2 +- src/prolog/toplevel.pl | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index edb5f419..c632e059 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -461,7 +461,7 @@ pub(crate) trait CallPolicy: Any { let b = machine_st.b - 1; let n = machine_st.or_stack[b].num_args(); - for i in 1..n + 1 { + for i in 1 .. n + 1 { machine_st.registers[i] = machine_st.or_stack[b][i].clone(); } diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index f9eba5dd..e3c8a605 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -44,11 +44,27 @@ ; write('false.'), nl ). +'$needs_bracketing'(Value, Op) :- + catch((functor(Value, F, _), + current_op(EqPrec, EqSpec, Op), + current_op(FPrec, _, F)), + _, + false), + ( EqPrec < FPrec -> true + ; EqPrec == FPrec, + memberchk(EqSpec, [fx,xfx,yfx]) + ). + '$write_goal'(G, VarList) :- ( G = (Var = Value) -> write(Var), write(' = '), - write_term(Value, [quoted(true), variable_names(VarList)]) + ( '$needs_bracketing'(Value, (=)) -> + write('('), + write_term(Value, [quoted(true), variable_names(VarList)]), + write(')') + ; write_term(Value, [quoted(true), variable_names(VarList)]) + ) ; G == [] -> write('true') ; write_term(G, [quoted(true), variable_names(VarList)]) From 24ffdc27247a0ab91ff025831d5853169ce4e5ed Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Fri, 22 Nov 2019 20:38:03 -0700 Subject: [PATCH 12/21] correct bug, dead code in toplevel.pl --- src/prolog/toplevel.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 6b24e2ca..ba2b0ee9 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -1,8 +1,8 @@ -:- module('$toplevel', ['$repl'/1, consult/1, use_module/1, use_module/2]). - :- use_module(library(lists)). :- use_module(library(si)). +:- module('$toplevel', ['$repl'/1, consult/1, use_module/1, use_module/2]). + '$repl'(ListOfModules) :- maplist('$use_list_of_modules', ListOfModules), false. @@ -29,9 +29,10 @@ catch('$$compile_batch', E, '$print_exception_with_check'(E)) ; consult(Item) ) - ; catch(throw(error(type_error(atom, Item), repl/0)), + ; !, + catch(throw(error(type_error(atom, Item), repl/0)), E, - '$print_exception_with_check'(E)) + '$print_exception_with_check'(E)) ). '$instruction_match'(Term, VarList) :- '$submit_query_and_print_results'(Term, VarList), @@ -91,8 +92,7 @@ write(' .'), nl ) - ; repeat, - thread_goals(Goals, ThreadedGoals, (',')), + ; thread_goals(Goals, ThreadedGoals, (',')), '$write_eq'(ThreadedGoals, VarList), '$raw_input_read_char'(C), ( C == (';'), !, From 7bf6a230f3c8ceec740d463a03cc67879cde5c4d Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 24 Nov 2019 12:50:53 -0700 Subject: [PATCH 13/21] record module-level term_expansion and goal_expansion as inner predicates (#228) --- src/prolog/forms.rs | 2 ++ src/prolog/machine/compile.rs | 20 ++++++++++++--- src/prolog/machine/modules.rs | 46 +++++++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/prolog/forms.rs b/src/prolog/forms.rs index ed64a67f..c2e4ac14 100644 --- a/src/prolog/forms.rs +++ b/src/prolog/forms.rs @@ -337,6 +337,8 @@ pub struct Module { pub goal_expansions: (Predicate, VecDeque), pub user_term_expansions: (Predicate, VecDeque), // term expansions inherited from the user scope. pub user_goal_expansions: (Predicate, VecDeque), // same for goal_expansions. + pub local_term_expansions: (Predicate, VecDeque), // expansions local to the module. + pub local_goal_expansions: (Predicate, VecDeque), pub inserted_expansions: bool, // has the module been successfully inserted into toplevel?? pub is_impromptu_module: bool, } diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 55a916bf..19a20425 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -448,7 +448,8 @@ fn add_toplevel_code(wam: &mut Machine, code: Code, indices: IndexStore) { } #[inline] -fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, indices: IndexStore) { +fn add_module_code(wam: &mut Machine, mut module: Module, code: Code, indices: IndexStore) +{ module.code_dir.extend(indices.code_dir); module.op_dir.extend(indices.op_dir.into_iter()); @@ -683,7 +684,8 @@ impl ListingCompiler { .or_insert((Predicate::new(), VecDeque::from(vec![]))); if let Some(ref mut module) = &mut self.module { - module.add_module_expansion_record(hook, clause.clone(), queue.clone()); + module.add_expansion_record(hook, clause.clone(), queue.clone()); + module.add_local_expansion(hook, clause.clone(), queue.clone()); } (module_preds.0).0.push(clause); @@ -918,7 +920,7 @@ fn compile_work_impl( mut indices: IndexStore, mut results: GatherResult, ) -> Result<(), SessionError> { - let module_code = compiler.generate_code( + let mut module_code = compiler.generate_code( results.worker_results, wam, &mut indices.code_dir, @@ -969,7 +971,17 @@ fn compile_work_impl( wam.indices.use_module(&mut wam.code_repo, wam.machine_st.flags, &module)?; wam.indices.insert_module(module); - } else { + } else { + // compile the module-level goal and term expansions and store + // their locations to the module's code_dir. + let offset = module_code.len() + toplvl_code.len(); + let decls = module.take_local_expansions(); + + if !decls.is_empty() { + let code = compiler.generate_code(decls, &wam, &mut indices.code_dir, offset)?; + module_code.extend(code.into_iter()); + } + add_module_code(wam, module, module_code, indices); } diff --git a/src/prolog/machine/modules.rs b/src/prolog/machine/modules.rs index ace04f65..b6c07e8f 100644 --- a/src/prolog/machine/modules.rs +++ b/src/prolog/machine/modules.rs @@ -7,6 +7,7 @@ use crate::prolog::machine::machine_errors::*; use crate::prolog::machine::machine_indices::*; use std::collections::VecDeque; +use std::mem; // Module's and related types are defined in forms. impl Module { @@ -19,6 +20,8 @@ impl Module { user_goal_expansions: (Predicate::new(), VecDeque::from(vec![])), term_expansions: (Predicate::new(), VecDeque::from(vec![])), goal_expansions: (Predicate::new(), VecDeque::from(vec![])), + local_term_expansions: (Predicate::new(), VecDeque::from(vec![])), + local_goal_expansions: (Predicate::new(), VecDeque::from(vec![])), code_dir: CodeDir::new(), op_dir: default_op_dir(), inserted_expansions: false, @@ -61,7 +64,7 @@ impl Module { Ok(()) } - pub fn add_module_expansion_record( + pub fn add_expansion_record( &mut self, hook: CompileTimeHook, clause: PredicateClause, @@ -78,6 +81,45 @@ impl Module { } } } + + pub fn add_local_expansion( + &mut self, + hook: CompileTimeHook, + clause: PredicateClause, + queue: VecDeque, + ) { + match hook { + CompileTimeHook::TermExpansion => { + (self.local_term_expansions.0).0.push(clause); + self.local_term_expansions.1.extend(queue.into_iter()); + } + CompileTimeHook::GoalExpansion => { + (self.local_goal_expansions.0).0.push(clause); + self.local_goal_expansions.1.extend(queue.into_iter()); + } + _ => {} + } + } + + pub fn take_local_expansions(&mut self) -> Vec<(Predicate, VecDeque)> + { + let term_expansions = + mem::replace(&mut self.local_term_expansions, (Predicate::new(), VecDeque::new())); + let goal_expansions = + mem::replace(&mut self.local_goal_expansions, (Predicate::new(), VecDeque::new())); + + let mut result = vec![]; + + if !(term_expansions.0).0.is_empty() { + result.push(term_expansions); + } + + if !(goal_expansions.0).0.is_empty() { + result.push(goal_expansions); + } + + result + } } pub trait SubModuleUser { @@ -283,7 +325,7 @@ impl SubModuleUser for Module { self.user_goal_expansions .1 .extend(submodule.goal_expansions.1.iter().cloned()); - + Ok(()) } } From 4e887e3a875e583c6e003d2f8800664735c0cf7c Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 24 Nov 2019 15:47:34 -0700 Subject: [PATCH 14/21] generate module-level expansion code along with rest of module code --- src/prolog/machine/compile.rs | 22 +++++++++++----------- src/prolog/machine/machine_state_impl.rs | 17 +++++++++-------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 19a20425..b24584df 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -920,7 +920,17 @@ fn compile_work_impl( mut indices: IndexStore, mut results: GatherResult, ) -> Result<(), SessionError> { - let mut module_code = compiler.generate_code( + if let Some(ref mut module) = &mut compiler.module { + // compile the module-level goal and term expansions and store + // their locations to the module's code_dir. + let decls = module.take_local_expansions(); + + if !decls.is_empty() { + results.worker_results.extend(decls.into_iter()); + } + } + + let module_code = compiler.generate_code( results.worker_results, wam, &mut indices.code_dir, @@ -972,16 +982,6 @@ fn compile_work_impl( wam.indices.use_module(&mut wam.code_repo, wam.machine_st.flags, &module)?; wam.indices.insert_module(module); } else { - // compile the module-level goal and term expansions and store - // their locations to the module's code_dir. - let offset = module_code.len() + toplvl_code.len(); - let decls = module.take_local_expansions(); - - if !decls.is_empty() { - let code = compiler.generate_code(decls, &wam, &mut indices.code_dir, offset)?; - module_code.extend(code.into_iter()); - } - add_module_code(wam, module, module_code, indices); } diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 7392d65c..60713510 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -3080,14 +3080,15 @@ impl MachineState { | ( HeapCellValue::Addr(v1 @ Addr::StackCell(..)), HeapCellValue::Addr(v2 @ Addr::HeapCell(_)), - ) => match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) { - (Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => continue, - (Some(_), _) | (_, Some(_)) => return true, - (None, None) => { - var_pairs.insert(v1.clone(), v2.clone()); - var_pairs.insert(v2, v1); - } - }, + ) => + match (var_pairs.get(&v1).cloned(), var_pairs.get(&v2).cloned()) { + (Some(ref v2_p), Some(ref v1_p)) if *v1_p == v1 && *v2_p == v2 => continue, + (Some(_), _) | (_, Some(_)) => return true, + (None, None) => { + var_pairs.insert(v1.clone(), v2.clone()); + var_pairs.insert(v2, v1); + } + }, (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => { if a1 != a2 { return true; From 834c57466fd1b2f4b6cb9eeeeb2baa68a9ea851b Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 25 Nov 2019 23:09:49 -0700 Subject: [PATCH 15/21] add operator exports to module declarations, treat them separately from predicate exports (#230)" --- src/prolog/forms.rs | 27 ++++-- src/prolog/lib/atts.pl | 13 ++- src/prolog/lib/builtins.pl | 58 ++++++------ src/prolog/lib/clpb.pl | 8 +- src/prolog/lib/dcgs.pl | 3 +- src/prolog/machine/compile.rs | 43 ++++++--- src/prolog/machine/mod.rs | 83 ++++++++++++----- src/prolog/machine/modules.rs | 163 ++++++++++++++++++++------------- src/prolog/machine/toplevel.rs | 61 +++++++++--- src/prolog/toplevel.pl | 25 ++++- 10 files changed, 313 insertions(+), 171 deletions(-) diff --git a/src/prolog/forms.rs b/src/prolog/forms.rs index c2e4ac14..aa8eeec6 100644 --- a/src/prolog/forms.rs +++ b/src/prolog/forms.rs @@ -179,7 +179,7 @@ pub enum Declaration { NonCountedBacktracking(ClauseName, usize), // name, arity Op(OpDecl), UseModule(ModuleSource), - UseQualifiedModule(ModuleSource, Vec), + UseQualifiedModule(ModuleSource, Vec), } impl Declaration { @@ -216,15 +216,20 @@ impl OpDecl { self.insert_into_op_dir(clause_name!(""), op_dir, 0); } - fn insert_into_op_dir(&self, module: ClauseName, op_dir: &mut OpDir, prec: usize) { - let (spec, name) = (self.1, self.2.clone()); - - let fixity = match spec { + #[inline] + pub fn fixity(&self) -> Fixity { + match self.1 { XFY | XFX | YFX => Fixity::In, XF | YF => Fixity::Post, FX | FY => Fixity::Pre, - _ => return, - }; + _ => unreachable!() + } + } + + pub fn insert_into_op_dir(&self, module: ClauseName, op_dir: &mut OpDir, prec: usize) { + let (spec, name) = (self.1, self.2.clone()); + + let fixity = self.fixity(); match op_dir.get(&(name.clone(), fixity)) { Some(cell) => { @@ -322,10 +327,16 @@ pub fn fetch_op_spec( pub type ModuleDir = IndexMap; +#[derive(Clone, PartialEq)] +pub enum ModuleExport { + OpDecl(OpDecl), + PredicateKey(PredicateKey), +} + #[derive(Clone)] pub struct ModuleDecl { pub name: ClauseName, - pub exports: Vec, + pub exports: Vec, } pub struct Module { diff --git a/src/prolog/lib/atts.pl b/src/prolog/lib/atts.pl index 5de6d32c..3fc36974 100644 --- a/src/prolog/lib/atts.pl +++ b/src/prolog/lib/atts.pl @@ -1,14 +1,13 @@ -:- module(atts, [attribute/1, call_residue_vars/2, '$absent_attr'/2, - '$copy_attr_list'/2, '$get_attr'/2, '$put_attr'/2, - '$absent_from_list'/2, '$get_from_list'/3, - '$add_to_list'/3, '$del_attr'/3, '$del_attr_step'/3, - '$del_attr_buried'/4, '$default_attr_list'/4]). +:- module(atts, [op(1199, fx, attribute), call_residue_vars/2, + '$absent_attr'/2, '$copy_attr_list'/2, '$get_attr'/2, + '$put_attr'/2, '$absent_from_list'/2, + '$get_from_list'/3, '$add_to_list'/3, '$del_attr'/3, + '$del_attr_step'/3, '$del_attr_buried'/4, + '$default_attr_list'/4]). :- use_module(library(dcgs)). :- use_module(library(terms)). -:- op(1199, fx, attribute). - /* represent the list of attributes belonging to a variable, of a particular module, as a list of terms of the form Module:put_atts(V, ListOfAtts). */ diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 8c018fcb..e6e0d40f 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -1,35 +1,19 @@ :- op(400, yfx, /). -/* this is an implementation specific declarative operator used to implement call_with_inference_limit/3 - and setup_call_cleanup/3. switches to the default trust_me and retry_me_else. Indexing choice - instructions are unchanged. */ -:- op(700, fx, non_counted_backtracking). - -:- module(builtins, [(=)/2, (\=)/2, (\+)/1, (^)/2, (\)/1, (+)/1, - (+)/2, (**)/2, (*)/2, (-)/1, (-)/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, (',')/2, (->)/2, (;)/2, (=..)/2, (==)/2, (\==)/2, - (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (:)/2, abolish/1, asserta/1, - assertz/1, atom_chars/2, atom_codes/2, atom_concat/3, - atom_length/2, bagof/3, catch/3, char_code/2, clause/2, - current_op/3, current_predicate/1, current_prolog_flag/2, - expand_goal/2, expand_term/2, fail/0, false/0, findall/3, - findall/4, get_char/1, halt/0, number_chars/2, number_codes/2, - once/1, op/3, read_term/2, repeat/0, retract/1, - set_prolog_flag/2, setof/3, sub_atom/5, subsumes_term/2, - term_variables/2, throw/1, true/0, unify_with_occurs_check/2, - write/1, write_canonical/1, write_term/2, writeq/1]). - % module resolution operator. :- op(600, xfy, :). user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :- - expand_op_list([Op | OtherOps], Pred, Spec, OpResults). + '$expand_op_list'([Op | OtherOps], Pred, Spec, OpResults). -expand_op_list([], _, _, []). -expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResults]) :- - expand_op_list(OtherOps, Pred, Spec, OtherResults). +'$expand_op_list'([], _, _, []). +'$expand_op_list'([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResults]) :- + '$expand_op_list'(OtherOps, Pred, Spec, OtherResults). + +/* this is an implementation specific declarative operator used to implement call_with_inference_limit/3 + and setup_call_cleanup/3. switches to the default trust_me and retry_me_else. Indexing choice + instructions are unchanged. */ +:- op(700, fx, non_counted_backtracking). % arithmetic operators. :- op(700, xfx, is). @@ -37,8 +21,7 @@ expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResu :- op(400, yfx, *). :- op(200, xfy, [**, ^]). :- op(500, yfx, [/\, \/, xor]). -:- op(400, yfx, [div, //, rdiv]). -:- op(400, yfx, [<<, >>, mod, rem]). +:- op(400, yfx, [div, //, rdiv, <<, >>, mod, rem]). :- op(200, fy, [+, -, \]). % arithmetic comparison operators. @@ -47,9 +30,6 @@ expand_op_list([Op | OtherOps], Pred, Spec, [(:- op(Pred, Spec, Op)) | OtherResu % term comparison. :- op(700, xfx, [==, \==, @=<, @>=, @<, @>]). -% the maximum arity flag. needs to be replaced with current_prolog_flag(max_arity, MAX_ARITY). -max_arity(255). - % conditional operators. :- op(1050, xfy, ->). :- op(1100, xfy, ;). @@ -58,6 +38,24 @@ max_arity(255). :- op(700, xfx, [=, =.., \=]). :- op(900, fy, \+). +:- module(builtins, [(=)/2, (\=)/2, (\+)/1, (',')/2, (->)/2, (;)/2, + (=..)/2, (:)/2, abolish/1, asserta/1, assertz/1, + atom_chars/2, atom_codes/2, atom_concat/3, + atom_length/2, bagof/3, catch/3, char_code/2, + clause/2, current_op/3, current_predicate/1, + current_prolog_flag/2, expand_goal/2, + expand_term/2, fail/0, false/0, findall/3, + findall/4, get_char/1, halt/0, max_arity/1, + number_chars/2, number_codes/2, once/1, op/3, + read_term/2, repeat/0, retract/1, + set_prolog_flag/2, setof/3, sub_atom/5, + subsumes_term/2, term_variables/2, throw/1, + true/0, unify_with_occurs_check/2, write/1, + write_canonical/1, write_term/2, writeq/1]). + +% the maximum arity flag. needs to be replaced with current_prolog_flag(max_arity, MAX_ARITY). +max_arity(255). + % unify. X = X. diff --git a/src/prolog/lib/clpb.pl b/src/prolog/lib/clpb.pl index 5aa9561a..d11c5a42 100644 --- a/src/prolog/lib/clpb.pl +++ b/src/prolog/lib/clpb.pl @@ -16,11 +16,9 @@ Public operators. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -:- op(300, fy, ~). -:- op(500, yfx, #). - -:- module(clpb, [ - sat/1, +:- module(clpb, [op(300, fy, ~), + op(500, yfx, #), + sat/1, taut/2, labeling/1, sat_count/2, diff --git a/src/prolog/lib/dcgs.pl b/src/prolog/lib/dcgs.pl index 1d69b68c..2ee8baac 100644 --- a/src/prolog/lib/dcgs.pl +++ b/src/prolog/lib/dcgs.pl @@ -1,7 +1,6 @@ -:- op(1200, xfx, -->). % :- op(1105, xfy, ('|')). -:- module(dcgs, [phrase/2, phrase/3]). +:- module(dcgs, [op(1200, xfx, -->), phrase/2, phrase/3]). :- use_module(library(lists), [append/3]). diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index b24584df..36c7bf60 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -574,7 +574,7 @@ impl ListingCompiler { submodule: ClauseName, code_repo: &mut CodeRepo, flags: MachineFlags, - exports: &Vec, + exports: &Vec, wam_indices: &mut IndexStore, indices: &mut IndexStore, ) -> Result<(), SessionError> { @@ -712,6 +712,24 @@ impl ListingCompiler { (len, queue_len) } + fn submit_op( + &mut self, + wam: &Machine, + indices: &mut IndexStore, + op_decl: &OpDecl, + ) -> Result<(), SessionError> { + let spec = get_desc( + op_decl.name(), + composite_op!( + self.module.is_some(), + &wam.indices.op_dir, + &mut indices.op_dir + ), + ); + + op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir) + } + fn process_decl( &mut self, decl: Declaration, @@ -730,6 +748,7 @@ impl ListingCompiler { .code_repo .compile_hook(hook, flags) .map_err(SessionError::from); + wam.code_repo.truncate_terms(key, len, queue_len); result @@ -738,16 +757,7 @@ impl ListingCompiler { Ok(self.add_non_counted_bt_flag(name, arity)) } Declaration::Op(op_decl) => { - let spec = get_desc( - op_decl.name(), - composite_op!( - self.module.is_some(), - &wam.indices.op_dir, - &mut indices.op_dir - ), - ); - - op_decl.submit(self.get_module_name(), spec, &mut indices.op_dir) + self.submit_op(wam, indices, &op_decl) } Declaration::UseModule(ModuleSource::Library(name)) => { let name = if !wam.indices.modules.contains_key(&name) { @@ -779,6 +789,12 @@ impl ListingCompiler { let module_name = module_decl.name.clone(); let atom_tbl = TabledData::new(module_name.to_rc()); + for export in module_decl.exports.iter() { + if let ModuleExport::OpDecl(ref op_decl) = export { + self.submit_op(wam, indices, op_decl)?; + } + } + Ok(self.module = Some(Module::new(module_decl, atom_tbl))) } else { Err(SessionError::from(ParserError::InvalidModuleDecl)) @@ -959,8 +975,9 @@ fn compile_work_impl( if let Some(mut module) = compiler.module.take() { if module.is_impromptu_module { module.module_decl.exports = indices.code_dir.keys().cloned() - .filter(|(name, _)| name.owning_module().as_str() != "builtins") - .collect(); + .filter(|(name, _)| name.owning_module().as_str() != "builtins") + .map(ModuleExport::PredicateKey) + .collect(); } let mut clause_code_generator = diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 527a2301..a562858c 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -34,6 +34,7 @@ use crate::prolog::machine::machine_errors::*; use crate::prolog::machine::machine_indices::*; use crate::prolog::machine::machine_state::*; use crate::prolog::machine::modules::*; +use crate::prolog::machine::toplevel::*; use crate::prolog::read::PrologStream; use indexmap::IndexMap; @@ -139,7 +140,7 @@ impl SubModuleUser for IndexStore { code_repo: &mut CodeRepo, flags: MachineFlags, submodule: &Module, - exports: &Vec, + exports: &Vec, ) -> Result<(), SessionError> { use_qualified_module(self, submodule, exports)?; submodule @@ -400,30 +401,64 @@ impl Machine { return; } - fn extract_predicate_indicator_list(&mut self) -> Vec + fn extract_module_export_list(&mut self) -> Result, ParserError> { - let export_list = self.machine_st[temp_v!(2)].clone(); - let mut export_list = self.machine_st.store(self.machine_st.deref(export_list)); + let mut export_list = self.machine_st[temp_v!(2)].clone(); let mut exports = vec![]; - while let Addr::Lis(l) = export_list { + while let Addr::Lis(l) = self.machine_st.store(self.machine_st.deref(export_list)) { match &self.machine_st.heap[l] { &HeapCellValue::Addr(Addr::Str(s)) => { - let name = match &self.machine_st.heap[s+1] { - &HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) => - name.clone(), - _ => - unreachable!() - }; + match &self.machine_st.heap[s] { + HeapCellValue::NamedStr(arity, ref name, _) + if *arity == 2 && name.as_str() == "/" => { + let name = match &self.machine_st.heap[s+1] { + &HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) => + name.clone(), + _ => + unreachable!() + }; + + let arity = match &self.machine_st.heap[s+2] { + &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => + arity.to_usize().unwrap(), + _ => + unreachable!() + }; + + exports.push(ModuleExport::PredicateKey((name, arity))); + } + HeapCellValue::NamedStr(arity, ref name, _) + if *arity == 3 && name.as_str() == "op" => { + let name = match &self.machine_st.heap[s+3] { + &HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) => + name.clone(), + _ => + unreachable!() + }; - let arity = match &self.machine_st.heap[s+2] { - &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => - arity.to_usize().unwrap(), - _ => - unreachable!() - }; + let spec = match &self.machine_st.heap[s+2] { + &HeapCellValue::Addr(Addr::Con(Constant::Atom(ref name, _))) => + name.clone(), + _ => + unreachable!() + }; + + let prec = match &self.machine_st.heap[s+1] { + &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => + arity.to_usize().unwrap(), + _ => + unreachable!() + }; - exports.push((name, arity)); + exports.push(ModuleExport::OpDecl(to_op_decl( + prec, + spec.as_str(), + name, + )?)); + } + _ => unreachable!() + } } _ => unreachable!() } @@ -431,7 +466,7 @@ impl Machine { export_list = self.machine_st.heap[l+1].as_addr(l+1); } - exports + Ok(exports) } fn use_module(&mut self, to_src: ToSource) @@ -489,7 +524,13 @@ impl Machine { _ => unreachable!() }; - let exports = self.extract_predicate_indicator_list(); + let exports = match self.extract_module_export_list() { + Ok(exports) => exports, + Err(e) => { + self.throw_session_error(SessionError::from(e), (clause_name!("use_module"), 2)); + return; + } + }; let load_result = match to_src(name) { ModuleSource::Library(name) => @@ -521,7 +562,7 @@ impl Machine { self.code_repo.cached_query = cached_query; if let Err(e) = result { - self.throw_session_error(e, (clause_name!("use_module"), 1)); + self.throw_session_error(e, (clause_name!("use_module"), 2)); } } diff --git a/src/prolog/machine/modules.rs b/src/prolog/machine/modules.rs index b6c07e8f..508eb77d 100644 --- a/src/prolog/machine/modules.rs +++ b/src/prolog/machine/modules.rs @@ -137,64 +137,55 @@ pub trait SubModuleUser { } fn remove_module(&mut self, mod_name: ClauseName, module: &Module) { - for (name, arity) in module.module_decl.exports.iter().cloned() { - let name = name.defrock_brackets(); + for export in module.module_decl.exports.iter().cloned() { + match export { + ModuleExport::PredicateKey((name, arity)) => { + let name = name.defrock_brackets(); - match self.get_code_index((name.clone(), arity), mod_name.clone()) { - Some(CodeIndex(ref code_idx)) => { - if &code_idx.borrow().1 != &module.module_decl.name { - continue; - } - - self.remove_code_index((name.clone(), arity)); - - // remove or respecify ops. - if arity == 2 { - if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) { - if mod_name == module.module_decl.name { - self.op_dir().remove(&(name.clone(), Fixity::In)); + match self.get_code_index((name.clone(), arity), mod_name.clone()) { + Some(CodeIndex(ref code_idx)) => { + if &code_idx.borrow().1 != &module.module_decl.name { + continue; } - } - } else if arity == 1 { - if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) { - if mod_name == module.module_decl.name { - self.op_dir().remove(&(name.clone(), Fixity::Pre)); - } - } - if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Post) - { - if mod_name == module.module_decl.name { - self.op_dir().remove(&(name.clone(), Fixity::Post)); + self.remove_code_index((name.clone(), arity)); + + // remove or respecify ops. + if arity == 2 { + if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::In) { + if mod_name == module.module_decl.name { + self.op_dir().remove(&(name.clone(), Fixity::In)); + } + } + } else if arity == 1 { + if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Pre) { + if mod_name == module.module_decl.name { + self.op_dir().remove(&(name.clone(), Fixity::Pre)); + } + } + + if let Some(mod_name) = self.get_op_module_name(name.clone(), Fixity::Post) + { + if mod_name == module.module_decl.name { + self.op_dir().remove(&(name.clone(), Fixity::Post)); + } + } } - } - } + } + _ => {} + }; + }, + ModuleExport::OpDecl(op_decl) => { + let op_dir = self.op_dir(); + op_dir.remove(&(op_decl.name(), op_decl.fixity())); } - _ => {} - }; + } } } // returns true on successful import. fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool { let name = name.defrock_brackets(); - let mut found_op = false; - - { - let mut insert_op_dir = |fix| { - if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) { - self.op_dir().insert((name.clone(), fix), op_data.clone()); - found_op = true; - } - }; - - if arity == 1 { - insert_op_dir(Fixity::Pre); - insert_op_dir(Fixity::Post); - } else if arity == 2 { - insert_op_dir(Fixity::In); - } - } if let Some(code_data) = submodule.code_dir.get(&(name.clone(), arity)) { let name = name.with_table(submodule.atom_tbl.clone()); @@ -205,7 +196,7 @@ pub trait SubModuleUser { self.insert_dir_entry(name, arity, code_data.clone()); true } else { - found_op || submodule.is_impromptu_module + submodule.is_impromptu_module } } @@ -214,30 +205,58 @@ pub trait SubModuleUser { _: &mut CodeRepo, _: MachineFlags, _: &Module, - _: &Vec, + _: &Vec, + ) -> Result<(), SessionError>; + + fn use_module( + &mut self, + _: &mut CodeRepo, + _: MachineFlags, + _: &Module ) -> Result<(), SessionError>; - fn use_module(&mut self, _: &mut CodeRepo, _: MachineFlags, _: &Module) -> Result<(), SessionError>; } pub fn use_qualified_module( user: &mut User, submodule: &Module, - exports: &Vec, + exports: &Vec, ) -> Result<(), SessionError> where User: SubModuleUser, { - for (name, arity) in exports.iter().cloned() { - if !submodule - .module_decl - .exports - .contains(&(name.clone(), arity)) - { - continue; - } + for export in exports.iter().cloned() { + match export { + ModuleExport::PredicateKey((name, arity)) => { + if !submodule + .module_decl + .exports + .contains(&ModuleExport::PredicateKey((name.clone(), arity))) + { + continue; + } - if !user.import_decl(name, arity, submodule) { - return Err(SessionError::ModuleDoesNotContainExport); + if !user.import_decl(name, arity, submodule) { + return Err(SessionError::ModuleDoesNotContainExport); + } + }, + ModuleExport::OpDecl(op_decl) => { + if !submodule + .module_decl + .exports + .contains(&ModuleExport::OpDecl(op_decl.clone())) + { + continue; + } + + let op_dir = user.op_dir(); + let prec = op_decl.0; + + op_decl.insert_into_op_dir( + submodule.module_decl.name.clone(), + op_dir, + prec, + ); + } } } @@ -248,9 +267,23 @@ pub fn use_module( user: &mut User, submodule: &Module, ) -> Result<(), SessionError> { - for (name, arity) in submodule.module_decl.exports.iter().cloned() { - if !user.import_decl(name, arity, submodule) { - return Err(SessionError::ModuleDoesNotContainExport); + for export in submodule.module_decl.exports.iter().cloned() { + match export { + ModuleExport::PredicateKey((name, arity)) => { + if !user.import_decl(name, arity, submodule) { + return Err(SessionError::ModuleDoesNotContainExport); + } + } + ModuleExport::OpDecl(op_decl) => { + let op_dir = user.op_dir(); + let prec = op_decl.0; + + op_decl.insert_into_op_dir( + submodule.module_decl.name.clone(), + op_dir, + prec, + ); + } } } @@ -283,7 +316,7 @@ impl SubModuleUser for Module { _: &mut CodeRepo, _: MachineFlags, submodule: &Module, - exports: &Vec, + exports: &Vec, ) -> Result<(), SessionError> { use_qualified_module(self, submodule, exports)?; diff --git a/src/prolog/machine/toplevel.rs b/src/prolog/machine/toplevel.rs index 542dd131..823067a4 100644 --- a/src/prolog/machine/toplevel.rs +++ b/src/prolog/machine/toplevel.rs @@ -196,13 +196,13 @@ fn setup_op_decl( to_op_decl(prec, spec.as_str(), name) } -fn setup_predicate_indicator(mut term: Term) -> Result { +fn setup_predicate_indicator(term: &mut Term) -> Result { match term { Term::Clause(_, ref name, ref mut terms, Some(_)) if name.as_str() == "/" && terms.len() == 2 => { let arity = *terms.pop().unwrap(); - let name = *terms.pop().unwrap(); + let name = *terms.pop().unwrap(); let arity = arity .to_constant() @@ -210,7 +210,7 @@ fn setup_predicate_indicator(mut term: Term) -> Result Result>) -> Result { +fn setup_module_export( + mut term: Term, + atom_tbl: TabledData, +) -> Result { + setup_predicate_indicator(&mut term) + .map(ModuleExport::PredicateKey) + .or_else(|_| { + if let Term::Clause(_, name, terms, _) = term { + if terms.len() == 3 && name.as_str() == "op" { + Ok(ModuleExport::OpDecl(setup_op_decl( + terms, + atom_tbl + )?)) + } else { + Err(ParserError::InvalidModuleDecl) + } + } else { + Err(ParserError::InvalidModuleDecl) + } + }) +} + +fn setup_module_decl( + mut terms: Vec>, + atom_tbl: TabledData, +) -> Result { let mut export_list = *terms.pop().unwrap(); let name = terms .pop() @@ -230,10 +255,12 @@ fn setup_module_decl(mut terms: Vec>) -> Result>) -> Result Ok(ModuleSource::File(name.clone())), + Term::Constant(_, Constant::Atom(ref name, _)) => + Ok(ModuleSource::File(name.clone())), _ => Err(ParserError::InvalidUseModuleDecl), } } -type UseModuleExport = (ModuleSource, Vec); +type UseModuleExport = (ModuleSource, Vec); -fn setup_qualified_import(mut terms: Vec>) -> Result { +fn setup_qualified_import( + mut terms: Vec>, + atom_tbl: TabledData, +) -> Result { let mut export_list = *terms.pop().unwrap(); let module_src = match *terms.pop().unwrap() { Term::Clause(_, ref name, ref mut terms, None) @@ -282,10 +313,10 @@ fn setup_qualified_import(mut terms: Vec>) -> Result Err(ParserError::InvalidUseModuleDecl), }?; - let mut exports = Vec::new(); + let mut exports = vec![]; while let Term::Cons(_, t1, t2) = export_list { - exports.push(setup_predicate_indicator(*t1)?); + exports.push(setup_module_export(*t1, atom_tbl.clone())?); export_list = *t2; } @@ -460,19 +491,19 @@ fn setup_declaration<'a, 'b, 'c, R: Read>( ("op", 3) => Ok(Declaration::Op(setup_op_decl(terms, indices.atom_tbl())?)), ("module", 2) => - Ok(Declaration::Module(setup_module_decl(terms)?)), + Ok(Declaration::Module(setup_module_decl(terms, indices.atom_tbl())?)), ("use_module", 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)), ("use_module", 2) => { - let (name, exports) = setup_qualified_import(terms)?; + let (name, exports) = setup_qualified_import(terms, indices.atom_tbl())?; Ok(Declaration::UseQualifiedModule(name, exports)) } ("non_counted_backtracking", 1) => { - let (name, arity) = setup_predicate_indicator(*terms.pop().unwrap())?; + let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?; Ok(Declaration::NonCountedBacktracking(name, arity)) } ("dynamic", 1) => { - let (name, arity) = setup_predicate_indicator(*terms.pop().unwrap())?; + let (name, arity) = setup_predicate_indicator(&mut *terms.pop().unwrap())?; Ok(Declaration::Dynamic(name, arity)) } ("initialization", 1) => { diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index ba2b0ee9..d04d7b10 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -134,7 +134,7 @@ ; '$print_exception'(E) ). -'$predicate_indicator'(Source, PI) :- +'$module_export'(Source, PI) :- ( nonvar(PI) -> ( PI = Name / Arity -> ( var(Name) -> throw(error(instantiation_error, Source)) @@ -145,7 +145,20 @@ ) ; throw(error(type_error(integer, Arity), Source)) ) - ; throw(error(type_error(predicate_indicator, PI), Source)) + ; PI = op(Prec, Spec, Name) -> + ( integer(Prec) -> + ( \+ atom(Name) -> + throw(error(type_error(atom, Name), Source)) + ; Prec < 0 -> + throw(error(domain_error(not_less_than_zero, Prec), Source)) + ; Prec > 1200 -> + throw(error(domain_error(operator_precision, Prec), Source)) + ; memberchk(Spec, [xfy, yfx, xfx, fx, fy, yf, xf]) + ; throw(error(domain_error(operator_specification, Spec), Source)) + ) + ; throw(error(type_error(integer, Prec), Source)) + ) + ; throw(error(type_error(module_export, PI), Source)) ) ; throw(error(instantiation_error, Source)) ). @@ -167,9 +180,11 @@ use_module(Module) :- use_module(Module, QualifiedExports) :- ( nonvar(Module) -> ( list_si(QualifiedExports) -> - maplist('$predicate_indicator'(use_module/2), QualifiedExports), !, - ( Module = library(Filename) -> '$use_qualified_module'(Filename, QualifiedExports) - ; atom(Module) -> '$use_qualified_module_from_file'(Module, QualifiedExports) + maplist('$module_export'(use_module/2), QualifiedExports) -> + ( Module = library(Filename) -> + '$use_qualified_module'(Filename, QualifiedExports) + ; atom(Module) -> + '$use_qualified_module_from_file'(Module, QualifiedExports) ; throw(error(invalid_module_specifier, use_module/2)) ) ; throw(error(type_error(list, QualifiedExports), use_module/2)) From c3c53017f9b8b95cd54b3b7d1c11b8bb6cd783b9 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 26 Nov 2019 19:38:43 -0700 Subject: [PATCH 16/21] add ambiguity check for period printing, remove extraneous space between last goal and period (#237) --- src/prolog/toplevel.pl | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index d04d7b10..63433554 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -72,13 +72,46 @@ ; write_term(G, [quoted(true), variable_names(VarList)]) ). +'$write_last_goal'(G, VarList) :- + ( G = (Var = Value) -> + write(Var), + write(' = '), + ( '$needs_bracketing'(Value, (=)) -> + write('('), + write_term(Value, [quoted(true), variable_names(VarList)]), + write(')') + ; write_term(Value, [quoted(true), variable_names(VarList)]), + ( '$trailing_period_is_ambiguous'(Value) -> + write(' ') + ; true + ) + ) + ; G == [] -> + write('true') + ; write_term(G, [quoted(true), variable_names(VarList)]) + ). + '$write_eq'((G1, G2), VarList) :- !, '$write_goal'(G1, VarList), write(', '), '$write_eq'(G2, VarList). '$write_eq'(G, VarList) :- - '$write_goal'(G, VarList). + '$write_last_goal'(G, VarList). + +'$graphic_token_char'(C) :- + memberchk(C, ['#', '$', '&', '*', '+', '-', '.', ('/'), ':', + '<', '=', '>', '?', '@', '^', '~', ('\\')]). + +'$list_last_item'([C], C) :- !. +'$list_last_item'([_|Cs], D) :- + '$list_last_item'(Cs, D). + +'$trailing_period_is_ambiguous'(Value) :- + atom(Value), + atom_chars(Value, ValueChars), + '$list_last_item'(ValueChars, Char), + '$graphic_token_char'(Char). '$write_eqs_and_read_input'(B, VarList) :- sort(VarList, SortedVarList), @@ -89,7 +122,7 @@ write('true.'), nl ; thread_goals(Goals, ThreadedGoals, (',')), '$write_eq'(ThreadedGoals, VarList), - write(' .'), + write('.'), nl ) ; thread_goals(Goals, ThreadedGoals, (',')), From 0a665b79f2e7131047597aeec3d6920baac83a91 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 26 Nov 2019 20:51:59 -0700 Subject: [PATCH 17/21] add (:)/{3..12} to enable metacalls on module-prefixed predicates --- src/prolog/clause_types.rs | 6 +-- src/prolog/lib/builtins.pl | 64 +++++++++++++++++++++++++++--- src/prolog/machine/system_calls.rs | 18 +++++---- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index 8f67177d..bf17531c 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -170,7 +170,7 @@ pub enum SystemClauseType { CopyToLiftedHeap, DeleteAttribute, DeleteHeadAttribute, - DynamicModuleResolution, + DynamicModuleResolution(usize), EnqueueAttributeGoal, EnqueueAttributedVar, ExpandGoal, @@ -278,7 +278,7 @@ impl SystemClauseType { &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"), - &SystemClauseType::DynamicModuleResolution => clause_name!("$module_call"), + &SystemClauseType::DynamicModuleResolution(_) => clause_name!("$module_call"), &SystemClauseType::EnqueueAttributeGoal => clause_name!("$enqueue_attribute_goal"), &SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"), &SystemClauseType::ExpandTerm => clause_name!("$expand_term"), @@ -399,7 +399,7 @@ impl SystemClauseType { ("$get_next_op_db_ref", 2) => Some(SystemClauseType::GetNextOpDBRef), ("$lookup_db_ref", 3) => Some(SystemClauseType::LookupDBRef), ("$lookup_op_db_ref", 4) => Some(SystemClauseType::LookupOpDBRef), - ("$module_call", 2) => Some(SystemClauseType::DynamicModuleResolution), + ("$module_call", _) => Some(SystemClauseType::DynamicModuleResolution(arity - 2)), ("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal), ("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar), ("$expand_term", 2) => Some(SystemClauseType::ExpandTerm), diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index e6e0d40f..f0a75453 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -39,10 +39,12 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :- :- op(900, fy, \+). :- module(builtins, [(=)/2, (\=)/2, (\+)/1, (',')/2, (->)/2, (;)/2, - (=..)/2, (:)/2, abolish/1, asserta/1, assertz/1, - atom_chars/2, atom_codes/2, atom_concat/3, - atom_length/2, bagof/3, catch/3, char_code/2, - clause/2, current_op/3, current_predicate/1, + (=..)/2, (:)/2, (:)/3, (:)/4, (:)/5, (:)/6, + (:)/7, (:)/8, (:)/9, (:)/10, (:)/11, (:)/12, + abolish/1, asserta/1, assertz/1, atom_chars/2, + atom_codes/2, atom_concat/3, atom_length/2, + bagof/3, catch/3, char_code/2, clause/2, + current_op/3, current_predicate/1, current_prolog_flag/2, expand_goal/2, expand_term/2, fail/0, false/0, findall/3, findall/4, get_char/1, halt/0, max_arity/1, @@ -53,7 +55,8 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :- true/0, unify_with_occurs_check/2, write/1, write_canonical/1, write_term/2, writeq/1]). -% the maximum arity flag. needs to be replaced with current_prolog_flag(max_arity, MAX_ARITY). +% the maximum arity flag. needs to be replaced with +% current_prolog_flag(max_arity, MAX_ARITY). max_arity(255). % unify. @@ -70,6 +73,57 @@ Module : Predicate :- ; throw(error(type_error(atom, Module), (:)/2)) ). +:(Module, Predicate, A1) :- + ( atom(Module) -> '$module_call'(A1, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2) :- + ( atom(Module) -> '$module_call'(A1, A2, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4, A5) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4, A5, A6) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, A9, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + +:(Module, Predicate, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) :- + ( atom(Module) -> '$module_call'(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, Module, Predicate) + ; throw(error(type_error(atom, Module), (:)/2)) + ). + + % flags. current_prolog_flag(Flag, false) :- Flag == bounded, !. diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 7a52632b..fd3e31a5 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1092,27 +1092,31 @@ impl MachineState { _ => unreachable!(), } } - &SystemClauseType::DynamicModuleResolution => { - let module_name = self.store(self.deref(self[temp_v!(1)].clone())); + &SystemClauseType::DynamicModuleResolution(narity) => { + let module_name = self.store(self.deref(self[temp_v!(1 + narity)].clone())); if let Addr::Con(Constant::Atom(module_name, _)) = module_name { - match self.store(self.deref(self[temp_v!(2)].clone())) { + match self.store(self.deref(self[temp_v!(2 + narity)].clone())) { Addr::Str(a) => { if let HeapCellValue::NamedStr(arity, name, _) = self.heap[a].clone() { - for i in 1..arity + 1 { + for i in (arity + 1 .. arity + narity + 1).rev() { + self.registers[i] = self.registers[i - arity].clone(); + } + + for i in 1 .. arity + 1 { self.registers[i] = self.heap[a + i].as_addr(a + i); } return self.module_lookup( indices, - (name, arity), + (name, arity + narity), module_name, true, ); } } - Addr::Con(Constant::Atom(name, _)) => { - return self.module_lookup(indices, (name, 0), module_name, true) + Addr::Con(Constant::Atom(name, _)) => { + return self.module_lookup(indices, (name, narity), module_name, true) } addr => { let stub = MachineError::functor_stub(clause_name!("(:)"), 2); From 1dec482e22497aa22b21e24a75cc07a87d91d987 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 27 Nov 2019 00:52:30 -0700 Subject: [PATCH 18/21] use in situ code directory from metacall if conventional lookup fails (#238) --- src/prolog/machine/machine_state.rs | 8 +------- src/prolog/machine/mod.rs | 26 +++++++++++++------------- src/prolog/machine/term_expansion.rs | 12 ++++++------ src/prolog/machine/toplevel.rs | 23 ++++++++++------------- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index c632e059..d09b5745 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -873,13 +873,7 @@ pub(crate) trait CallPolicy: Any { if let Some(idx) = indices.get_code_index((name.clone(), arity), module) { self.context_call(machine_st, name, arity, idx, indices)?; } else { - let h = machine_st.heap.h; - let stub = MachineError::functor_stub(clause_name!("call"), arity + 1); - let key = ExistenceError::Procedure(name, arity); - - return Err( - machine_st.error_form(MachineError::existence_error(h, key), stub) - ); + try_in_situ(machine_st, name, arity, indices, machine_st.last_call)?; } } ClauseType::Hook(_) | ClauseType::System(_) => { diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index a562858c..b1c0867c 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -107,13 +107,13 @@ impl SubModuleUser for IndexStore { &mut self.op_dir } - fn get_code_index(&self, key: PredicateKey, module: ClauseName) -> Option { - match module.as_str() { + fn get_code_index(&self, key: PredicateKey, module_name: ClauseName) -> Option { + match module_name.as_str() { "user" | "builtin" => self.code_dir.get(&key).cloned(), _ => self - .modules - .get(&module) - .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)), + .modules + .get(&module_name) + .and_then(|ref module| module.code_dir.get(&key).cloned().map(CodeIndex::from)) } } @@ -132,7 +132,7 @@ impl SubModuleUser for IndexStore { return; } - self.code_dir.insert((name, arity), idx); + self.code_dir.insert((name.clone(), arity), idx.clone()); } fn use_qualified_module( @@ -241,7 +241,7 @@ impl Machine { pub fn run_init_code(&mut self, code: Code) -> bool { let old_machine_st = self.sink_to_snapshot(); - self.machine_st.reset(); + self.machine_st.reset(); self.code_repo.cached_query = code; self.run_query(); @@ -418,14 +418,14 @@ impl Machine { _ => unreachable!() }; - + let arity = match &self.machine_st.heap[s+2] { &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => arity.to_usize().unwrap(), _ => unreachable!() }; - + exports.push(ModuleExport::PredicateKey((name, arity))); } HeapCellValue::NamedStr(arity, ref name, _) @@ -443,7 +443,7 @@ impl Machine { _ => unreachable!() }; - + let prec = match &self.machine_st.heap[s+1] { &HeapCellValue::Addr(Addr::Con(Constant::Integer(ref arity))) => arity.to_usize().unwrap(), @@ -593,7 +593,7 @@ impl Machine { fn sink_to_snapshot(&mut self) -> MachineState { let mut snapshot = MachineState::with_capacity(0); - + snapshot.hb = self.machine_st.hb; snapshot.e = self.machine_st.e; snapshot.b = self.machine_st.b; @@ -619,7 +619,7 @@ impl Machine { snapshot } - fn absorb_snapshot(&mut self, mut snapshot: MachineState) { + fn absorb_snapshot(&mut self, mut snapshot: MachineState) { self.machine_st.hb = snapshot.hb; self.machine_st.e = snapshot.e; self.machine_st.b = snapshot.b; @@ -667,7 +667,7 @@ impl Machine { // so hold onto it locally and restore it after the compiler has finished. self.machine_st.fail = false; let cached_query = mem::replace(&mut self.code_repo.cached_query, vec![]); - + self.dynamic_transaction(trans_type, p); self.code_repo.cached_query = cached_query; diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index 1c45b49e..f8ef4ed3 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -161,7 +161,7 @@ impl<'a, R: Read> TermStream<'a, R> { pub fn col_num(&self) -> usize { self.parser.col_num() } - + #[inline] pub fn update_expansion_lens(&mut self) { let te_key = (clause_name!("term_expansion"), 2); @@ -267,7 +267,7 @@ impl<'a, R: Read> TermStream<'a, R> { let line_num = self.line_num(); let col_num = self.col_num(); - + let term = self.parser.read_term(composite_op!( self.in_module, &self.wam.indices.op_dir, @@ -308,7 +308,7 @@ impl<'a, R: Read> TermStream<'a, R> { initial_term, clause_name!(","), ))); - + Ok(Term::Clause(cell, name, terms, arity)) } _ => Ok(term), @@ -324,7 +324,7 @@ impl<'a, R: Read> TermStream<'a, R> { ) -> Result, ParserError> { let mut results = vec![]; - while let Some(term) = terms.pop_front() { + while let Some(term) = terms.pop_front() { match machine_st.try_expand_term(self.wam, &term, CompileTimeHook::GoalExpansion) { Some(term_string) => { let term = self.parse_expansion_output(term_string.as_str(), op_dir)?; @@ -382,14 +382,14 @@ impl MachineState { ) -> Option { let term_write_result = write_term_to_heap(term, self); let h = self.heap.h; - + self[temp_v!(1)] = Addr::HeapCell(term_write_result.heap_loc); self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h))); self[temp_v!(2)] = Addr::HeapCell(h); let code = vec![call_clause!(ClauseType::Hook(hook), 2, 0, true)]; wam.code_repo.cached_query = code; - + self.query_stepper( &mut wam.indices, &mut wam.policies, diff --git a/src/prolog/machine/toplevel.rs b/src/prolog/machine/toplevel.rs index 823067a4..a01d3dd8 100644 --- a/src/prolog/machine/toplevel.rs +++ b/src/prolog/machine/toplevel.rs @@ -60,8 +60,8 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> { IndexSource::TermStream => &mut self.term_stream.wam.indices.code_dir, IndexSource::Local(ref mut indices) => &mut indices.code_dir, } - } - + } + fn static_code_dir(&self) -> Option<&CodeDir> { match self.static_code_dir { Some(IndexSource::TermStream) => Some(&self.term_stream.wam.indices.code_dir), @@ -81,11 +81,11 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> { }; if let Some(idx) = idx_opt { - self.local_code_dir().insert((name, arity), idx.clone()); + self.local_code_dir().insert((name.clone(), arity), idx.clone()); idx } else { - let idx = CodeIndex::default(); - self.local_code_dir().insert((name, arity), idx.clone()); + let idx = CodeIndex::default(); + self.local_code_dir().insert((name.clone(), arity), idx.clone()); idx } } @@ -594,7 +594,7 @@ impl RelationWorker { fn fabricate_disjunct(&self, body_term: Term) -> (JumpStub, VecDeque) { let vars = self.compute_head(&body_term); - let clauses: Vec<_> = unfold_by_str(body_term, ";") + let results = unfold_by_str(body_term, ";") .into_iter() .map(|term| { let mut subterms = unfold_by_str(term, ","); @@ -603,13 +603,10 @@ impl RelationWorker { check_for_internal_if_then(&mut subterms); let term = subterms.pop().unwrap(); - fold_by_str(subterms.into_iter(), term, clause_name!(",")) - }) - .collect(); + let clause = fold_by_str(subterms.into_iter(), term, clause_name!(",")); - let results = clauses - .into_iter() - .map(|clause| self.fabricate_rule_body(&vars, clause)) + self.fabricate_rule_body(&vars, clause) + }) .collect(); (vars, results) @@ -984,7 +981,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> { if self.in_module { None } else { Some(IndexSource::TermStream) } ); - let queue = self.rel_worker.parse_queue(&mut indices)?; + let queue = self.rel_worker.parse_queue(&mut indices)?; let result = (append_preds(preds), queue); let in_situ_code_dir = &mut indices.term_stream.wam.indices.in_situ_code_dir; From 9ae901bd0d69cfb49bedf1a20b18dd450437ec4b Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 27 Nov 2019 14:13:18 -0400 Subject: [PATCH 19/21] terms containing attributed variables are not ground (#239) --- src/prolog/machine/machine_state_impl.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 60713510..f48d77ff 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -3109,6 +3109,7 @@ impl MachineState { match v { HeapCellValue::Addr(Addr::HeapCell(..)) => return true, HeapCellValue::Addr(Addr::StackCell(..)) => return true, + HeapCellValue::Addr(Addr::AttrVar(..)) => return true, _ => {} } } From 7eb0de7f52fb543994adcca7fef46742d70246ad Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 28 Nov 2019 00:45:13 -0700 Subject: [PATCH 20/21] preserve heap contents in between goal expansions (#240, #241) --- Cargo.lock | 6 ++-- Cargo.toml | 2 +- src/prolog/machine/term_expansion.rs | 48 +++++++--------------------- src/prolog/machine/toplevel.rs | 48 ++++++++++++++++------------ 4 files changed, 42 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48178a56..dd192cb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -311,7 +311,7 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.8.35" +version = "0.8.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -447,7 +447,7 @@ dependencies = [ "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rug-adapter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)", + "prolog_parser 0.8.36 (registry+https://github.com/rust-lang/crates.io-index)", "ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rug 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -590,7 +590,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6" "checksum ordered-float 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7eb5259643245d3f292c7a146b2df53bba24d7eab159410e648eb73dc164669d" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum prolog_parser 0.8.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1bc16334ea998d54f73cda14254fe546c57ae0c6c990263d50f7efd6ae10ea9d" +"checksum prolog_parser 0.8.36 (registry+https://github.com/rust-lang/crates.io-index)" = "fea0ae985b51f28cb3582469fbe9318e238d504a7358d90eb671f0d772fb5061" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" diff --git a/Cargo.toml b/Cargo.toml index 676e1707..30099863 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ libc = "0.2.62" nix = "0.15.0" num-rug-adapter = { optional = true, version = "0.1.1" } ordered-float = "0.5.0" -prolog_parser = { version = "0.8.35", default-features = false } +prolog_parser = { version = "0.8.36", default-features = false } ref_thread_local = "0.0.0" rug = { version = "1.4.0", optional = true } rustyline = "5.0.3" diff --git a/src/prolog/machine/term_expansion.rs b/src/prolog/machine/term_expansion.rs index f8ef4ed3..f322f712 100644 --- a/src/prolog/machine/term_expansion.rs +++ b/src/prolog/machine/term_expansion.rs @@ -257,7 +257,6 @@ impl<'a, R: Read> TermStream<'a, R> { self.enqueue_term(term)? } None => { - let term = self.run_goal_expanders(&mut machine_st, op_dir, term)?; return Ok(term); } }; @@ -281,40 +280,6 @@ impl<'a, R: Read> TermStream<'a, R> { } } - pub(crate) fn run_goal_expanders( - &mut self, - machine_st: &mut MachineState, - op_dir: &OpDir, - term: Term, - ) -> Result { - match term { - Term::Clause(cell, name, mut terms, arity) => { - let mut new_terms = { - let old_terms = match (name.as_str(), terms.len()) { - (":-", 2) => { - let comma_term = *terms.pop().unwrap(); - unfold_by_str(comma_term, ",") - } - ("?-", 1) => unfold_by_str(*terms.pop().unwrap(), ","), - _ => return Ok(Term::Clause(cell, name, terms, arity)), - }; - - self.expand_goals(machine_st, op_dir, VecDeque::from(old_terms))? - }; - - let initial_term = new_terms.pop().unwrap(); - terms.push(Box::new(fold_by_str( - new_terms.into_iter(), - initial_term, - clause_name!(","), - ))); - - Ok(Term::Clause(cell, name, terms, arity)) - } - _ => Ok(term), - } - } - pub(super) fn expand_goals( &mut self, @@ -374,6 +339,15 @@ impl MachineState { output } + // reset the machine, but keep the heap contents as they were. + // this prevents clashes between underscored variable names + // in the same query. + fn reset_with_heap_preservation(&mut self) { + let heap = self.heap.take(); + self.reset(); + self.heap = heap; + } + fn try_expand_term( &mut self, wam: &mut Machine, @@ -398,7 +372,7 @@ impl MachineState { ); if self.fail { - self.reset(); + self.reset_with_heap_preservation(); None } else { let TermWriteResult { var_dict, .. } = term_write_result; @@ -406,7 +380,7 @@ impl MachineState { self.heap_locs = var_dict; let output = self.print_with_locs(Addr::HeapCell(h), &wam.indices.op_dir); - self.reset(); + self.reset_with_heap_preservation(); Some(output.result()) } } diff --git a/src/prolog/machine/toplevel.rs b/src/prolog/machine/toplevel.rs index a01d3dd8..ea91d1e6 100644 --- a/src/prolog/machine/toplevel.rs +++ b/src/prolog/machine/toplevel.rs @@ -60,8 +60,8 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> { IndexSource::TermStream => &mut self.term_stream.wam.indices.code_dir, IndexSource::Local(ref mut indices) => &mut indices.code_dir, } - } - + } + fn static_code_dir(&self) -> Option<&CodeDir> { match self.static_code_dir { Some(IndexSource::TermStream) => Some(&self.term_stream.wam.indices.code_dir), @@ -84,7 +84,7 @@ impl<'a, 'b, 'c, R: Read> CompositeIndices<'a, 'b, 'c, R> { self.local_code_dir().insert((name.clone(), arity), idx.clone()); idx } else { - let idx = CodeIndex::default(); + let idx = CodeIndex::default(); self.local_code_dir().insert((name.clone(), arity), idx.clone()); idx } @@ -240,7 +240,7 @@ fn setup_module_export( } else { Err(ParserError::InvalidModuleDecl) } - }) + }) } fn setup_module_decl( @@ -259,7 +259,7 @@ fn setup_module_decl( while let Term::Cons(_, t1, t2) = export_list { let module_export = setup_module_export(*t1, atom_tbl.clone())?; - + exports.push(module_export); export_list = *t2; } @@ -327,9 +327,14 @@ fn setup_qualified_import( } } -fn is_consistent(tl: &TopLevel, clauses: &Vec) -> bool { +fn is_consistent( + name: Option, + arity: usize, + clauses: &Vec, +) -> bool +{ match clauses.first() { - Some(ref cl) => tl.name() == cl.name() && tl.arity() == cl.arity(), + Some(ref cl) => name == cl.name() && arity == cl.arity(), None => true, } } @@ -342,18 +347,18 @@ fn merge_clauses(tls: &mut VecDeque) -> Result TopLevel::Query(_) if clauses.is_empty() && tls.is_empty() => return Ok(tl), TopLevel::Declaration(_) if clauses.is_empty() => return Ok(tl), TopLevel::Query(_) => return Err(ParserError::InconsistentEntry), - TopLevel::Fact(..) if is_consistent(&tl, &clauses) => + TopLevel::Fact(..) if is_consistent(tl.name(), tl.arity(), &clauses) => if let TopLevel::Fact(fact, line_num, col_num) = tl { let clause = PredicateClause::Fact(fact, line_num, col_num); clauses.push(clause); }, - TopLevel::Rule(..) if is_consistent(&tl, &clauses) => { + TopLevel::Rule(..) if is_consistent(tl.name(), tl.arity(), &clauses) => { if let TopLevel::Rule(rule, line_num, col_num) = tl { let clause = PredicateClause::Rule(rule, line_num, col_num); clauses.push(clause); } } - TopLevel::Predicate(_) if is_consistent(&tl, &clauses) => { + TopLevel::Predicate(_) if is_consistent(tl.name(), tl.arity(), &clauses) => { if let TopLevel::Predicate(pred) = tl { clauses.extend(pred.clauses().into_iter()) } @@ -751,11 +756,11 @@ impl RelationWorker { 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); @@ -769,7 +774,7 @@ impl RelationWorker { query_terms.push(self.pre_query_term(indices, term)?); } } - + Ok(query_terms) } @@ -974,7 +979,7 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> { &mut self, indices: &mut IndexStore, preds: &mut Vec, - ) -> Result<(), SessionError> { + ) -> Result<(), SessionError> { let mut indices = CompositeIndices::new( &mut self.term_stream, IndexSource::Local(indices), @@ -1020,17 +1025,18 @@ impl<'a, R: Read> TopLevelBatchWorker<'a, R> { while !self.term_stream.eof()? { let term = self.term_stream.read_term(&indices.op_dir)?; + + // if is_consistent is false, preds is non-empty. + if !is_consistent(term.predicate_name(), term.predicate_arity(), &preds) { + self.process_result(indices, &mut preds)?; + self.take_dynamic_clauses(); + } + let (mut tl, new_rel_worker) = self.try_term_to_tl(indices, term)?; if tl.is_end_of_file_atom() { tl = TopLevel::Declaration(Declaration::EndOfFile); - } - - // if is_consistent is false, preds is non-empty. - if !is_consistent(&tl, &preds) { - self.process_result(indices, &mut preds)?; - self.take_dynamic_clauses(); - } + } self.rel_worker.absorb(new_rel_worker); From 335202b9d905b6318d82001b84db81c007e19f50 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 28 Nov 2019 19:08:08 -0700 Subject: [PATCH 21/21] reset attributed variable state between toplevel queries (#242) --- src/prolog/clause_types.rs | 3 +++ src/prolog/machine/attributed_variables.rs | 2 +- src/prolog/machine/system_calls.rs | 3 +++ src/prolog/toplevel.pl | 3 ++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index bf17531c..82bd8cde 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -179,6 +179,7 @@ pub enum SystemClauseType { FetchGlobalVar, FetchGlobalVarWithOffset, GetChar, + ResetAttrVarState, TruncateIfNoLiftedHeapGrowthDiff, TruncateIfNoLiftedHeapGrowth, GetAttributedVariableList, @@ -289,6 +290,7 @@ impl SystemClauseType { clause_name!("$fetch_global_var_with_offset") } &SystemClauseType::GetChar => clause_name!("$get_char"), + &SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"), &SystemClauseType::TruncateIfNoLiftedHeapGrowth => { clause_name!("$truncate_if_no_lh_growth") } @@ -408,6 +410,7 @@ impl SystemClauseType { ("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar), ("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset), ("$get_char", 1) => Some(SystemClauseType::GetChar), + ("$reset_attr_var_state", 0) => Some(SystemClauseType::ResetAttrVarState), ("$truncate_if_no_lh_growth", 1) => { Some(SystemClauseType::TruncateIfNoLiftedHeapGrowth) } diff --git a/src/prolog/machine/attributed_variables.rs b/src/prolog/machine/attributed_variables.rs index 992ba98d..50a101b9 100644 --- a/src/prolog/machine/attributed_variables.rs +++ b/src/prolog/machine/attributed_variables.rs @@ -32,9 +32,9 @@ impl AttrVarInitializer { #[inline] pub(super) fn reset(&mut self) { + self.attribute_goals.clear(); self.attr_var_queue.clear(); self.bindings.clear(); - self.attribute_goals.clear(); } } diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index fd3e31a5..e168849b 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1680,6 +1680,9 @@ impl MachineState { } }; }, + &SystemClauseType::ResetAttrVarState => { + self.attr_var_init.reset(); + } &SystemClauseType::RemoveCallPolicyCheck => { let restore_default = match call_policy.downcast_mut::().ok() { Some(call_policy) => { diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 63433554..51eb93fa 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -44,7 +44,8 @@ ), ( '$get_b_value'(B), call(Term), '$write_eqs_and_read_input'(B, VarList), ! ; write('false.'), nl - ). + ), + '$reset_attr_var_state'. '$needs_bracketing'(Value, Op) :- catch((functor(Value, F, _),