mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 11:25:51 +00:00
use ADT for strings
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a7e2fb31e3
commit
3c50508762
10 changed files with 421 additions and 201 deletions
|
@ -22,6 +22,145 @@ Revision History:
|
|||
#include "ast_pp.h"
|
||||
#include <sstream>
|
||||
|
||||
zstring::zstring(encoding enc): m_encoding(enc) {}
|
||||
|
||||
zstring::zstring(char const* s, encoding enc): m_encoding(enc) {
|
||||
// TBD: epply decoding
|
||||
while (*s) {
|
||||
m_buffer.push_back(*s);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
zstring::zstring(zstring const& other) {
|
||||
m_buffer = other.m_buffer;
|
||||
m_encoding = other.m_encoding;
|
||||
}
|
||||
|
||||
zstring::zstring(unsigned num_bits, bool const* ch) {
|
||||
SASSERT(num_bits == 8 || num_bits == 16);
|
||||
m_encoding = (num_bits == 8)?ascii:unicode;
|
||||
unsigned n = 0;
|
||||
for (unsigned i = 0; i < num_bits; ++i) {
|
||||
n |= (((unsigned)ch[i]) << num_bits);
|
||||
}
|
||||
m_buffer.push_back(n);
|
||||
}
|
||||
|
||||
zstring::zstring(unsigned ch, encoding enc) {
|
||||
m_encoding = enc;
|
||||
m_buffer.push_back(ch & ((enc == ascii)?0x000000FF:0x0000FFFF));
|
||||
}
|
||||
|
||||
zstring& zstring::operator=(zstring const& other) {
|
||||
m_encoding = other.m_encoding;
|
||||
m_buffer.reset();
|
||||
m_buffer.append(other.m_buffer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
zstring zstring::replace(zstring const& src, zstring const& dst) const {
|
||||
zstring result(m_encoding);
|
||||
if (length() < src.length()) {
|
||||
return zstring(*this);
|
||||
}
|
||||
bool found = false;
|
||||
for (unsigned i = 0; i <= length() - src.length(); ++i) {
|
||||
bool eq = !found;
|
||||
for (unsigned j = 0; eq && j < src.length(); ++j) {
|
||||
eq = m_buffer[i+j] == src[j];
|
||||
}
|
||||
if (eq) {
|
||||
result.m_buffer.append(dst.m_buffer);
|
||||
found = true;
|
||||
}
|
||||
else {
|
||||
result.m_buffer.push_back(m_buffer[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string zstring::encode() const {
|
||||
// TBD apply encodings.
|
||||
SASSERT(m_encoding == ascii);
|
||||
std::ostringstream strm;
|
||||
for (unsigned i = 0; i < m_buffer.size(); ++i) {
|
||||
strm << (char)(m_buffer[i]);
|
||||
}
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
bool zstring::suffixof(zstring const& other) const {
|
||||
if (length() > other.length()) return false;
|
||||
bool suffix = true;
|
||||
for (unsigned i = 0; suffix && i < length(); ++i) {
|
||||
suffix = m_buffer[length()-i-1] == other[other.length()-i-1];
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
bool zstring::prefixof(zstring const& other) const {
|
||||
if (length() > other.length()) return false;
|
||||
bool prefix = true;
|
||||
for (unsigned i = 0; prefix && i < length(); ++i) {
|
||||
prefix = m_buffer[i] == other[i];
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
bool zstring::contains(zstring const& other) const {
|
||||
if (other.length() > length()) return false;
|
||||
unsigned last = length() - other.length();
|
||||
bool cont = false;
|
||||
for (unsigned i = 0; !cont && i <= last; ++i) {
|
||||
cont = true;
|
||||
for (unsigned j = 0; cont && j < other.length(); ++j) {
|
||||
cont = other[j] == m_buffer[j+i];
|
||||
}
|
||||
}
|
||||
return cont;
|
||||
}
|
||||
|
||||
int zstring::indexof(zstring const& other, int offset) const {
|
||||
SASSERT(offset >= 0);
|
||||
if (offset == length()) return -1;
|
||||
if (other.length() + offset > length()) return -1;
|
||||
unsigned last = length() - other.length();
|
||||
for (unsigned i = static_cast<unsigned>(offset); i <= last; ++i) {
|
||||
bool prefix = true;
|
||||
for (unsigned j = 0; prefix && j < other.length(); ++j) {
|
||||
prefix = m_buffer[i + j] == other[j];
|
||||
}
|
||||
if (prefix) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
zstring zstring::extract(int offset, int len) const {
|
||||
zstring result(m_encoding);
|
||||
SASSERT(0 <= offset && 0 <= len);
|
||||
int last = std::min(offset+len, static_cast<int>(length()));
|
||||
for (int i = offset; i < last; ++i) {
|
||||
result.m_buffer.push_back(m_buffer[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
zstring zstring::operator+(zstring const& other) const {
|
||||
SASSERT(m_encoding == other.m_encoding);
|
||||
zstring result(*this);
|
||||
result.m_buffer.append(other.m_buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostream& zstring::operator<<(std::ostream& out) const {
|
||||
return out << encode();
|
||||
}
|
||||
|
||||
|
||||
seq_decl_plugin::seq_decl_plugin(): m_init(false),
|
||||
m_stringc_sym("String"),
|
||||
m_string(0),
|
||||
|
@ -452,6 +591,14 @@ app* seq_decl_plugin::mk_string(symbol const& s) {
|
|||
return m_manager->mk_const(f);
|
||||
}
|
||||
|
||||
app* seq_decl_plugin::mk_string(zstring const& s) {
|
||||
symbol sym(s.encode().c_str());
|
||||
parameter param(sym);
|
||||
func_decl* f = m_manager->mk_const_decl(m_stringc_sym, m_string,
|
||||
func_decl_info(m_family_id, OP_STRING_CONST, 1, ¶m));
|
||||
return m_manager->mk_const(f);
|
||||
}
|
||||
|
||||
bool seq_decl_plugin::is_value(app* e) const {
|
||||
return is_app_of(e, m_family_id, OP_STRING_CONST);
|
||||
}
|
||||
|
@ -463,6 +610,18 @@ app* seq_util::mk_skolem(symbol const& name, unsigned n, expr* const* args, sort
|
|||
return m.mk_app(f, n, args);
|
||||
}
|
||||
|
||||
app* seq_util::str::mk_string(zstring const& s) { return u.seq.mk_string(s); }
|
||||
|
||||
bool seq_util::str::is_string(expr const* n, zstring& s) const {
|
||||
if (is_string(n)) {
|
||||
s = zstring(to_app(n)->get_decl()->get_parameter(0).get_symbol().bare_str());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void seq_util::str::get_concat(expr* e, ptr_vector<expr>& es) const {
|
||||
expr* e1, *e2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue