• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
      • Std/lists
      • Std/alists
      • Obags
      • Std/util
      • Std/strings
        • Pretty-printing
        • Printtree
        • Base64
        • Charset-p
        • Strtok!
        • Cases
        • Concatenation
        • Html-encoding
        • Character-kinds
        • Substrings
        • Strtok
        • Equivalences
        • Url-encoding
        • Lines
        • Ordering
          • Charlistnat<
          • Istr<
            • Ichar<
            • Icharlist<
            • Strnat<
            • Istrsort
          • Numbers
          • Pad-trim
          • Coercion
          • Std/strings-extensions
          • Std/strings/digit-to-char
          • Substitution
          • Symbols
        • Std/io
        • Std/osets
        • Std/system
        • Std/basic
        • Std/typed-lists
        • Std/bitsets
        • Std/testing
        • Std/typed-alists
        • Std/stobjs
        • Std-extensions
      • Proof-automation
      • Macro-libraries
      • ACL2
      • Interfacing-tools
      • Hardware-verification
      • Software-verification
      • Testing-utilities
      • Math
    • Ordering

    Istr<

    Case-insensitive string less-than test.

    (icharlist< x y) determines whether the string x preceeds y in alphabetical order without regards to case. The characters are compared with ichar< and shorter strings are considered smaller than longer strings.

    Logically, this is identical to:

    (icharlist< (explode x) (explode y))

    But we use a more efficient implementation which avoids coercing the strings into lists.

    NOTE: for reasoning, we leave this function enabled and prefer to work with icharlist< of the explodes as our normal form.

    Definitions and Theorems

    Function: istr<-aux

    (defun
     istr<-aux (x y n xl yl)
     (declare (type string x)
              (type string y)
              (type integer n)
              (type integer xl)
              (type integer yl)
              (xargs :guard (and (stringp x)
                                 (stringp y)
                                 (natp n)
                                 (<= n (length x))
                                 (<= n (length y))
                                 (equal xl (length x))
                                 (equal yl (length y)))))
     (mbe
      :logic (cond ((zp (- (nfix yl) (nfix n))) nil)
                   ((zp (- (nfix xl) (nfix n))) t)
                   ((ichar< (char x n) (char y n)) t)
                   ((ichar< (char y n) (char x n)) nil)
                   (t (istr<-aux x y (+ (nfix n) 1) xl yl)))
      :exec
      (cond
       ((= (the integer n) (the integer yl))
        nil)
       ((= (the integer n) (the integer xl)) t)
       (t
        (let* ((xc (the (unsigned-byte 8)
                        (char-code (the character
                                        (char (the string x)
                                              (the integer n))))))
               (yc (the (unsigned-byte 8)
                        (char-code (the character
                                        (char (the string y)
                                              (the integer n))))))
               (xc-fix (if (and (<= (big-a) (the (unsigned-byte 8) xc))
                                (<= (the (unsigned-byte 8) xc) (big-z)))
                           (the (unsigned-byte 8)
                                (+ (the (unsigned-byte 8) xc) 32))
                           (the (unsigned-byte 8) xc)))
               (yc-fix (if (and (<= (big-a) (the (unsigned-byte 8) yc))
                                (<= (the (unsigned-byte 8) yc) (big-z)))
                           (the (unsigned-byte 8)
                                (+ (the (unsigned-byte 8) yc) 32))
                           (the (unsigned-byte 8) yc))))
              (cond ((< (the (unsigned-byte 8) xc-fix)
                        (the (unsigned-byte 8) yc-fix))
                     t)
                    ((< (the (unsigned-byte 8) yc-fix)
                        (the (unsigned-byte 8) xc-fix))
                     nil)
                    (t (istr<-aux (the string x)
                                  (the string y)
                                  (the integer (+ (the integer n) 1))
                                  (the integer xl)
                                  (the integer yl)))))))))

    Function: istr<$inline

    (defun
         istr<$inline (x y)
         (declare (type string x)
                  (type string y))
         (mbe :logic (icharlist< (explode x) (explode y))
              :exec (istr<-aux (the string x)
                               (the string y)
                               (the integer 0)
                               (the integer (length (the string x)))
                               (the integer (length (the string y))))))

    Theorem: istr<-aux-correct

    (defthm istr<-aux-correct
            (implies (and (stringp x)
                          (stringp y)
                          (natp n)
                          (<= n (length x))
                          (<= n (length y))
                          (equal xl (length x))
                          (equal yl (length y)))
                     (equal (istr<-aux x y n xl yl)
                            (icharlist< (nthcdr n (coerce x 'list))
                                        (nthcdr n (coerce y 'list))))))

    Theorem: istreqv-implies-equal-istr<-1

    (defthm istreqv-implies-equal-istr<-1
            (implies (istreqv x x-equiv)
                     (equal (istr< x y) (istr< x-equiv y)))
            :rule-classes (:congruence))

    Theorem: istreqv-implies-equal-istr<-2

    (defthm istreqv-implies-equal-istr<-2
            (implies (istreqv y y-equiv)
                     (equal (istr< x y) (istr< x y-equiv)))
            :rule-classes (:congruence))