(declare-const a String) (declare-const b String) (assert (= (str.++ b a) (str.++ "abc" b))) (check-sat) (get-model)
To represent non-ASCII characters Z3 treats the sequence \xHH where HH are two hexa-decimal numerals (using one of the characters, 0-9, a-f, A-F) as an encoding of an 8 bit character. Furthermore, the following escape sequences correspond to their ASCII escape encodings.
\a | \b | \f | \n | \r | \t | \v |
(define-const a String "\x0a") (define-const b String " ") (define-const c String "\n") (simplify (= a b)) (simplify (= a c)) (simplify (str.++ a b c))
Operation | Brief description |
(str.++ a b c) | String concatenation of one or more strings |
(str.len s) | String length. Returns an integer. |
(str.substr s offset length) | Retrieves substring of s at offset |
(str.indexof s sub) | Retrieves first position of sub in s, -1 if there are no occurrences |
(str.indexof s sub offset) | Retrieves first position of sub at or after offset in s, -1 if there are no occurrences |
(str.at s offset) | Substring of length 1 at offset in s. |
(str.contains s sub) | Does s contain the substring sub? |
(str.prefixof pre s) | Is pre a prefix of s? |
(str.suffixof suf s) | Is suf a suffix of s? |
(str.replace s src dst) | Replace the first occurrence of src by dst in s. |
(str.to.int s) | Retrieve integer encoded by string s (ground rewriting only). |
(int.to.str i) | Retrieve string encoding of integer i (ground rewriting only). |
Note that (str.indexof s offset) is shorthand for (str.indexof s offset 0).
Some operations have under-specified behavior on certain arguments. Namely, (str.at s i) is unconstrained for indices that are either negative or beyond (- (str.len s) 1). Furthermore (str.substr s offset length) is under-specified when the offset is outside the range of positions in s or length is negative or offset+length exceeds the length of s.(simplify (str.++ (str.at "abc" 1) (str.at "abc" 0))) (simplify (str.indexof "abcabc" "a")) (simplify (str.indexof "abcabc" "a" 1)) (simplify (str.substr "xxabcyy" 2 3))A string cannot overlap with two different characters. load in editor
(declare-const a String) (assert (= (str.++ a "b") (str.++ "a" a))) (check-sat)Strings a, b, c can have a non-trivial overlap. load in editor
(declare-const a String) (declare-const b String) (declare-const c String) (assert (= (str.++ a b) "abcd")) (assert (= (str.++ b c) "cdef")) (assert (not (= b ""))) (check-sat)There is a solution to a of length at most 2. load in editor
(declare-const a String) (declare-const b String) (assert (= (str.++ "abc" a) (str.++ b "cef"))) (assert (<= (str.len a) 2)) (check-sat)There is a solution to a that is not a sequence of "a"'s. load in editor
(declare-const a String) (declare-const b String) (declare-const c String) (assert (= (str.++ a "ab" b) (str.++ b "ba" c))) (assert (= c (str.++ a b))) (assert (not (= (str.++ a "a") (str.++ "a" a)))) (check-sat) (get-model)Contains is transitive. load in editor
(declare-const a String) (declare-const b String) (declare-const c String) (assert (str.contains a b)) (assert (str.contains b c)) (assert (not (str.contains a c))) (check-sat)But containment is not a linear order. load in editor
(declare-const a String) (declare-const b String) (declare-const c String) (assert (str.contains a b)) (assert (str.contains a c)) (assert (not (str.contains b c))) (assert (not (str.contains c b))) (check-sat) (get-model)Any string is equal to the prefix and suffix that add up to a its length. load in editor
(declare-const a String) (declare-const b String) (declare-const c String) (assert (str.prefixof b a)) (assert (str.suffixof c a)) (assert (= (str.len a) (+ (str.len b) (str.len c)))) (assert (not (= a (str.++ b c)))) (check-sat)
Operation | Brief description |
(seq.unit elem) | Sequence with a single element elem. |
(as seq.empty (Seq Int)) | The empty sequence of integers. |
(seq.++ a b c) | Concatenation of one or more sequences. |
(seq.len s) | Sequence length. Returns an integer. |
(seq.extract s offset length) | Retrieves sub-sequence of s at offset |
(seq.indexof s sub) | Retrieves first position of sub in s, -1 if there are no occurrences |
(seq.indexof s sub offset) | Retrieves first position of sub at or after offset in s, -1 if there are no occurrences |
(seq.at s offset) | Sub-sequence of length 1 at offset in s. |
(seq.contains s sub) | Does s contain the sub-sequence sub? |
(seq.prefixof pre s) | Is pre a prefix of s? |
(seq.suffixof suf s) | Is suf a suffix of s? |
(seq.replace s src dst) | Replace the first occurrence of src by dst in s. |
(declare-const s (Seq Int)) (declare-const t (Seq Int)) (declare-const j Int) (declare-const b Int) (assert (<= 10 (seq.len s))) (assert (<= 8 j)) (assert (< j (seq.len s))) (assert (= t (seq.++ (seq.extract s 0 j) (seq.unit b) (seq.extract s (+ j 1) (- (seq.len s) j 1))))) (push) (assert (not (= (seq.unit b) (seq.at t j)))) (check-sat) (pop) (push) (assert (not (= (seq.len s) (seq.len t)))) (check-sat) (pop) (push) (assert (not (= (seq.at s 8) (seq.at t 8)))) (assert (not (= (seq.at s 9) (seq.at t 9)))) (check-sat) (pop)
Operation | Brief description |
(str.to.re s) | Convert string to regular expression accepting s. |
(str.in.re s r) | Determine if s is in the language generated by r. |
re.allchar | The regular expression accepting every string. |
re.nostr | The regular expression rejecting every string. |
(re.range ch1 ch2) | The range of characters between ch1 and ch2. |
(re.++ r1 r2 r3) | Concatenation of regular expressions. |
(re.* r) | Kleene star. |
(re.+ r) | Kleene plus. |
(re.opt r) | Zero or one use of r. |
((_ re.loop lo hi) r) | from lo to hi number of repetitions of r. |
(re.union r1 r2) | The union of regular languages. |
(re.inter r1 r2) | The intersection of regular languages. |
(seq.to.re s) | Convert sequenceto regular expression accepting s. |
(seq.in.re s r) | Determine if sequence s is in the language generated by r. |
(as re.all R) | The regular expression of sort R accepting every sequence. |
(as re.empty R) | The regular expression of sort R rejecting every sequence. |
The re.range operator expects two strings each encoding a single character. For example (str.range "a" "\xff") is a valid range of characters, while (str.range "aa" "") is not associated with any specified range.
For added compatibility with CVC4's format, Z3 also accepts expressions of the form (re.loop r lo hi). Z3 understands only the meaning of these terms when lo, hi are integer numerals.
(declare-const a String) (push) (set-info :status sat) (assert (str.in.re a ((_ re.loop 1 3) (str.to.re "ab")))) (assert (= (str.len a) 6)) (check-sat) (get-model) (pop) (push) (set-info :status unsat) (assert (str.in.re a ((_ re.loop 1 3) (str.to.re "ab")))) (assert (> (str.len a) 6)) (check-sat) (pop)