diff --git a/regression/smt2_solver/arrays/as_const1.desc b/regression/smt2_solver/arrays/as_const1.desc new file mode 100644 index 00000000000..03d592ad6ca --- /dev/null +++ b/regression/smt2_solver/arrays/as_const1.desc @@ -0,0 +1,7 @@ +CORE +as_const1.smt2 + +^EXIT=0$ +^SIGNAL=0$ +^unsat$ +-- diff --git a/regression/smt2_solver/arrays/as_const1.smt2 b/regression/smt2_solver/arrays/as_const1.smt2 new file mode 100644 index 00000000000..55e47fd2b27 --- /dev/null +++ b/regression/smt2_solver/arrays/as_const1.smt2 @@ -0,0 +1,8 @@ +; an array consisting of all #x10 +(declare-const array (Array (_ BitVec 16) (_ BitVec 8))) +(assert (= array ((as const (Array (_ BitVec 16) (_ BitVec 8))) #x10))) + +(declare-const index (_ BitVec 16)) +(assert (not (= #x10 (select array index)))) + +(check-sat) diff --git a/regression/smt2_solver/arrays/as_const2.desc b/regression/smt2_solver/arrays/as_const2.desc new file mode 100644 index 00000000000..d3b33caa087 --- /dev/null +++ b/regression/smt2_solver/arrays/as_const2.desc @@ -0,0 +1,8 @@ +CORE +as_const2.smt2 + +^EXIT=0$ +^SIGNAL=0$ +^sat$ +^\(\(sample \(_ bv16 8\)\)\)$ +-- diff --git a/regression/smt2_solver/arrays/as_const2.smt2 b/regression/smt2_solver/arrays/as_const2.smt2 new file mode 100644 index 00000000000..c44c9924d29 --- /dev/null +++ b/regression/smt2_solver/arrays/as_const2.smt2 @@ -0,0 +1,9 @@ +; an array consisting of all #x10 +(declare-const array (Array (_ BitVec 16) (_ BitVec 8))) +(assert (= array ((as const (Array (_ BitVec 16) (_ BitVec 8))) #x10))) + +(declare-const sample (_ BitVec 8)) +(assert (= sample (select array #x0000))) + +(check-sat) +(get-value (sample)) diff --git a/src/solvers/smt2/smt2_parser.cpp b/src/solvers/smt2/smt2_parser.cpp index 7dd3e42b4f3..0e9c9d590d8 100644 --- a/src/solvers/smt2/smt2_parser.cpp +++ b/src/solvers/smt2/smt2_parser.cpp @@ -690,6 +690,40 @@ exprt smt2_parsert::function_application() << smt2_tokenizer.get_buffer() << '\''; } } + else if(smt2_tokenizer.get_buffer() == "as") + { + // This is an extension understood by Z3 and CVC4. + if( + smt2_tokenizer.peek() == smt2_tokenizert::SYMBOL && + smt2_tokenizer.get_buffer() == "const") + { + next_token(); // eat the "const" + auto sort = this->sort(); + + if(sort.id() != ID_array) + { + throw error() + << "unexpected 'as const' expression expects array type"; + } + + const auto &array_sort = to_array_type(sort); + + if(smt2_tokenizer.next_token() != smt2_tokenizert::CLOSE) + throw error() << "expecting ')' after sort in 'as const'"; + + auto value = expression(); + + if(value.type() != array_sort.subtype()) + throw error() << "unexpected 'as const' with wrong element type"; + + if(smt2_tokenizer.next_token() != smt2_tokenizert::CLOSE) + throw error() << "expecting ')' at the end of 'as const'"; + + return array_of_exprt(value, array_sort); + } + else + throw error() << "unexpected 'as' expression"; + } else { // just double parentheses