other
(in-package "STR")
other
(include-book "cat")
other
(include-book "strprefixp")
other
(local (include-book "arithmetic"))
other
(defsection strsubst-aux :parents (strsubst) :short "Fast implementation of @(see strsubst)." (defund strsubst-aux (old new x n xl oldl acc) (declare (type string old new x) (type (integer 0 *) n xl oldl) (xargs :guard (and (stringp old) (stringp new) (stringp x) (natp n) (natp xl) (posp oldl) (= oldl (length old)) (= xl (length x))) :measure (nfix (- (nfix xl) (nfix n))))) (cond ((mbe :logic (zp oldl) :exec nil) acc) ((mbe :logic (zp (- (nfix xl) (nfix n))) :exec (>= n xl)) acc) ((strprefixp-impl old x 0 n oldl xl) (let ((acc (revappend-chars new acc))) (strsubst-aux old new x (the (integer 0 *) (+ oldl (the (integer 0 *) (lnfix n)))) xl oldl acc))) (t (let ((acc (cons (char x n) acc))) (strsubst-aux old new x (the (integer 0 *) (+ 1 (the (integer 0 *) (lnfix n)))) xl oldl acc))))) (local (in-theory (enable strsubst-aux))) (defthm character-listp-of-strsubst-aux (implies (and (stringp old) (stringp new) (stringp x) (natp n) (posp oldl) (= oldl (length old)) (= xl (length x)) (character-listp acc)) (character-listp (strsubst-aux old new x n xl oldl acc)))))
other
(defsection strsubst :parents (substitution substitute) :short "Replace substrings throughout a string." :long "<p>@(call strsubst) replaces each occurrence of @('old') with @('new') throughout @('x'). Each argument is a string, and a new string is returned. The replacement is done globally and non-recursively.</p> <p>Examples:</p> @({ (strsubst "World" "Star" "Hello, World!") --> "Hello, Star!" (strsubst "oo" "aa" "xoooyoo") --> "xaaoyaa" }) <p>ACL2 has a built in @(see substitute) function, but it only works on individual characters, whereas @('strsubst') works on substrings.</p>" (defund strsubst (old new x) (declare (xargs :guard (and (stringp old) (stringp new) (stringp x)))) (let ((oldl (mbe :logic (len (explode old)) :exec (length old))) (xl (mbe :logic (len (explode x)) :exec (length x)))) (if (zp oldl) (mbe :logic (str-fix x) :exec x) (rchars-to-string (strsubst-aux old new x 0 xl oldl nil))))) (local (in-theory (enable strsubst))) (defthm stringp-of-strsubst (stringp (strsubst old new x)) :rule-classes :type-prescription))
other
(defsection strsubst-list :parents (substitution) :short "Carry out a @(see strsubst) replacement throughout a list of strings." :long "<p>@(call strsubst-list) replaces every occurrence of @('old') with @('new') throughout @('x'). Here, @('old') and @('new') are strings, but @('x') is a list of strings. A new list of strings is returned.</p> <p>Example:</p> @({ (strsubst-list "Sun" "Moon" '("Sun Roof" "Hello Sun" "Sunny Sunshades")) --> ("Moon Roof" "Hello Moon" "Moonny Moonshades") })" (defund strsubst-list (old new x) (declare (xargs :guard (and (stringp old) (stringp new) (string-listp x)))) (if (atom x) nil (cons (strsubst old new (car x)) (strsubst-list old new (cdr x))))) (local (in-theory (enable strsubst-list))) (defthm strsubst-list-when-atom (implies (atom x) (equal (strsubst-list old new x) nil))) (defthm strsubst-list-of-cons (equal (strsubst-list old new (cons a x)) (cons (strsubst old new a) (strsubst-list old new x)))) (defthm string-listp-of-strsubst-list (string-listp (strsubst-list old new x))) (local (defthm l0 (equal (strsubst-list old new (list-fix x)) (strsubst-list old new x)))) (defcong list-equiv equal (strsubst-list old new x) 3 :hints (("Goal" :in-theory (disable l0) :use ((:instance l0 (x x)) (:instance l0 (x x-equiv)))))) (defthm strsubst-list-of-append (equal (strsubst-list old new (append x y)) (append (strsubst-list old new x) (strsubst-list old new y)))) (defthm strsubst-list-of-revappend (equal (strsubst-list old new (revappend x y)) (revappend (strsubst-list old new x) (strsubst-list old new y)))) (defthm strsubst-list-of-rev (equal (strsubst-list old new (rev x)) (rev (strsubst-list old new x)))))