Efficient way to take leading characters from a string.
(firstn-chars n x) is logically equal to:
(take (min n (length x)) (explode x))
But it is implemented more efficiently, via char.
Function:
(defun firstn-chars-aux (x n acc) (declare (xargs :guard (and (stringp x) (natp n) (< n (length x)))) (type string x) (type (integer 0 *) n)) (if (zp n) (cons (char x 0) acc) (firstn-chars-aux x (the (integer 0 *) (- n 1)) (cons (char x n) acc))))
Function:
(defun firstn-chars (n x) (declare (xargs :guard (and (stringp x) (natp n))) (type string x) (type (integer 0 *) n)) (mbe :logic (take (min (nfix n) (len (explode x))) (explode x)) :exec (let ((n (min n (length x)))) (if (zp n) nil (firstn-chars-aux x (the (integer 0 *) (- n 1)) nil)))))
Theorem:
(defthm firstn-chars-aux-removal (implies (and (stringp x) (natp n) (< n (length x))) (equal (firstn-chars-aux x n acc) (append (take (+ n 1) (coerce x 'list)) acc))))
Theorem:
(defthm character-listp-of-firstn-chars (character-listp (firstn-chars n x)))
Theorem:
(defthm streqv-implies-equal-firstn-chars-2 (implies (streqv x x-equiv) (equal (firstn-chars n x) (firstn-chars n x-equiv))) :rule-classes (:congruence))
Theorem:
(defthm istreqv-implies-icharlisteqv-firstn-chars-2 (implies (istreqv x x-equiv) (icharlisteqv (firstn-chars n x) (firstn-chars n x-equiv))) :rule-classes (:congruence))