Skip to content

Commit 95e1161

Browse files
committed
SMT2 parser: add 'as const'
This is an extension understood by Z3 and CVC4, which is the equivalent of array_of_exprt.
1 parent d7b9787 commit 95e1161

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CORE
2+
as_const1.smt2
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^unsat$
7+
--
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; an array consisting of all #x10
2+
(declare-const array (Array (_ BitVec 16) (_ BitVec 8)))
3+
(assert (= array ((as const (Array (_ BitVec 16) (_ BitVec 8))) #x10)))
4+
5+
(declare-const index (_ BitVec 16))
6+
(assert (not (= #x10 (select array index))))
7+
8+
(check-sat)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
as_const2.smt2
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^sat$
7+
^\(\(sample \(_ bv16 8\)\)\)$
8+
--
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
; an array consisting of all #x10
2+
(declare-const array (Array (_ BitVec 16) (_ BitVec 8)))
3+
(assert (= array ((as const (Array (_ BitVec 16) (_ BitVec 8))) #x10)))
4+
5+
(declare-const sample (_ BitVec 8))
6+
(assert (= sample (select array #x0000)))
7+
8+
(check-sat)
9+
(get-value (sample))

src/solvers/smt2/smt2_parser.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,40 @@ exprt smt2_parsert::function_application()
690690
<< smt2_tokenizer.get_buffer() << '\'';
691691
}
692692
}
693+
else if(smt2_tokenizer.get_buffer() == "as")
694+
{
695+
// This is an extension understood by Z3 and CVC4.
696+
if(
697+
smt2_tokenizer.peek() == smt2_tokenizert::SYMBOL &&
698+
smt2_tokenizer.get_buffer() == "const")
699+
{
700+
next_token(); // eat the "const"
701+
auto sort = this->sort();
702+
703+
if(sort.id() != ID_array)
704+
{
705+
throw error()
706+
<< "unexpected 'as const' expression expects array type";
707+
}
708+
709+
const auto &array_sort = to_array_type(sort);
710+
711+
if(smt2_tokenizer.next_token() != smt2_tokenizert::CLOSE)
712+
throw error() << "expecting ')' after sort in 'as const'";
713+
714+
auto value = expression();
715+
716+
if(value.type() != array_sort.subtype())
717+
throw error() << "unexpected 'as const' with wrong element type";
718+
719+
if(smt2_tokenizer.next_token() != smt2_tokenizert::CLOSE)
720+
throw error() << "expecting ')' at the end of 'as const'";
721+
722+
return array_of_exprt(value, array_sort);
723+
}
724+
else
725+
throw error() << "unexpected 'as' expression";
726+
}
693727
else
694728
{
695729
// just double parentheses

0 commit comments

Comments
 (0)