fix unification on string lists.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
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.",
|
||||
[["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]"]]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user