fix unification on string lists.

This commit is contained in:
Mark Thom
2018-12-23 12:14:03 -07:00
parent 40fa795d49
commit 56ec550031
5 changed files with 56 additions and 24 deletions

6
Cargo.lock generated
View File

@@ -86,7 +86,7 @@ dependencies = [
[[package]]
name = "prolog_parser"
version = "0.7.18"
version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -113,7 +113,7 @@ dependencies = [
"downcast 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prolog_parser 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)",
"prolog_parser 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -152,7 +152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
"checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
"checksum prolog_parser 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "fc54110ca6a70b5b509f14826af44b97fa6d7a0832d97229e7de3b73224d2c33"
"checksum prolog_parser 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "121df281a26fc692c1b8089bfdc0ba010a4af06379dec213446297c0c357713a"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"

View File

@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
downcast = "0.9.1"
num = "0.2"
ordered-float = "0.5.0"
prolog_parser = "0.7.18"
prolog_parser = "0.7.19"
[dependencies.termion]
version = "1.4.0"

View File

@@ -271,7 +271,7 @@ fn try_in_situ(machine_st: &mut MachineState, name: ClauseName, arity: usize,
} else {
let stub = MachineError::functor_stub(name.clone(), arity);
let h = machine_st.heap.h;
Err(machine_st.error_form(MachineError::existence_error(h, name, arity),
stub))
}
@@ -601,7 +601,7 @@ pub(crate) trait CallPolicy: Any {
let a2 = machine_st[temp_v!(2)].clone();
if let Addr::Con(Constant::String(s)) = a1 {
s.set_expandable();
s.set_expandable(true);
machine_st.write_constant_to_var(a2, Constant::String(s));
} else {
machine_st.fail = true;

View File

@@ -185,7 +185,7 @@ impl MachineState {
return s1 == s2;
} else {
self.pstr_trail(s1.clone());
s1.set_non_expandable();
s1.set_expandable(false);
}
return true;
@@ -194,7 +194,7 @@ impl MachineState {
self.pstr_trail(s2.clone());
}
s2.set_non_expandable();
s2.set_expandable(false);
return true;
}
@@ -281,7 +281,7 @@ impl MachineState {
if self.flags.double_quotes.is_chars() => {
if s.is_expandable() && s.is_empty() {
self.pstr_trail(s.clone());
s.set_non_expandable();
s.set_expandable(false);
continue;
}
@@ -335,8 +335,8 @@ impl MachineState {
}
}
let len = s.len();
self.pstr_trail.push((self.b, s, len));
let truncate_end = s.len() + s.cursor();
self.pstr_trail.push((self.b, s, truncate_end));
self.pstr_tr += 1;
}
@@ -477,24 +477,39 @@ impl MachineState {
self.fail = match c {
Constant::EmptyList if self.flags.double_quotes.is_chars() =>
!s.is_empty(),
Constant::String(ref s2) if s.is_empty() && s.is_expandable() => {
self.pstr_trail(s.clone());
s.append(s2);
false
},
Constant::String(ref s2)
if s.is_expandable() && s2.starts_with(s) => {
self.pstr_trail(s.clone());
s.append_suffix(s2);
s.set_expandable(s2.is_expandable());
false
},
Constant::String(s2) => *s != s2,
Constant::Atom(ref a, _) if s.is_empty() && s.is_expandable() =>
if let Some(c) = a.as_str().chars().next() {
if c.len_utf8() == a.as_str().len() {
self.write_char_to_string(s, c)
Constant::Atom(ref a, _)
if a.as_str().starts_with(&s.borrow()[s.cursor() ..]) =>
if let Some(c) = a.as_str().chars().next() {
if c.len_utf8() == a.as_str().len() {
// detect chars masquerading as atoms.
if s.is_empty() {
self.write_char_to_string(s, c);
}
false
} else {
true
}
} else {
true
}
},
Constant::Char(ref c) if s.is_empty() && s.is_expandable() =>
self.write_char_to_string(s, *c),
Constant::Char(ref c) =>
if s.borrow().chars().next() == Some(*c) && c.len_utf8() == s.len() {
s.set_expandable(false);
false
} else {
true
},
Constant::Char(ref c) if s.is_empty() && s.is_expandable() =>
self.write_char_to_string(s, *c),
_ => true
},
Addr::Con(c1) =>

View File

@@ -1988,6 +1988,9 @@ fn test_queries_on_string_lists()
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.",
[["X = [a, b, c, d, e, f]", "Y = [d, e, f]"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y).",
[["X = [a, b, c, d, e, f | _]",
"Y = [d, e, f | _]"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
Y = \"defghijkl\".",
[["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
@@ -1996,7 +1999,7 @@ fn test_queries_on_string_lists()
\"defghijkl\" = Y.",
[["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
"Y = [d, e, f, g, h, i, j, k, l]"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), Y = [d, e, f | G].",
[["X = [a, b, c, d, e, f | _]", "Y = [d, e, f | _]", "G = _"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), [d, e, f | G] = Y.",
@@ -2091,4 +2094,18 @@ fn test_queries_on_string_lists()
["X = [b, d | _]", "Y = [d | _]"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"bc\", X), matcher(X, Y).",
[["X = [b, c | _]", "Y = [c | _]"]]);
submit(&mut wam, "f(\"appendy jones\").
f(\"appendy smithers jones\").
f(\"appendy o'toole\").");
assert_prolog_success!(&mut wam, "?- partial_string(\"appendy\", X), f(X).",
[["X = [a, p, p, e, n, d, y, ' ', j, o, n, e, s]"],
["X = [a, p, p, e, n, d, y, ' ', s, m, i, t, h, e, r, s, ' ', j, o, n, e, s]"],
["X = [a, p, p, e, n, d, y, ' ', o, ''', t, o, o, l, e]"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abcdef\", X).",
[["X = [a, b, c, d, e, f | _]"]]);
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), partial_string(\"abcdef\", X), X = \"abcdef\".",
[["X = [a, b, c, d, e, f]"]]);
}