SMT-LIB indicates that abstract values can appear in terms as arguments to `get-value`. This is not currently the case, as pointed out by #6908.
This updates our parser so that bindings are added to the symbol table for all uninterpreted constants in the model whenever we parse a `get-value` term.
Fixes #6908.
d_symman->pushScope(isUserContext);
}
+void Parser::pushGetValueScope()
+{
+ pushScope();
+ // we must bind all relevant uninterpreted constants, which coincide with
+ // the set of uninterpreted constants that are printed in the definition
+ // of a model.
+ std::vector<api::Sort> declareSorts = d_symman->getModelDeclareSorts();
+ Trace("parser") << "Push get value scope, with " << declareSorts.size()
+ << " declared sorts" << std::endl;
+ for (const api::Sort& s : declareSorts)
+ {
+ std::vector<api::Term> elements = d_solver->getModelDomainElements(s);
+ for (const api::Term& e : elements)
+ {
+ // Uninterpreted constants are abstract values, which by SMT-LIB are
+ // required to be annotated with their type, e.g. (as @uc_Foo_0 Foo).
+ // Thus, the element is not printed simply as its name.
+ std::string en = e.toString();
+ size_t index = en.find("(as ");
+ if (index == 0)
+ {
+ index = en.find(" ", 4);
+ en = en.substr(4, index - 4);
+ }
+ Trace("parser") << "Get value scope : " << en << " -> " << e << std::endl;
+ defineVar(en, e);
+ }
+ }
+}
+
void Parser::popScope()
{
d_symman->popScope();
*/
void pushScope(bool isUserContext = false);
+ /** Push scope for get-value
+ *
+ * This pushes a scope by a call to pushScope that binds all relevant bindings
+ * required for parsing the SMT-LIB command `get-value`. This includes
+ * all uninterpreted constant values in user-defined uninterpreted sorts.
+ */
+ void pushGetValueScope();
+
void popScope();
virtual void reset();
| DECLARE_DATATYPE_TOK datatypeDefCommand[false, cmd]
| DECLARE_DATATYPES_TOK datatypesDefCommand[false, cmd]
| /* value query */
- GET_VALUE_TOK { PARSER_STATE->checkThatLogicIsSet(); }
+ GET_VALUE_TOK
+ {
+ PARSER_STATE->checkThatLogicIsSet();
+ // bind all symbols specific to the model, e.g. uninterpreted constant
+ // values
+ PARSER_STATE->pushGetValueScope();
+ }
( LPAREN_TOK termList[terms,expr] RPAREN_TOK
{ cmd->reset(new GetValueCommand(terms)); }
| ~LPAREN_TOK
"parentheses?");
}
)
+ { PARSER_STATE->popScope(); }
| /* get-assignment */
GET_ASSIGNMENT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
{ cmd->reset(new GetAssignmentCommand()); }
regress0/parser/force_logic_set_logic.smt2
regress0/parser/force_logic_success.smt2
regress0/parser/issue5163.smt2
+ regress0/parser/issue6908-get-value-uc.smt2
regress0/parser/issue7274.smt2
regress0/parser/linear_arithmetic_err1.smt2
regress0/parser/linear_arithmetic_err2.smt2
--- /dev/null
+; COMMAND-LINE: --produce-models
+; EXPECT: sat
+; EXPECT: (((f (as @uc_Foo_0 Foo)) 3))
+(set-logic ALL)
+(set-option :produce-models true)
+(declare-sort Foo 0)
+(declare-fun f (Foo) Int)
+(assert (exists ((x Foo)) (= (f x) 3)))
+(check-sat)
+(get-value ((f @uc_Foo_0)))