From 2d1f57e839c8607d78e0a67c66bd443cbf3b5252 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Tue, 14 Apr 2020 19:24:13 +0200 Subject: [PATCH 01/24] update the toplevel description, incorporating the latest changes --- README.md | 81 ++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index e103767c..4fa1bab5 100644 --- a/README.md +++ b/README.md @@ -124,61 +124,56 @@ The optional `--release` flag will perform various optimizations, producing a faster executable. ## Tutorial -To enter a multi-clause predicate, the directive "[user]" is used. -For example, -``` -?- [user]. -(type Enter + Ctrl-D to terminate the stream when finished) -p(f(f(X)), h(W), Y) :- g(W), h(W), f(X). -p(X, Y, Z) :- h(Y), z(Z). -?- [user]. -(type Enter + Ctrl-D to terminate the stream when finished) -h(x). h(y). -h(z). -``` -In the example, `Enter + Ctrl-D` is used to terminate the standard -input stream. The instructive message is always printed. +Prolog files are loaded by specifying them as arguments on the command +line. For example, to load `program.pl`, use: -Queries are issued as ``` -?- p(X, Y, Z). +$> scryer-prolog program.pl ``` -Pressing `SPACE` will backtrack through other possible answers, if any exist. -Pressing `.` will abort the search and return to the prompt. +Loading a Prolog file is also called “consulting” it. The built-in +predicate `consult/1` can be used to consult a file from within +Prolog: -Wildcards work as well: +``` +?- consult('program.pl'). +``` + +As an abbreviation for `consult/1`, you can specify a *list* of +program files, given as *atoms*: + +``` +?- ['program.pl']. +``` + +The special notation `[user]` is used to read Prolog text from +standard input. For example, ``` ?- [user]. -(type Enter + Ctrl-D to terminate the stream when finished) -member(X, [X|_]). -member(X, [_|Xs]) :- member(X, Xs). -?- member(X, [a, b, c]). - X = a -; X = b -; X = c -; false. -``` -and so do conjunctive queries: -``` -?- [user]. -(type Enter + Ctrl-D to terminate the stream when finished) -f(X) :- g(X). -g(x). g(y). g(z). -h(call(f, X)). -?- h(X), X. - X = call(f,x) -; X = call(f,y) -; X = call(f,z). +hello(declarative_world). +hello(pure_world). ``` -Note that the values of variables belonging to successful queries are -printed out, on one line each. Uninstantiated variables are denoted by -a number preceded by an underscore (`X = _0` in an example above). +Pressing `RETURN` followed by `Ctrl-d` stops reading from +standard input and consults the entered Prolog text. + +After a program is consulted, you can ask *queries* about the +predicates it defines. For example, with the program shown above: + +``` +?- hello(What). + What = declarative_world +; What = pure_world. +``` + +Press `SPACE` to show further answers, if any exist. Press `.` to +abort the search and return to the toplevel prompt. +Press `h` to show a help message. + +To quit Scryer Prolog, use the standard predicate `halt/0`: -To quit scryer-prolog, type ``` ?- halt. ``` From 93a0ab7f0a0fd338e6d08aa00dc8e4a2d0b1d0e8 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 14 Apr 2020 23:25:15 -0600 Subject: [PATCH 02/24] write [a,b,c] correctly with write_canonical (#349) --- src/prolog/heap_print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index 186a2128..ed9b9859 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -1083,7 +1083,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { let at_cdr = self.at_cdr(","); if !at_cdr && Addr::EmptyList == end_addr { - if !self.machine_st.flags.double_quotes.is_codes() { + if self.machine_st.flags.double_quotes.is_chars() && !self.ignore_ops { self.print_proper_string(buf, max_depth); return; } From 2b720b8d0b2ce68c4fd1d0dbc1fa3e6a03eeb1d3 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 00:08:35 -0600 Subject: [PATCH 03/24] interrupt running queries and return to toplevel (#323) --- src/prolog/machine/mod.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 248f35fe..414a6ad6 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -343,14 +343,18 @@ impl Machine { use std::env; let mut arg_pstrs = vec![]; + for arg in env::args() { arg_pstrs.push(self.machine_st.heap.put_complete_string(&arg)); } - let list_addr = Addr::HeapCell(self.machine_st.heap.to_list(arg_pstrs.into_iter())); + let list_addr = Addr::HeapCell(self.machine_st.heap.to_list(arg_pstrs.into_iter())); self.machine_st[temp_v!(1)] = list_addr; - self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx)); - self.run_query(); + + loop { + self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx)); + self.run_query(); + } } pub fn new(current_input_stream: Stream, current_output_stream: Stream) -> Self From a9a5e79e85acf734b865f9315903e401dce0f2de Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 00:37:00 -0600 Subject: [PATCH 04/24] privilege new op declarations over old ones (#346) --- Cargo.lock | 6 ++---- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f20106a9..cd183d59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -477,8 +477,7 @@ dependencies = [ [[package]] name = "prolog_parser" -version = "0.8.51" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.8.52" dependencies = [ "lexical 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rug-adapter 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -622,7 +621,7 @@ dependencies = [ "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rug-adapter 0.1.2 (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.51 (registry+https://github.com/rust-lang/crates.io-index)", + "prolog_parser 0.8.52", "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 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -852,7 +851,6 @@ dependencies = [ "checksum proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" -"checksum prolog_parser 0.8.51 (registry+https://github.com/rust-lang/crates.io-index)" = "717a1384cfba76eb9e9c83bf8f003777dc164dd403680aa5a9d2eaff68c71c3c" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" diff --git a/Cargo.toml b/Cargo.toml index 9465d2d4..390e1eda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,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.51", default-features = false } +prolog_parser = { version = "0.8.52", default-features = false } ref_thread_local = "0.0.0" rug = { version = "1.4.0", optional = true } rustyline = "6.0.0" \ No newline at end of file From 8d95eb57fa39217a73725084639f2c5547f05d50 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 00:54:32 -0600 Subject: [PATCH 05/24] quote dot when quoted(true) (#349) --- Cargo.lock | 4 +++- src/prolog/heap_print.rs | 4 ++-- src/prolog/toplevel.pl | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd183d59..34a10e99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,6 +478,7 @@ dependencies = [ [[package]] name = "prolog_parser" version = "0.8.52" +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.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -621,7 +622,7 @@ dependencies = [ "nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-rug-adapter 0.1.2 (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.52", + "prolog_parser 0.8.52 (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 6.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -851,6 +852,7 @@ dependencies = [ "checksum proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" +"checksum prolog_parser 0.8.52 (registry+https://github.com/rust-lang/crates.io-index)" = "6d9baffc92f102756f07ef5a367409d4d78ddb5c32bc3bd6ee4584a27f79408d" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index ed9b9859..c9cd42a5 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -442,7 +442,7 @@ fn non_quoted_token>(mut iter: Iter) -> bool { if let Some(c) = iter.next() { if small_letter_char!(c) { iter.all(|c| alpha_numeric_char!(c)) - } else if graphic_token_char!(c) { + } else if c != '.' && graphic_token_char!(c) { non_quoted_graphic_token(iter, c) } else if semicolon_char!(c) { iter.next().is_none() @@ -1116,7 +1116,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> { let mut char_count = 0; for c in buf_iter { - self.push_char('.'); + self.append_str("'.'"); self.push_char('('); char_printer(self, c); diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 37afaf6f..4da303ce 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -123,6 +123,7 @@ atom(Value), atom_chars(Value, ValueChars), '$list_last_item'(ValueChars, Char), + Char \== '.', '$graphic_token_char'(Char). '$write_eqs_and_read_input'(B, VarList) :- From 2c96420bc4f3c0db006b775b911e87d3c9aa43c1 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Wed, 15 Apr 2020 17:49:01 +0200 Subject: [PATCH 06/24] ADDED: list_to_set/2, using the first occurrence of each element Example: ?- list_to_set([B,a,b,a,B,A,b,A], Ls). Ls = [B,a,b,A] ; false. --- src/prolog/lib/lists.pl | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/prolog/lib/lists.pl b/src/prolog/lib/lists.pl index c373fb95..8561ab2a 100644 --- a/src/prolog/lib/lists.pl +++ b/src/prolog/lib/lists.pl @@ -2,7 +2,7 @@ memberchk/2, reverse/2, length/2, maplist/2, maplist/3, maplist/4, maplist/5, maplist/6, maplist/7, maplist/8, maplist/9, same_length/2, - sum_list/2, transpose/2]). + sum_list/2, transpose/2, list_to_set/2]). :- use_module(library(error)). @@ -149,3 +149,31 @@ transpose_(_, Fs, Lists0, Lists) :- maplist(list_first_rest, Lists0, Fs, Lists). list_first_rest([L|Ls], L, Ls). + + +list_to_set(Ls0, Ls) :- + maplist(with_var, Ls0, LVs0), + keysort(LVs0, LVs), + same_elements(LVs), + pick_firsts(LVs0, Ls). + +pick_firsts([], []). +pick_firsts([E-V|EVs], Fs0) :- + ( V == visited -> + Fs0 = Fs + ; V = visited, + Fs0 = [E|Fs] + ), + pick_firsts(EVs, Fs). + +with_var(E, E-_). + +same_elements([]). +same_elements([EV|EVs]) :- + foldl(unify_same, EVs, EV, _). + +unify_same(E-V, Prev-Var, E-V) :- + ( Prev == E -> + Var = V + ; true + ). From f56e0a658684e3492fadc9c90198879cb576364e Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 10:07:44 -0600 Subject: [PATCH 07/24] don't count the terminator in PStrIter len --- src/prolog/examples/plres.pl | 1 + src/prolog/machine/partial_string.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prolog/examples/plres.pl b/src/prolog/examples/plres.pl index a19ca5a7..9bc2931b 100644 --- a/src/prolog/examples/plres.pl +++ b/src/prolog/examples/plres.pl @@ -31,6 +31,7 @@ :- use_module(library(dcgs)). :- use_module(library(dif)). +:- use_module(library(format)). :- use_module(library(lists)). pl_resolution(Clauses0, Chain) :- diff --git a/src/prolog/machine/partial_string.rs b/src/prolog/machine/partial_string.rs index eaaad181..cb95b44c 100644 --- a/src/prolog/machine/partial_string.rs +++ b/src/prolog/machine/partial_string.rs @@ -200,7 +200,7 @@ impl PartialString { #[inline] pub fn range_from(&self, index: RangeFrom) -> PStrIter { - PStrIter::from(self.buf, self.len, index.start) + PStrIter::from(self.buf, self.len - '\u{0}'.len_utf8(), index.start) } #[inline] From 5f8f0d8573ea1c3a7d96cd04afb4ccc40d800f99 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 10:27:20 -0600 Subject: [PATCH 08/24] remove underscores in printed variables produced by write_term_to_chars (#340) --- src/prolog/lib/charsio.pl | 36 ++++++++++++++++++++++-------------- src/prolog/toplevel.pl | 2 +- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/prolog/lib/charsio.pl b/src/prolog/lib/charsio.pl index b0ccc88d..9cf5f325 100644 --- a/src/prolog/lib/charsio.pl +++ b/src/prolog/lib/charsio.pl @@ -4,15 +4,23 @@ :- use_module(library(iso_ext)). -fabricate_var_name(VarName, N) :- +fabricate_var_name(VarType, VarName, N) :- char_code('A', AC), LN is N mod 26 + AC, char_code(LC, LN), NN is N // 26, ( NN =:= 0 -> - atom_chars(VarName, ['_', LC]) + ( VarType == fabricated -> + atom_chars(VarName, ['_', LC]) + ; VarType == numbervars -> + atom_chars(VarName, [LC]) + ) ; number_chars(NN, NNChars), - atom_chars(VarName, ['_', LC | NNChars]) + ( VarType == fabricated -> + atom_chars(VarName, ['_', LC | NNChars]) + ; VarType == numbervars -> + atom_chars(VarName, [LC | NNChars]) + ) ). var_list_contains_name([VarName = _ | VarList], VarName0) :- @@ -25,26 +33,26 @@ var_list_contains_variable([_ = Var | VarList], Var0) :- ; var_list_contains_variable(VarList, Var0) ). -make_new_var_name(V, VarName, N, N1, VarList) :- - fabricate_var_name(VarName0, N), +make_new_var_name(VarType, V, VarName, N, N1, VarList) :- + fabricate_var_name(VarType, VarName0, N), ( var_list_contains_name(VarList, VarName0) -> N0 is N + 1, - make_new_var_name(V, VarName, N0, N1, VarList) + make_new_var_name(VarType, V, VarName, N0, N1, VarList) ; VarName = VarName0, N1 is N + 1 ). -extend_var_list(Value, VarList, NewVarList) :- +extend_var_list(Value, VarList, NewVarList, VarType) :- term_variables(Value, Vars), - extend_var_list_(Vars, 0, VarList, NewVarList). + extend_var_list_(Vars, 0, VarList, NewVarList, VarType). -extend_var_list_([], N, VarList, VarList). -extend_var_list_([V|Vs], N, VarList, NewVarList) :- +extend_var_list_([], N, VarList, VarList, _). +extend_var_list_([V|Vs], N, VarList, NewVarList, VarType) :- ( var_list_contains_variable(VarList, V) -> - extend_var_list_(Vs, N, VarList, NewVarList) - ; make_new_var_name(V, VarName, N, N1, VarList), + extend_var_list_(Vs, N, VarList, NewVarList, VarType) + ; make_new_var_name(VarType, V, VarName, N, N1, VarList), NewVarList = [VarName = V | NewVarList0], - extend_var_list_(Vs, N1, VarList, NewVarList0) + extend_var_list_(Vs, N1, VarList, NewVarList0, VarType) ). @@ -81,5 +89,5 @@ write_term_to_chars(Term, Options, Chars) :- builtins:inst_member_or(Options, quoted(Quoted), quoted(false)), builtins:inst_member_or(Options, variable_names(VarNames), variable_names([])), builtins:inst_member_or(Options, max_depth(MaxDepth), max_depth(0)), - extend_var_list(Term, VarNames, NewVarNames), + extend_var_list(Term, VarNames, NewVarNames, numbervars), '$write_term_to_chars'(Term, IgnoreOps, NumberVars, Quoted, NewVarNames, MaxDepth, Chars). diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 4da303ce..e9057b0c 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -127,7 +127,7 @@ '$graphic_token_char'(Char). '$write_eqs_and_read_input'(B, VarList) :- - charsio:extend_var_list(VarList, VarList, NewVarList), + charsio:extend_var_list(VarList, VarList, NewVarList, fabricated), sort(NewVarList, SortedVarList), '$get_b_value'(B0), '$gather_goals'(SortedVarList, SortedVarList, Goals), From 023ee688d395e37382d526958d999d12e77af728 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 10:32:23 -0600 Subject: [PATCH 09/24] allow characters as atoms in Machine::use_module and Machine::use_qualified_module --- src/prolog/machine/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 414a6ad6..1a58482a 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -632,8 +632,12 @@ impl Machine { let addr = self.machine_st.store(self.machine_st.deref(module_spec)); match self.machine_st.heap.index_addr(&addr).as_ref() { - HeapCellValue::Atom(name, _) => name.clone(), - _ => unreachable!(), + HeapCellValue::Atom(name, _) => + name.clone(), + HeapCellValue::Addr(Addr::Char(c)) => + clause_name!(c.to_string(), self.indices.atom_tbl), + _ => + unreachable!(), } }; @@ -679,8 +683,12 @@ impl Machine { let addr = self.machine_st.store(self.machine_st.deref(module_spec)); match self.machine_st.heap.index_addr(&addr).as_ref() { - HeapCellValue::Atom(name, _) => name.clone(), - _ => unreachable!(), + HeapCellValue::Atom(name, _) => + name.clone(), + HeapCellValue::Addr(Addr::Char(c)) => + clause_name!(c.to_string(), self.indices.atom_tbl), + _ => + unreachable!(), } }; From 4d8f76e9220b546d998c0937d29001a11af467be Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 13:45:35 -0600 Subject: [PATCH 10/24] quote single dots only --- src/prolog/heap_print.rs | 4 +++- src/prolog/toplevel.pl | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/prolog/heap_print.rs b/src/prolog/heap_print.rs index c9cd42a5..a57be201 100644 --- a/src/prolog/heap_print.rs +++ b/src/prolog/heap_print.rs @@ -442,7 +442,9 @@ fn non_quoted_token>(mut iter: Iter) -> bool { if let Some(c) = iter.next() { if small_letter_char!(c) { iter.all(|c| alpha_numeric_char!(c)) - } else if c != '.' && graphic_token_char!(c) { + } else if c == '.' { + iter.next().is_some() + } else if graphic_token_char!(c) { non_quoted_graphic_token(iter, c) } else if semicolon_char!(c) { iter.next().is_none() diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index e9057b0c..27bf71f5 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -123,7 +123,7 @@ atom(Value), atom_chars(Value, ValueChars), '$list_last_item'(ValueChars, Char), - Char \== '.', + ValueChars \== ['.'], '$graphic_token_char'(Char). '$write_eqs_and_read_input'(B, VarList) :- From 57d739673a67337aa43384b54c58ba93496aeb21 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Wed, 15 Apr 2020 14:11:45 -0600 Subject: [PATCH 11/24] index Constant::Usize (#355) --- src/prolog/indexing.rs | 34 +++++++++++++++++++++++++++ src/prolog/machine/machine_indices.rs | 3 +++ 2 files changed, 37 insertions(+) diff --git a/src/prolog/indexing.rs b/src/prolog/indexing.rs index 239c5dbd..f02565eb 100644 --- a/src/prolog/indexing.rs +++ b/src/prolog/indexing.rs @@ -6,6 +6,7 @@ use crate::prolog::rug::Integer; use indexmap::IndexMap; use std::collections::VecDeque; +use std::convert::TryFrom; use std::hash::Hash; use std::rc::Rc; @@ -66,6 +67,16 @@ impl CodeOffsets { .or_insert(vec![]); code.push(Self::add_index(code.is_empty(), index)); + + if n >= 0 { + if let Ok(n) = usize::try_from(n) { + let code = self.constants + .entry(Constant::Usize(n)) + .or_insert(vec![]); + + code.push(Self::add_index(code.is_empty(), index)); + } + } } &Constant::Integer(ref n) => { if let Some(n) = n.to_isize() { @@ -75,11 +86,34 @@ impl CodeOffsets { code.push(Self::add_index(code.is_empty(), index)); } + + if let Some(n) = n.to_usize() { + let code = self.constants + .entry(Constant::Usize(n)) + .or_insert(vec![]); + + code.push(Self::add_index(code.is_empty(), index)); + } } &Constant::String(_) => { let is_initial_index = self.lists.is_empty(); self.lists.push(Self::add_index(is_initial_index, index)); } + &Constant::Usize(n) => { + let code = self.constants + .entry(Constant::Integer(Rc::new(Integer::from(n)))) + .or_insert(vec![]); + + code.push(Self::add_index(code.is_empty(), index)); + + if let Ok(n) = isize::try_from(n) { + let code = self.constants + .entry(Constant::Fixnum(n)) + .or_insert(vec![]); + + code.push(Self::add_index(code.is_empty(), index)); + } + } _ => { } } diff --git a/src/prolog/machine/machine_indices.rs b/src/prolog/machine/machine_indices.rs index a8a985a8..a11d2c1a 100644 --- a/src/prolog/machine/machine_indices.rs +++ b/src/prolog/machine/machine_indices.rs @@ -283,6 +283,9 @@ impl Addr { None } } + &Addr::Usize(n) => { + Some(Constant::Usize(n)) + } _ => { None } From 1ea6ae9fd90ff0067e47a3e1190cbe112c9e5700 Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 11:49:28 +0200 Subject: [PATCH 12/24] Added predicate for reading a single character --- src/prolog/clause_types.rs | 3 +++ src/prolog/lib/builtins.pl | 11 +++++++++-- src/prolog/machine/system_calls.rs | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index 7100855e..37c8f612 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -178,6 +178,7 @@ pub enum SystemClauseType { FetchGlobalVar, FetchGlobalVarWithOffset, GetChar, + GetSingleChar, ResetAttrVarState, TruncateIfNoLiftedHeapGrowthDiff, TruncateIfNoLiftedHeapGrowth, @@ -309,6 +310,7 @@ impl SystemClauseType { clause_name!("$fetch_global_var_with_offset") } &SystemClauseType::GetChar => clause_name!("$get_char"), + &SystemClauseType::GetSingleChar => clause_name!("$get_single_char"), &SystemClauseType::ResetAttrVarState => clause_name!("$reset_attr_var_state"), &SystemClauseType::TruncateIfNoLiftedHeapGrowth => { clause_name!("$truncate_if_no_lh_growth") @@ -455,6 +457,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), + ("$get_single_char", 1) => Some(SystemClauseType::GetSingleChar), ("$points_to_cont_reset_marker", 1) => { Some(SystemClauseType::PointsToContinuationResetMarker) } diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 17235d3b..15c81403 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -47,8 +47,8 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :- current_input/1, current_output/1, 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, + findall/3, findall/4, get_char/1, get_single_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, set_input/1, set_output/1, setof/3, sub_atom/5, subsumes_term/2, @@ -933,6 +933,13 @@ get_char(C) :- ; throw(error(type_error(in_character, C), get_char/1)) ). +get_single_char(C) :- + ( var(C) -> '$get_single_char'(C) + ; C == end_of_file -> '$get_single_char'(C) + ; atom_length(C, 1) -> '$get_single_char'(C) + ; throw(error(type_error(in_character, C), get_char/1)) + ). + can_be_number(N, PI) :- ( var(N) -> true ; must_be_number(N, PI) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index cd9cc86f..bd35d6e6 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -67,6 +67,24 @@ pub fn next_keypress() -> ContinueResult { } } +pub fn get_single_char() -> char { + let c; + enable_raw_mode().expect("failed to enable raw mode"); + loop { + if let Ok(Event::Key(KeyEvent { code, .. })) = read() { + match code { + KeyCode::Char(ch) => { + c = ch; + break; + }, + _ => () + } + } + } + disable_raw_mode().expect("failed to disable raw mode"); + c +} + struct BrentAlgState { hare: Addr, tortoise: Addr, @@ -1463,6 +1481,13 @@ impl MachineState { } } } + &SystemClauseType::GetSingleChar => { + let c = get_single_char(); + + let a1 = self[temp_v!(1)]; + + self.unify(Addr::Char(c), a1); + } &SystemClauseType::GetModuleClause => { let module = self[temp_v!(3)]; let head = self[temp_v!(1)]; From 11ea92288d50a3f0a2fb3a90077abf559b1f5783 Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 12:52:49 +0200 Subject: [PATCH 13/24] Moved get_single_char from builtins.pl to charsio.pl --- src/prolog/lib/builtins.pl | 11 ++--------- src/prolog/lib/charsio.pl | 11 ++++++++++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/prolog/lib/builtins.pl b/src/prolog/lib/builtins.pl index 15c81403..17235d3b 100644 --- a/src/prolog/lib/builtins.pl +++ b/src/prolog/lib/builtins.pl @@ -47,8 +47,8 @@ user:term_expansion((:- op(Pred, Spec, [Op | OtherOps])), OpResults) :- current_input/1, current_output/1, 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, get_single_char/1, - halt/0, max_arity/1, number_chars/2, number_codes/2, + 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, set_input/1, set_output/1, setof/3, sub_atom/5, subsumes_term/2, @@ -933,13 +933,6 @@ get_char(C) :- ; throw(error(type_error(in_character, C), get_char/1)) ). -get_single_char(C) :- - ( var(C) -> '$get_single_char'(C) - ; C == end_of_file -> '$get_single_char'(C) - ; atom_length(C, 1) -> '$get_single_char'(C) - ; throw(error(type_error(in_character, C), get_char/1)) - ). - can_be_number(N, PI) :- ( var(N) -> true ; must_be_number(N, PI) diff --git a/src/prolog/lib/charsio.pl b/src/prolog/lib/charsio.pl index 9cf5f325..5fde900c 100644 --- a/src/prolog/lib/charsio.pl +++ b/src/prolog/lib/charsio.pl @@ -1,4 +1,5 @@ -:- module(charsio, [read_term_from_chars/2, +:- module(charsio, [get_single_char/1, + read_term_from_chars/2, write_term_to_chars/3]). :- use_module(library(iso_ext)). @@ -56,6 +57,14 @@ extend_var_list_([V|Vs], N, VarList, NewVarList, VarType) :- ). +get_single_char(C) :- + ( var(C) -> '$get_single_char'(C) + ; C == end_of_file -> '$get_single_char'(C) + ; atom_length(C, 1) -> '$get_single_char'(C) + ; throw(error(type_error(in_character, C), get_char/1)) + ). + + read_term_from_chars(Chars, Term) :- ( var(Chars) -> throw(error(instantiation_error, read_term_from_chars/2)) From 5d064b18e61b4b7a6c2aa61b84fa8110c4429d76 Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 13:30:52 +0200 Subject: [PATCH 14/24] get_single_char reads Enter as \n --- src/prolog/machine/system_calls.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index bd35d6e6..1b2f48f0 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -77,6 +77,10 @@ pub fn get_single_char() -> char { c = ch; break; }, + KeyCode::Enter => { + c = '\n'; + break; + }, _ => () } } From b35b49f7b3636a786d0f996f4189a36ab6883a3e Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 13:33:42 +0200 Subject: [PATCH 15/24] get_single_char reads Tab as \t --- src/prolog/machine/system_calls.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 1b2f48f0..1a783ac9 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -81,6 +81,10 @@ pub fn get_single_char() -> char { c = '\n'; break; }, + KeyCode::Tab => { + c = '\t'; + break; + }, _ => () } } From 99e1a5f11749a519a2ecde8cc9d1ffe9bea925ad Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 13:54:18 +0200 Subject: [PATCH 16/24] Removed $raw_input_read_char --- src/prolog/clause_types.rs | 3 -- src/prolog/machine/system_calls.rs | 56 ------------------------------ src/prolog/toplevel.pl | 5 +-- 3 files changed, 3 insertions(+), 61 deletions(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index 37c8f612..660de341 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -242,7 +242,6 @@ pub enum SystemClauseType { InstallNewBlock, Maybe, QuotedToken, - RawInputReadChar, ReadTermFromChars, ResetBlock, ReturnFromVerifyAttr, @@ -366,7 +365,6 @@ impl SystemClauseType { &SystemClauseType::QuotedToken => { clause_name!("$quoted_token") } - &SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"), &SystemClauseType::RedoAttrVarBinding => clause_name!("$redo_attr_var_binding"), &SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"), &SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"), @@ -509,7 +507,6 @@ impl SystemClauseType { ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint), ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock), ("$quoted_token", 1) => Some(SystemClauseType::QuotedToken), - ("$raw_input_read_char", 1) => Some(SystemClauseType::RawInputReadChar), ("$nextEP", 3) => Some(SystemClauseType::NextEP), ("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm), ("$read_term", 2) => Some(SystemClauseType::ReadTerm), diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 1a783ac9..e2cad96a 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -31,42 +31,6 @@ use std::rc::Rc; use crate::crossterm::event::{read, Event, KeyCode, KeyEvent}; use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode}; -pub enum ContinueResult { - ContinueQuery, - Conclude, - Help, - PrintWithoutMaxDepth, - PrintWithMaxDepth -} - -pub fn next_keypress() -> ContinueResult { - loop { - match read() { - Ok(Event::Key(KeyEvent { code, .. })) => { - match code { - KeyCode::Char('w') => { - return ContinueResult::PrintWithoutMaxDepth; - } - KeyCode::Char('p') => { - return ContinueResult::PrintWithMaxDepth; - } - KeyCode::Char(' ') | KeyCode::Char(';') | KeyCode::Char('n') => { - return ContinueResult::ContinueQuery; - } - KeyCode::Char('.') => { - return ContinueResult::Conclude; - } - KeyCode::Char('h') => { - return ContinueResult::Help; - } - _ => {} - } - } - _ => {} - } - } -} - pub fn get_single_char() -> char { let c; enable_raw_mode().expect("failed to enable raw mode"); @@ -2913,26 +2877,6 @@ impl MachineState { &SystemClauseType::InstallNewBlock => { self.install_new_block(temp_v!(1)); } - &SystemClauseType::RawInputReadChar => { - let keypress = { - enable_raw_mode().expect("failed to transition into raw mode"); - let result = next_keypress(); - disable_raw_mode().expect("failed to transition out of raw mode"); - - result - }; - - let c = match keypress { - ContinueResult::ContinueQuery => ';', - ContinueResult::Conclude => '.', - ContinueResult::Help => 'h', - ContinueResult::PrintWithoutMaxDepth => 'w', - ContinueResult::PrintWithMaxDepth => 'p', - }; - - let target = self[temp_v!(1)]; - self.unify(Addr::Char(c), target); - } &SystemClauseType::NextEP => { let first_arg = self.store(self.deref(self[temp_v!(1)])); diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 27bf71f5..e7eb3b7a 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -145,7 +145,7 @@ ). '$read_input'(ThreadedGoals, NewVarList) :- - '$raw_input_read_char'(C), + '$get_single_char'(C), ( C == w -> nl, write(' '), @@ -161,8 +161,9 @@ ; C == h -> '$help_message', '$read_input'(ThreadedGoals, NewVarList) - ; C == '.', + ; C == '.' -> nl, write('; ...'), nl + ; '$read_input'(ThreadedGoals, NewVarList) ). '$help_message' :- From 105e9c8e8887dbbb281454cabca323cb07dbe1b1 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Sat, 18 Apr 2020 14:33:11 +0200 Subject: [PATCH 17/24] use get_single_char/1 --- src/prolog/toplevel.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index e7eb3b7a..dc58c386 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -145,7 +145,7 @@ ). '$read_input'(ThreadedGoals, NewVarList) :- - '$get_single_char'(C), + get_single_char(C), ( C == w -> nl, write(' '), From 1f7e18f2a9e9893d5a5f2199e1571cbcce80fc82 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Sat, 18 Apr 2020 14:38:03 +0200 Subject: [PATCH 18/24] instead of a type error, use a domain error The preceding use of atom_length/2 already ensures that C has the correct type (i.e., atom). However, its domain may still be wrong, if its length is greater than 1. --- src/prolog/lib/charsio.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prolog/lib/charsio.pl b/src/prolog/lib/charsio.pl index 5fde900c..29a668fd 100644 --- a/src/prolog/lib/charsio.pl +++ b/src/prolog/lib/charsio.pl @@ -61,7 +61,7 @@ get_single_char(C) :- ( var(C) -> '$get_single_char'(C) ; C == end_of_file -> '$get_single_char'(C) ; atom_length(C, 1) -> '$get_single_char'(C) - ; throw(error(type_error(in_character, C), get_char/1)) + ; throw(error(domain_error(in_character, C), get_char/1)) ). From 98a37905b8fb4e267dd8038076e89920a6a07156 Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 15:21:19 +0200 Subject: [PATCH 19/24] Fixed the predicate name when error is thrown --- src/prolog/lib/charsio.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prolog/lib/charsio.pl b/src/prolog/lib/charsio.pl index 29a668fd..11dc04b7 100644 --- a/src/prolog/lib/charsio.pl +++ b/src/prolog/lib/charsio.pl @@ -61,7 +61,7 @@ get_single_char(C) :- ( var(C) -> '$get_single_char'(C) ; C == end_of_file -> '$get_single_char'(C) ; atom_length(C, 1) -> '$get_single_char'(C) - ; throw(error(domain_error(in_character, C), get_char/1)) + ; throw(error(domain_error(in_character, C), get_single_char/1)) ). From 988366e37f06f599e36f2cc3193e80ebdc088182 Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 16:57:45 +0200 Subject: [PATCH 20/24] Added Space for continuation --- src/prolog/toplevel.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index dc58c386..f2adba33 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -158,6 +158,8 @@ '$read_input'(ThreadedGoals, NewVarList) ; C == (';') -> nl, write('; '), false + ; C == (' ') -> + nl, write('; '), false ; C == h -> '$help_message', '$read_input'(ThreadedGoals, NewVarList) From 6dcefcfb716680437575ec19bfbe8d0b44d6a0ec Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Sat, 18 Apr 2020 17:40:19 +0200 Subject: [PATCH 21/24] small simplifications --- src/prolog/toplevel.pl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index f2adba33..09131d6d 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -146,24 +146,22 @@ '$read_input'(ThreadedGoals, NewVarList) :- get_single_char(C), - ( C == w -> + ( C = w -> nl, write(' '), '$write_eq'(ThreadedGoals, NewVarList, 0), '$read_input'(ThreadedGoals, NewVarList) - ; C == p -> + ; C = p -> nl, write(' '), '$write_eq'(ThreadedGoals, NewVarList, 20), '$read_input'(ThreadedGoals, NewVarList) - ; C == (';') -> + ; member(C, [';', ' ']) -> nl, write('; '), false - ; C == (' ') -> - nl, write('; '), false - ; C == h -> + ; C = h -> '$help_message', '$read_input'(ThreadedGoals, NewVarList) - ; C == '.' -> + ; C = '.' -> nl, write('; ...'), nl ; '$read_input'(ThreadedGoals, NewVarList) ). From 98a32790cd5991b3c438511178b5c34225e010ba Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Sat, 18 Apr 2020 17:47:24 +0200 Subject: [PATCH 22/24] ENHANCED: the toplevel interaction now supports RETURN as a synonym for "." This is made possible due to the recent improvements by @notoria. --- README.md | 4 ++-- src/prolog/toplevel.pl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4fa1bab5..652e7b98 100644 --- a/README.md +++ b/README.md @@ -168,8 +168,8 @@ predicates it defines. For example, with the program shown above: ; What = pure_world. ``` -Press `SPACE` to show further answers, if any exist. Press `.` to -abort the search and return to the toplevel prompt. +Press `SPACE` to show further answers, if any exist. Press `RETURN` or + `.` to abort the search and return to the toplevel prompt. Press `h` to show a help message. To quit Scryer Prolog, use the standard predicate `halt/0`: diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 09131d6d..6cee5ecc 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -161,7 +161,7 @@ ; C = h -> '$help_message', '$read_input'(ThreadedGoals, NewVarList) - ; C = '.' -> + ; member(C, ['\n', .]) -> nl, write('; ...'), nl ; '$read_input'(ThreadedGoals, NewVarList) ). @@ -169,7 +169,7 @@ '$help_message' :- nl, nl, write('SPACE, "n" or ";": next solution, if any\n'), - write('".": stop enumeration\n'), + write('RETURN or ".": stop enumeration\n'), write('"h": display this help message\n'), write('"w": write terms without depth limit\n'), write('"p": print terms with depth limit\n\n'). From 2ae5472872b11110f014670edd548839c2f12da5 Mon Sep 17 00:00:00 2001 From: Markus Triska Date: Sat, 18 Apr 2020 18:08:08 +0200 Subject: [PATCH 23/24] reintroduce "n" as a synonym for ";" and " " --- src/prolog/toplevel.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 6cee5ecc..aad24573 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -156,7 +156,7 @@ write(' '), '$write_eq'(ThreadedGoals, NewVarList, 20), '$read_input'(ThreadedGoals, NewVarList) - ; member(C, [';', ' ']) -> + ; member(C, [';', ' ', n]) -> nl, write('; '), false ; C = h -> '$help_message', From 2e15ab44ab473e49cb518b030da21ba27b7fed2c Mon Sep 17 00:00:00 2001 From: notoria Date: Sat, 18 Apr 2020 18:28:26 +0200 Subject: [PATCH 24/24] Removed a check in get_single_char --- src/prolog/lib/charsio.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prolog/lib/charsio.pl b/src/prolog/lib/charsio.pl index 11dc04b7..4e3a4a22 100644 --- a/src/prolog/lib/charsio.pl +++ b/src/prolog/lib/charsio.pl @@ -59,7 +59,6 @@ extend_var_list_([V|Vs], N, VarList, NewVarList, VarType) :- get_single_char(C) :- ( var(C) -> '$get_single_char'(C) - ; C == end_of_file -> '$get_single_char'(C) ; atom_length(C, 1) -> '$get_single_char'(C) ; throw(error(domain_error(in_character, C), get_single_char/1)) ).