]> Repositorios git - scryer-prolog.git/commitdiff
compare the tails of partial string prefixes in compare_pstr_prefixes (#883)
authorMark Thom <[email protected]>
Mon, 22 Mar 2021 18:44:58 +0000 (12:44 -0600)
committerMark Thom <[email protected]>
Mon, 22 Mar 2021 18:44:58 +0000 (12:44 -0600)
src/examples/bimetatrans/bimetatrans_tests.pl
src/machine/partial_string.rs

index eab6f29478e4e3028df524e600baba30fe470217..59a95cfafac355d941ad74999357ff1f32c3f1a2 100644 (file)
@@ -1,4 +1,4 @@
-:- module(bimetatran_tests, [test_bimetatrans/0]).
+:- module(bimetatrans_tests, [test_bimetatrans/0]).
 
 :- use_module(bimetatrans).
 
  * order of ascending N.
  */
 
-term_expansion(Term0, Term) :-
-    nonvar(Term0),
-    Term0 = test(N, Assert, Query, XML),
-    integer(N),
-    list_si(Assert),
-    list_si(Query),
-    partial_string(XML),
-    number_chars(N, NChars),
-    atom_chars(NAtom, NChars),
-    atom_concat(prolog2ruleml_, NAtom, Prolog2RuleML),
-    atom_concat(ruleml2prolog_, NAtom, RuleML2Prolog),
-    atom_concat(test_, NAtom, TestN),
-    strip_indentation(XML, XML1),
-    Term = [(Prolog2RuleML :- parse_ruleml(Assert, Query, XML0),
-                              XML0 = XML1),
-            (RuleML2Prolog :- parse_ruleml(Assert0, Query0, XML),
-                              Assert0 = Assert,
-                              Query0 = Query),
-            (TestN :- write(test(N)), nl, Prolog2RuleML, RuleML2Prolog, !),
-            (TestN :- throw(error(test_failure, TestN)))].
-
-
 until_non_space_or_end([C|Cs], Cs1) :-
     (  C == (' ') ->
        until_non_space_or_end(Cs, Cs1)
@@ -66,6 +44,28 @@ strip_indentation_([C|Cs], Cs0) :-
 strip_indentation_([], []).
 
 
+user:term_expansion(Term0, Term) :-
+    nonvar(Term0),
+    Term0 = test(N, Assert, Query, XML),
+    integer(N),
+    list_si(Assert),
+    list_si(Query),
+    partial_string(XML),
+    number_chars(N, NChars),
+    atom_chars(NAtom, NChars),
+    atom_concat(prolog2ruleml_, NAtom, Prolog2RuleML),
+    atom_concat(ruleml2prolog_, NAtom, RuleML2Prolog),
+    atom_concat(test_, NAtom, TestN),
+    strip_indentation(XML, XML1),
+    Term = [(Prolog2RuleML :- parse_ruleml(Assert, Query, XML0),
+                              XML0 = XML1),
+            (RuleML2Prolog :- parse_ruleml(Assert0, Query0, XML),
+                              Assert0 = Assert,
+                              Query0 = Query),
+            (TestN :- write(test(N)), nl, Prolog2RuleML, RuleML2Prolog, !),
+            (TestN :- throw(error(test_failure, TestN)))].
+
+
 test(1,
      [people('Alex',male),people('Alex',female),people('Siri',female)],
      [],
index bdaacc7809114efe702631f6d2c0b5e5da8b6785..58f8cf375c0196e99fb016203c12c5999b341e10 100644 (file)
@@ -278,7 +278,7 @@ impl<'a> Iterator for HeapPStrIter<'a> {
                     Addr::Con(h) if self.machine_st.heap.atom_at(h) => {
                         if let HeapCellValue::Atom(ref atom, _) = &self.machine_st.heap[h] {
                             if atom.is_char() {
-                                Some(atom.as_str().chars().next().unwrap())
+                                atom.as_str().chars().next()
                             } else {
                                 None
                             }
@@ -400,11 +400,42 @@ pub(super) fn compare_pstr_prefixes<'a>(
             }
         }
 
-        return match (i1.focus(), i2.focus()) {
-            (Addr::EmptyList, Addr::EmptyList) => Some(Ordering::Equal),
-            (Addr::EmptyList, _) => Some(Ordering::Less),
-            (_, Addr::EmptyList) => Some(Ordering::Greater),
-            _ => None,
+        let ordering = if r1.is_none() {
+            mem::swap(&mut r1, &mut r2);
+            Ordering::Less
+        } else {
+            Ordering::Greater
+        };
+
+        let machine_st = i1.machine_st;
+
+        let check_focuses = || {
+            match (i1.focus(), i2.focus()) {
+                (Addr::EmptyList, Addr::EmptyList) => Some(Ordering::Equal),
+                (Addr::EmptyList, _) => Some(Ordering::Less),
+                (_, Addr::EmptyList) => Some(Ordering::Greater),
+                _ => None,
+            }
+        };
+
+        return match r1 {
+            Some(PStrIteratee::PStrSegment(h, n)) => {
+                if let &HeapCellValue::PartialString(ref pstr, _) = &machine_st.heap[h] {
+                    if pstr.as_str_from(n).chars().next().is_some() {
+                        Some(ordering)
+                    } else {
+                        check_focuses()
+                    }
+                } else {
+                    unreachable!()
+                }
+            }
+            Some(PStrIteratee::Char(_)) => {
+                Some(ordering)
+            }
+            None => {
+                check_focuses()
+            }
         };
     }
 }