correct for issues #88, #89, #90, conformity test #208.

This commit is contained in:
Mark Thom
2019-04-06 09:46:42 -06:00
parent a3af56351b
commit 16eadc7412
8 changed files with 43 additions and 35 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "scryer-prolog" name = "scryer-prolog"
version = "0.8.44" version = "0.8.45"
authors = ["Mark Thom <markjordanthom@gmail.com>"] authors = ["Mark Thom <markjordanthom@gmail.com>"]
repository = "https://github.com/mthom/scryer-prolog" repository = "https://github.com/mthom/scryer-prolog"
description = "A modern Prolog implementation written mostly in Rust." description = "A modern Prolog implementation written mostly in Rust."

View File

@@ -317,6 +317,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<TermMarker>
&InlinedClauseType::IsAtom(..) => &InlinedClauseType::IsAtom(..) =>
match terms[0].as_ref() { match terms[0].as_ref() {
&Term::Constant(_, Constant::Char(_)) &Term::Constant(_, Constant::Char(_))
| &Term::Constant(_, Constant::EmptyList)
| &Term::Constant(_, Constant::Atom(..)) => { | &Term::Constant(_, Constant::Atom(..)) => {
code.push(succeed!()); code.push(succeed!());
}, },

View File

@@ -264,7 +264,7 @@ macro_rules! push_space_if_amb {
) )
} }
fn continues_with_append(atom: &str, op: &str) -> bool { fn requires_space(atom: &str, op: &str) -> bool {
match atom.chars().last() { match atom.chars().last() {
Some(ac) => op.chars().next().map(|oc| { Some(ac) => op.chars().next().map(|oc| {
if alpha_char!(ac) { if alpha_char!(ac) {
@@ -277,6 +277,8 @@ fn continues_with_append(atom: &str, op: &str) -> bool {
alpha_numeric_char!(oc) alpha_numeric_char!(oc)
} else if sign_char!(ac) { } else if sign_char!(ac) {
sign_char!(oc) || decimal_digit_char!(oc) sign_char!(oc) || decimal_digit_char!(oc)
} else if ac == '0' {
!non_quoted_token(op.chars())
} else { } else {
false false
} }
@@ -382,7 +384,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
fn ambiguity_check(&self, atom: &str) -> bool fn ambiguity_check(&self, atom: &str) -> bool
{ {
let tail = self.outputter.range_from(self.last_item_idx ..); let tail = self.outputter.range_from(self.last_item_idx ..);
continues_with_append(tail, atom) requires_space(tail, atom)
} }
// TODO: create a DirectedOp factory method. Use it here, and above. // TODO: create a DirectedOp factory method. Use it here, and above.
@@ -579,11 +581,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter>
} }
fn print_op(&mut self, atom: &str) { fn print_op(&mut self, atom: &str) {
if atom == "," { push_space_if_amb!(self, atom, {
self.push_char(','); if atom == "," {
} else { self.push_char(',');
self.print_op_addendum(atom); } else {
} self.print_op_addendum(atom);
}
});
} }
fn print_char(&mut self, c: char) { fn print_char(&mut self, c: char) {

View File

@@ -4,7 +4,7 @@
(+)/2, (**)/2, (*)/2, (-)/1, (-)/2, (/)/2, (/\)/2, (\/)/2, (+)/2, (**)/2, (*)/2, (-)/1, (-)/2, (/)/2, (/\)/2, (\/)/2,
(is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2, (is)/2, (xor)/2, (div)/2, (//)/2, (rdiv)/2, (<<)/2, (>>)/2,
(mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (>=)/2, (mod)/2, (rem)/2, (>)/2, (<)/2, (=\=)/2, (=:=)/2, (>=)/2,
(=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2, (==)/2, (\==)/2, (=<)/2, (',')/2, (->)/2, (;)/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, abolish/1, asserta/1, assertz/1, atom_chars/2, atom_codes/2,
atom_length/2, bagof/3, bb_b_put/2, bb_get/2, bb_put/2, atom_length/2, bagof/3, bb_b_put/2, bb_get/2, bb_put/2,
@@ -137,10 +137,10 @@ repeat :- repeat.
','(G1, G2) :- '$get_b_value'(B), '$call_with_default_policy'(comma_errors(G1, G2, B)). ','(G1, G2) :- '$get_b_value'(B), '$call_with_default_policy'(comma_errors(G1, G2, B)).
:- non_counted_backtracking comma_errors/3. :- non_counted_backtracking comma_errors/3.
comma_errors(G1, G2, B) :- var(G1), throw(error(instantiation_error, (,)/2)). comma_errors(G1, G2, B) :- var(G1), throw(error(instantiation_error, (',')/2)).
comma_errors(G1, G2, B) :- '$call_with_default_policy'(','(G1, G2, B)). comma_errors(G1, G2, B) :- '$call_with_default_policy'(','(G1, G2, B)).
:- non_counted_backtracking (,)/3. :- non_counted_backtracking (',')/3.
','(!, CF, B) :- compound(CF), ','(!, CF, B) :- compound(CF),
'$call_with_default_policy'(CF = ','(G1, G2)), '$call_with_default_policy'(CF = ','(G1, G2)),
'$set_cp'(B), '$set_cp'(B),
@@ -256,12 +256,13 @@ expand_term(Term0, Term) :- '$expand_term'(Term0, Term).
% term_variables. % term_variables.
can_be(Type, Term) :- error:can_be(Type, Term). % ensures List is either a variable or a proper list.
can_be_list(List, _) :- var(List), !.
can_be_list(List, _) :- '$skip_max_list'(_, -1, List, Tail), Tail == [], !.
can_be_list(List, PI) :- throw(error(type_error(list, List), PI)).
term_variables(Term, Vars) :- term_variables(Term, Vars) :-
catch(can_be(list, Vars), error(E, Ctx), can_be_list(Vars, term_variables/2),
( ( var(Ctx) -> Ctx = term_variables/2 ; true ),
throw(error(E, Ctx)) ) ),
'$term_variables'(Term, Vars). '$term_variables'(Term, Vars).
% setup_call_cleanup. % setup_call_cleanup.
@@ -721,10 +722,15 @@ current_predicate(Pred) :-
'$get_next_op_db_ref'(Ref, NextRef), '$get_next_op_db_ref'(Ref, NextRef),
'$iterate_op_db_refs'(NextRef, Priority, Spec, Op). '$iterate_op_db_refs'(NextRef, Priority, Spec, Op).
can_be_op_priority(Priority) :- var(Priority).
can_be_op_priority(Priority) :- op_priority(Priority).
can_be_op_specifier(Spec) :- var(Spec).
can_be_op_specifier(Spec) :- op_specifier(Spec).
current_op(Priority, Spec, Op) :- current_op(Priority, Spec, Op) :-
( nonvar(Op), \+ atom(Op) ( can_be_op_priority(Priority), can_be_op_specifier(Spec), error:can_be(atom, Op)
-> throw(error(type_error(atom, Op), current_op/3)) -> '$get_next_op_db_ref'(Ref, _),
; '$get_next_op_db_ref'(Ref, _),
'$iterate_op_db_refs'(Ref, Priority, Spec, Op) '$iterate_op_db_refs'(Ref, Priority, Spec, Op)
). ).
@@ -753,7 +759,7 @@ op_specifier(OpSpec) :- atom(OpSpec),
op_specifier(OpSpec) :- throw(error(type_error(atom, OpSpec), op/3)). op_specifier(OpSpec) :- throw(error(type_error(atom, OpSpec), op/3)).
valid_op(Op) :- atom(Op), valid_op(Op) :- atom(Op),
( Op == (,) -> throw(error(permission_error(modify, operator, (,)), op/3)) % 8.14.3.3 j), k). ( Op == (',') -> throw(error(permission_error(modify, operator, (',')), op/3)) % 8.14.3.3 j), k).
; Op == {} -> throw(error(permission_error(create, operator, {}), op/3)) ; Op == {} -> throw(error(permission_error(create, operator, {}), op/3))
; Op == [] -> throw(error(permission_error(create, operator, []), op/3)) ; Op == [] -> throw(error(permission_error(create, operator, []), op/3))
; true ; true
@@ -810,24 +816,20 @@ no_var_in_list([]).
no_var_in_list([X|Xs]) :- var(X), !, '$fail'. no_var_in_list([X|Xs]) :- var(X), !, '$fail'.
no_var_in_list([_|Xs]) :- no_var_in_list(Xs). no_var_in_list([_|Xs]) :- no_var_in_list(Xs).
atom_chars(Atom, List) :- atom_chars(Atom, List) :-
error:can_be(list, List),
( var(Atom) -> ( var(Atom) ->
( var(List) -> throw(error(instantiation_error, atom_chars/2)) ( var(List) -> throw(error(instantiation_error, atom_chars/2))
; no_var_in_list(List) -> '$atom_chars'(Atom, List) ; can_be_list(List, atom_chars/3), no_var_in_list(List) -> '$atom_chars'(Atom, List)
) )
; atom(Atom) -> '$atom_chars'(Atom, List) ; atom(Atom) -> '$atom_chars'(Atom, List)
; Atom == [] -> '$atom_chars'(Atom, List)
; throw(error(type_error(atom, Atom), atom_chars/2)) ; throw(error(type_error(atom, Atom), atom_chars/2))
). ).
atom_codes(Atom, List) :- atom_codes(Atom, List) :-
error:can_be(list, List),
( var(Atom) -> ( var(Atom) ->
( var(List) -> throw(error(instantiation_error, atom_codes/2)) ( var(List) -> throw(error(instantiation_error, atom_codes/2))
; no_var_in_list(List) -> '$atom_codes'(Atom, List) ; can_be_list(List, atom_codes/3), no_var_in_list(List) -> '$atom_codes'(Atom, List)
) )
; atom(Atom) -> '$atom_codes'(Atom, List) ; atom(Atom) -> '$atom_codes'(Atom, List)
; Atom == [] -> '$atom_codes'(Atom, List)
; throw(error(type_error(atom, Atom), atom_codes/2)) ; throw(error(type_error(atom, Atom), atom_codes/2))
). ).

View File

@@ -1,4 +1,4 @@
:- module(reif, [if_/3, (=)/3, (,)/3, (;)/3, cond_t/3, dif/3, :- module(reif, [if_/3, (=)/3, (',')/3, (;)/3, cond_t/3, dif/3,
memberd_t/3, tfilter/3, tmember/2, tmember_t/3, memberd_t/3, tfilter/3, tmember/2, tmember_t/3,
tpartition/4]). tpartition/4]).

View File

@@ -1905,6 +1905,7 @@ impl MachineState {
match d { match d {
Addr::Con(Constant::Atom(..)) | Addr::Con(Constant::Char(_)) => self.p += 1, Addr::Con(Constant::Atom(..)) | Addr::Con(Constant::Char(_)) => self.p += 1,
Addr::Con(Constant::EmptyList) => self.p += 1,
_ => self.fail = true _ => self.fail = true
}; };
}, },

View File

@@ -362,7 +362,7 @@ impl MachineState {
}, },
ref addr if addr.is_ref() => { ref addr if addr.is_ref() => {
let stub = MachineError::functor_stub(clause_name!("atom_chars"), 2); let stub = MachineError::functor_stub(clause_name!("atom_chars"), 2);
match self.try_from_list(temp_v!(2), stub.clone()) { match self.try_from_list(temp_v!(2), stub.clone()) {
Err(e) => return Err(e), Err(e) => return Err(e),
Ok(addrs) => { Ok(addrs) => {

View File

@@ -1413,7 +1413,7 @@ fn test_queries_on_builtins()
assert_prolog_failure!(&mut wam, "?- atom(X)."); assert_prolog_failure!(&mut wam, "?- atom(X).");
assert_prolog_success!(&mut wam, "?- atom(a)."); assert_prolog_success!(&mut wam, "?- atom(a).");
assert_prolog_failure!(&mut wam, "?- atom(\"string\")."); assert_prolog_failure!(&mut wam, "?- atom(\"string\").");
assert_prolog_failure!(&mut wam, "?- atom([])."); assert_prolog_success!(&mut wam, "?- atom([]).");
assert_prolog_failure!(&mut wam, "?- atom(1)."); assert_prolog_failure!(&mut wam, "?- atom(1).");
assert_prolog_failure!(&mut wam, "?- atom(0)."); assert_prolog_failure!(&mut wam, "?- atom(0).");
assert_prolog_failure!(&mut wam, "?- atom(0.0)."); assert_prolog_failure!(&mut wam, "?- atom(0.0).");
@@ -1750,12 +1750,12 @@ fn test_queries_on_builtins()
assert_prolog_success!(&mut wam, "?- bagof(X, (X=Y; X=Z; Y=1), L).", assert_prolog_success!(&mut wam, "?- bagof(X, (X=Y; X=Z; Y=1), L).",
[["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"], [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
["L = [_188]", "X = _0", "Y = 1", "Z = _6"]]); ["L = [_112]", "X = _0", "Y = 1", "Z = _6"]]);
submit(&mut wam, "a(1, f(_)). a(2, f(_))."); submit(&mut wam, "a(1, f(_)). a(2, f(_)).");
assert_prolog_success!(&mut wam, "?- bagof(X, a(X, Y), L).", assert_prolog_success!(&mut wam, "?- bagof(X, a(X, Y), L).",
[["L = [1, 2]", "X = _0", "Y = f(_154)"]]); [["L = [1, 2]", "X = _0", "Y = f(_78)"]]);
assert_prolog_success!(&mut wam, "?- setof(X, (X = 1 ; X = 2), S).", assert_prolog_success!(&mut wam, "?- setof(X, (X = 1 ; X = 2), S).",
[["S = [1, 2]", "X = _0"]]); [["S = [1, 2]", "X = _0"]]);
@@ -1767,7 +1767,7 @@ fn test_queries_on_builtins()
["L = [1]", "Y = 2"]]); ["L = [1]", "Y = 2"]]);
assert_prolog_success!(&mut wam, "?- setof(X, (X=Y; X=Z; Y=1), L).", assert_prolog_success!(&mut wam, "?- setof(X, (X=Y; X=Z; Y=1), L).",
[["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"], [["L = [_3, _6]", "X = _0", "Y = _3", "Z = _6"],
["L = [_188]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]]); ["L = [_112]", "Y = 1", "X = _0", "Y = 1", "Z = _6"]]);
assert_prolog_failure!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,c),f(a,b)])."); assert_prolog_failure!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,c),f(a,b)]).");
assert_prolog_success!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,b),f(a,c)]).", assert_prolog_success!(&mut wam, "?- setof(X, member(X, [f(U,b),f(V,c)]), [f(a,b),f(a,c)]).",
[["U = a", "V = a", "X = _0"]]); [["U = a", "V = a", "X = _0"]]);
@@ -1794,12 +1794,12 @@ fn test_queries_on_builtins()
assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).", assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
[["S = [1, 2]", "X = _0", "Y = _5"]]); [["S = [1, 2]", "X = _0", "Y = _5"]]);
assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).", assert_prolog_success!(&mut wam, "?- bagof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
[["S = [1, _240, 2]", "X = _0", "Y = _5"]]); [["S = [1, _126, 2]", "X = _0", "Y = _5"]]);
assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).", assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1, Y = 1; (X = 2, Y = 2))), S).",
[["S = [1, 2]", "X = _0", "Y = _5"]]); [["S = [1, 2]", "X = _0", "Y = _5"]]);
assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).", assert_prolog_success!(&mut wam, "?- setof(X, Y^((X = 1 ; Y = 1) ; (X = 2, Y = 2)), S).",
[["S = [_240, 1, 2]", "X = _0", "Y = _5"]]); [["S = [_126, 1, 2]", "X = _0", "Y = _5"]]);
assert_prolog_success!(&mut wam, "?- setof(X, (exists(U,V) ^ member(X, [V,U,f(U),f(V)])), [a,b,f(b),f(a)])."); assert_prolog_success!(&mut wam, "?- setof(X, (exists(U,V) ^ member(X, [V,U,f(U),f(V)])), [a,b,f(b),f(a)]).");
submit(&mut wam, ":- use_module(library(non_iso))."); submit(&mut wam, ":- use_module(library(non_iso)).");