fix unification on string lists.
This commit is contained in:
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -86,7 +86,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prolog_parser"
|
name = "prolog_parser"
|
||||||
version = "0.7.18"
|
version = "0.7.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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.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 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 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_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 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"
|
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
|
|||||||
downcast = "0.9.1"
|
downcast = "0.9.1"
|
||||||
num = "0.2"
|
num = "0.2"
|
||||||
ordered-float = "0.5.0"
|
ordered-float = "0.5.0"
|
||||||
prolog_parser = "0.7.18"
|
prolog_parser = "0.7.19"
|
||||||
|
|
||||||
[dependencies.termion]
|
[dependencies.termion]
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@@ -271,7 +271,7 @@ fn try_in_situ(machine_st: &mut MachineState, name: ClauseName, arity: usize,
|
|||||||
} else {
|
} else {
|
||||||
let stub = MachineError::functor_stub(name.clone(), arity);
|
let stub = MachineError::functor_stub(name.clone(), arity);
|
||||||
let h = machine_st.heap.h;
|
let h = machine_st.heap.h;
|
||||||
|
|
||||||
Err(machine_st.error_form(MachineError::existence_error(h, name, arity),
|
Err(machine_st.error_form(MachineError::existence_error(h, name, arity),
|
||||||
stub))
|
stub))
|
||||||
}
|
}
|
||||||
@@ -601,7 +601,7 @@ pub(crate) trait CallPolicy: Any {
|
|||||||
let a2 = machine_st[temp_v!(2)].clone();
|
let a2 = machine_st[temp_v!(2)].clone();
|
||||||
|
|
||||||
if let Addr::Con(Constant::String(s)) = a1 {
|
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));
|
machine_st.write_constant_to_var(a2, Constant::String(s));
|
||||||
} else {
|
} else {
|
||||||
machine_st.fail = true;
|
machine_st.fail = true;
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ impl MachineState {
|
|||||||
return s1 == s2;
|
return s1 == s2;
|
||||||
} else {
|
} else {
|
||||||
self.pstr_trail(s1.clone());
|
self.pstr_trail(s1.clone());
|
||||||
s1.set_non_expandable();
|
s1.set_expandable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -194,7 +194,7 @@ impl MachineState {
|
|||||||
self.pstr_trail(s2.clone());
|
self.pstr_trail(s2.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
s2.set_non_expandable();
|
s2.set_expandable(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ impl MachineState {
|
|||||||
if self.flags.double_quotes.is_chars() => {
|
if self.flags.double_quotes.is_chars() => {
|
||||||
if s.is_expandable() && s.is_empty() {
|
if s.is_expandable() && s.is_empty() {
|
||||||
self.pstr_trail(s.clone());
|
self.pstr_trail(s.clone());
|
||||||
s.set_non_expandable();
|
s.set_expandable(false);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,8 +335,8 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let len = s.len();
|
let truncate_end = s.len() + s.cursor();
|
||||||
self.pstr_trail.push((self.b, s, len));
|
self.pstr_trail.push((self.b, s, truncate_end));
|
||||||
self.pstr_tr += 1;
|
self.pstr_tr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,24 +477,39 @@ impl MachineState {
|
|||||||
self.fail = match c {
|
self.fail = match c {
|
||||||
Constant::EmptyList if self.flags.double_quotes.is_chars() =>
|
Constant::EmptyList if self.flags.double_quotes.is_chars() =>
|
||||||
!s.is_empty(),
|
!s.is_empty(),
|
||||||
Constant::String(ref s2) if s.is_empty() && s.is_expandable() => {
|
Constant::String(ref s2)
|
||||||
self.pstr_trail(s.clone());
|
if s.is_expandable() && s2.starts_with(s) => {
|
||||||
s.append(s2);
|
self.pstr_trail(s.clone());
|
||||||
false
|
s.append_suffix(s2);
|
||||||
},
|
s.set_expandable(s2.is_expandable());
|
||||||
|
false
|
||||||
|
},
|
||||||
Constant::String(s2) => *s != s2,
|
Constant::String(s2) => *s != s2,
|
||||||
Constant::Atom(ref a, _) if s.is_empty() && s.is_expandable() =>
|
Constant::Atom(ref a, _)
|
||||||
if let Some(c) = a.as_str().chars().next() {
|
if a.as_str().starts_with(&s.borrow()[s.cursor() ..]) =>
|
||||||
if c.len_utf8() == a.as_str().len() {
|
if let Some(c) = a.as_str().chars().next() {
|
||||||
self.write_char_to_string(s, c)
|
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 {
|
} else {
|
||||||
true
|
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 {
|
} else {
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
Constant::Char(ref c) if s.is_empty() && s.is_expandable() =>
|
|
||||||
self.write_char_to_string(s, *c),
|
|
||||||
_ => true
|
_ => true
|
||||||
},
|
},
|
||||||
Addr::Con(c1) =>
|
Addr::Con(c1) =>
|
||||||
|
|||||||
19
src/tests.rs
19
src/tests.rs
@@ -1988,6 +1988,9 @@ fn test_queries_on_string_lists()
|
|||||||
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), \"def\" = Y.",
|
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]"]]);
|
[["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),
|
assert_prolog_success!(&mut wam, "?- partial_string(\"abc\", X), matcher(X, Y), partial_string(\"def\", Y),
|
||||||
Y = \"defghijkl\".",
|
Y = \"defghijkl\".",
|
||||||
[["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
|
[["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.",
|
\"defghijkl\" = Y.",
|
||||||
[["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
|
[["X = [a, b, c, d, e, f, g, h, i, j, k, l]",
|
||||||
"Y = [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].",
|
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 = _"]]);
|
[["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.",
|
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 | _]"]]);
|
["X = [b, d | _]", "Y = [d | _]"]]);
|
||||||
assert_prolog_success!(&mut wam, "?- partial_string(\"bc\", X), matcher(X, Y).",
|
assert_prolog_success!(&mut wam, "?- partial_string(\"bc\", X), matcher(X, Y).",
|
||||||
[["X = [b, c | _]", "Y = [c | _]"]]);
|
[["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]"]]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user