]> Repositorios git - scryer-prolog.git/commitdiff
fix unification on string lists.
authorMark Thom <[email protected]>
Sun, 23 Dec 2018 19:14:03 +0000 (12:14 -0700)
committerMark Thom <[email protected]>
Sun, 23 Dec 2018 19:14:03 +0000 (12:14 -0700)
Cargo.lock
Cargo.toml
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/tests.rs

index 4228369c08889e9e8ad34ed93c15a7c8af31022e..3b053f79d4cdb397288e9918353979ead8170df7 100644 (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"
index 77018d328a493e8efb60c15cf50ae40b91070446..d992eeaa67c91b378e60dc4e1f00940027b33f61 100644 (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"
\ No newline at end of file
index 9c9bbc408bc6761d6a5427861946ff336bc6beac..d6aa978677227e885dd7cbd0c07d10dafd6a6129 100644 (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;
index d479d2e0ab8dd63c53e1c029383ced2ab5eb109e..16881958be31a6fccaf7a6bd4cd230c783848287 100644 (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) =>
index a7ae5558bef37d82d4cea118a49ceb91942b7369..e4e21c17a8668232dae3e2df4101ddf1d62f4f80 100644 (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]"]]);
 }