summaryrefslogtreecommitdiff
path: root/src/parser/smt2/smt2.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/smt2/smt2.h')
-rw-r--r--src/parser/smt2/smt2.h332
1 files changed, 249 insertions, 83 deletions
diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h
index 171642c7e..178634693 100644
--- a/src/parser/smt2/smt2.h
+++ b/src/parser/smt2/smt2.h
@@ -16,8 +16,8 @@
#include "cvc4parser_private.h"
-#ifndef __CVC4__PARSER__SMT2_H
-#define __CVC4__PARSER__SMT2_H
+#ifndef CVC4__PARSER__SMT2_H
+#define CVC4__PARSER__SMT2_H
#include <sstream>
#include <stack>
@@ -25,8 +25,10 @@
#include <unordered_map>
#include <utility>
+#include "api/cvc4cpp.h"
#include "parser/parser.h"
-#include "parser/smt1/smt1.h"
+#include "parser/smt2/parse_op.h"
+#include "smt/command.h"
#include "theory/logic_info.h"
#include "util/abstract_value.h"
@@ -40,32 +42,42 @@ class Solver;
namespace parser {
-class Smt2 : public Parser {
+class Smt2 : public Parser
+{
friend class ParserBuilder;
-public:
- enum Theory
- {
- THEORY_ARRAYS,
- THEORY_BITVECTORS,
- THEORY_CORE,
- THEORY_DATATYPES,
- THEORY_INTS,
- THEORY_REALS,
- THEORY_TRANSCENDENTALS,
- THEORY_REALS_INTS,
- THEORY_QUANTIFIERS,
- THEORY_SETS,
- THEORY_STRINGS,
- THEORY_UF,
- THEORY_FP,
- THEORY_SEP
- };
-
-private:
+ public:
+ enum Theory
+ {
+ THEORY_ARRAYS,
+ THEORY_BITVECTORS,
+ THEORY_CORE,
+ THEORY_DATATYPES,
+ THEORY_INTS,
+ THEORY_REALS,
+ THEORY_TRANSCENDENTALS,
+ THEORY_REALS_INTS,
+ THEORY_QUANTIFIERS,
+ THEORY_SETS,
+ THEORY_STRINGS,
+ THEORY_UF,
+ THEORY_FP,
+ THEORY_SEP
+ };
+
+ private:
+ /** Has the logic been set (either by forcing it or a set-logic command)? */
bool d_logicSet;
+ /** Have we seen a set-logic command yet? */
+ bool d_seenSetLogic;
+
LogicInfo d_logic;
std::unordered_map<std::string, Kind> operatorKindMap;
+ /**
+ * Maps indexed symbols to the kind of the operator (e.g. "extract" to
+ * BITVECTOR_EXTRACT_OP).
+ */
+ std::unordered_map<std::string, api::Kind> d_indexedOpKindMap;
std::pair<Expr, std::string> d_lastNamedTerm;
// for sygus
std::vector<Expr> d_sygusVars, d_sygusVarPrimed, d_sygusConstraints,
@@ -87,6 +99,20 @@ private:
void addOperator(Kind k, const std::string& name);
+ /**
+ * Registers an indexed function symbol.
+ *
+ * @param tKind The kind of the term that uses the operator kind (e.g.
+ * BITVECTOR_EXTRACT). NOTE: this is an internal kind for now
+ * because that is what we use to create expressions. Eventually
+ * it will be an api::Kind.
+ * @param opKind The kind of the operator term (e.g. BITVECTOR_EXTRACT_OP)
+ * @param name The name of the symbol (e.g. "extract")
+ */
+ void addIndexedOperator(Kind tKind,
+ api::Kind opKind,
+ const std::string& name);
+
Kind getOperatorKind(const std::string& name) const;
bool isOperatorEnabled(const std::string& name) const;
@@ -96,24 +122,47 @@ private:
bool logicIsSet() override;
/**
- * Returns the expression that name should be interpreted as.
+ * Creates an indexed constant, e.g. (_ +oo 8 24) (positive infinity
+ * as a 32-bit floating-point constant).
+ *
+ * @param name The name of the constant (e.g. "+oo")
+ * @param numerals The parameters for the constant (e.g. [8, 24])
+ * @return The term corresponding to the constant or a parse error if name is
+ * not valid.
+ */
+ api::Term mkIndexedConstant(const std::string& name,
+ const std::vector<uint64_t>& numerals);
+
+ /**
+ * Creates an indexed operator term, e.g. (_ extract 5 0).
+ *
+ * @param name The name of the operator (e.g. "extract")
+ * @param numerals The parameters for the operator (e.g. [5, 0])
+ * @return The operator term corresponding to the indexed operator or a parse
+ * error if the name is not valid.
+ */
+ api::OpTerm mkIndexedOp(const std::string& name,
+ const std::vector<uint64_t>& numerals);
+
+ /**
+ * Returns the expression that name should be interpreted as.
*/
Expr getExpressionForNameAndType(const std::string& name, Type t) override;
/** Make function defined by a define-fun(s)-rec command.
- *
- * fname : the name of the function.
- * sortedVarNames : the list of variable arguments for the function.
- * t : the range type of the function we are defining.
- *
- * This function will create a bind a new function term to name fname.
- * The type of this function is
- * Parser::mkFlatFunctionType(sorts,t,flattenVars),
- * where sorts are the types in the second components of sortedVarNames.
- * As descibed in Parser::mkFlatFunctionType, new bound variables may be
- * added to flattenVars in this function if the function is given a function
- * range type.
- */
+ *
+ * fname : the name of the function.
+ * sortedVarNames : the list of variable arguments for the function.
+ * t : the range type of the function we are defining.
+ *
+ * This function will create a bind a new function term to name fname.
+ * The type of this function is
+ * Parser::mkFlatFunctionType(sorts,t,flattenVars),
+ * where sorts are the types in the second components of sortedVarNames.
+ * As descibed in Parser::mkFlatFunctionType, new bound variables may be
+ * added to flattenVars in this function if the function is given a function
+ * range type.
+ */
Expr mkDefineFunRec(
const std::string& fname,
const std::vector<std::pair<std::string, Type> >& sortedVarNames,
@@ -122,21 +171,21 @@ private:
/** Push scope for define-fun-rec
*
- * This calls Parser::pushScope(bindingLevel) and sets up
- * initial information for reading a body of a function definition
- * in the define-fun-rec and define-funs-rec command.
- * The input parameters func/flattenVars are the result
- * of a call to mkDefineRec above.
- *
- * func : the function whose body we are defining.
- * sortedVarNames : the list of variable arguments for the function.
- * flattenVars : the implicit variables introduced when defining func.
- *
- * This function:
- * (1) Calls Parser::pushScope(bindingLevel).
- * (2) Computes the bound variable list for the quantified formula
- * that defined this definition and stores it in bvs.
- */
+ * This calls Parser::pushScope(bindingLevel) and sets up
+ * initial information for reading a body of a function definition
+ * in the define-fun-rec and define-funs-rec command.
+ * The input parameters func/flattenVars are the result
+ * of a call to mkDefineRec above.
+ *
+ * func : the function whose body we are defining.
+ * sortedVarNames : the list of variable arguments for the function.
+ * flattenVars : the implicit variables introduced when defining func.
+ *
+ * This function:
+ * (1) Calls Parser::pushScope(bindingLevel).
+ * (2) Computes the bound variable list for the quantified formula
+ * that defined this definition and stores it in bvs.
+ */
void pushDefineFunRecScope(
const std::vector<std::pair<std::string, Type> >& sortedVarNames,
Expr func,
@@ -153,15 +202,19 @@ private:
* theory symbols.
*
* @param name the name of the logic (e.g., QF_UF, AUFLIA)
+ * @param fromCommand should be set to true if the request originates from a
+ * set-logic command and false otherwise
+ * @return the command corresponding to setting the logic
*/
- void setLogic(std::string name);
+ Command* setLogic(std::string name, bool fromCommand = true);
/**
* Get the logic.
*/
const LogicInfo& getLogic() const { return d_logic; }
- bool v2_0() const {
+ bool v2_0() const
+ {
return getLanguage() == language::input::LANG_SMTLIB_V2_0;
}
/**
@@ -180,8 +233,10 @@ private:
{
return language::isInputLang_smt2_6(getLanguage(), exact);
}
-
- bool sygus() const { return getLanguage() == language::input::LANG_SYGUS; }
+ /** Are we using a sygus language? */
+ bool sygus() const;
+ /** Are we using the sygus version 1.0 format? */
+ bool sygus_v1() const;
/**
* Returns true if the language that we are parsing (SMT-LIB version >=2.5
@@ -279,6 +334,30 @@ private:
std::vector<std::string>& unresolved_gterm_sym,
std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin );
+ /**
+ * Adds a constructor to sygus datatype dt whose sygus operator is term.
+ *
+ * ntsToUnres contains a mapping from non-terminal symbols to the unresolved
+ * types they correspond to. This map indicates how the argument term should
+ * be interpreted (instances of symbols from the domain of ntsToUnres
+ * correspond to constructor arguments).
+ *
+ * The sygus operator that is actually added to dt corresponds to replacing
+ * each occurrence of non-terminal symbols from the domain of ntsToUnres
+ * with bound variables via purifySygusGTerm, and binding these variables
+ * via a lambda.
+ */
+ void addSygusConstructorTerm(Datatype& dt,
+ Expr term,
+ std::map<Expr, Type>& ntsToUnres) const;
+ /**
+ * This adds constructors to dt for sygus variables in sygusVars whose
+ * type is argument type. This method should be called when the sygus grammar
+ * term (Variable type) is encountered.
+ */
+ void addSygusConstructorVariables(Datatype& dt,
+ std::vector<Expr>& sygusVars,
+ Type type) const;
/**
* Smt2 parser provides its own checkDeclaration, which does the
@@ -298,7 +377,8 @@ private:
return;
}else{
//it is allowable in sygus
- if( sygus() && name[0]=='-' ){
+ if (sygus_v1() && name[0] == '-')
+ {
//do not check anything
return;
}
@@ -319,15 +399,25 @@ private:
// that CVC4 permits as N-ary but the standard requires is binary
if(strictModeEnabled()) {
switch(kind) {
- case kind::BITVECTOR_CONCAT:
case kind::BITVECTOR_AND:
- case kind::BITVECTOR_OR:
- case kind::BITVECTOR_XOR:
case kind::BITVECTOR_MULT:
+ case kind::BITVECTOR_OR:
case kind::BITVECTOR_PLUS:
+ case kind::BITVECTOR_XOR:
+ if (numArgs != 2 && !v2_6())
+ {
+ parseError(
+ "Operator requires exactly 2 arguments in strict SMT-LIB "
+ "compliance mode (for versions <2.6): "
+ + kindToString(kind));
+ }
+ break;
+ case kind::BITVECTOR_CONCAT:
if(numArgs != 2) {
- parseError("Operator requires exact 2 arguments in strict SMT-LIB "
- "compliance mode: " + kindToString(kind));
+ parseError(
+ "Operator requires exactly 2 arguments in strict SMT-LIB "
+ "compliance mode: "
+ + kindToString(kind));
}
break;
default:
@@ -335,6 +425,17 @@ private:
}
}
}
+ /** Set named attribute
+ *
+ * This is called when expression expr is annotated with a name, i.e.
+ * (! expr :named sexpr). It sets up the necessary information to process
+ * this naming, including marking that expr is the last named term.
+ *
+ * We construct an expression symbol whose name is the name of s-expression
+ * which is used later for tracking assertions in unsat cores. This
+ * symbol is returned by this method.
+ */
+ Expr setNamedAttribute(Expr& expr, const SExpr& sexpr);
// Throw a ParserException with msg appended with the current logic.
inline void parseErrorLogic(const std::string& msg)
@@ -343,15 +444,70 @@ private:
parseError(withLogic);
}
-private:
+ //------------------------- processing parse operators
+ /**
+ * Given a parse operator p, apply a type ascription to it. This method is run
+ * when we encounter "(as t type)" and information regarding t has been stored
+ * in p.
+ *
+ * This updates p to take into account the ascription. This may include:
+ * - Converting an (pre-ascribed) array constant specification "const" to
+ * an ascribed array constant specification (as const type) where type is
+ * (Array T1 T2) for some T1, T2.
+ * - Converting a (nullary or non-nullary) parametric datatype constructor to
+ * the specialized constructor for the given type.
+ * - Converting an empty set, universe set, or separation nil reference to
+ * the respective term of the given type.
+ * - If p's expression field is set, then we leave p unchanged, check if
+ * that expression has the given type and throw a parse error otherwise.
+ */
+ void applyTypeAscription(ParseOp& p, Type type);
+ /**
+ * This converts a ParseOp to expression, assuming it is a standalone term.
+ *
+ * In particular:
+ * - If p's expression field is set, then that expression is returned.
+ * - If p's name field is set, then we look up that name in the symbol table
+ * of this class.
+ * In other cases, a parse error is thrown.
+ */
+ Expr parseOpToExpr(ParseOp& p);
+ /**
+ * Apply parse operator to list of arguments, and return the resulting
+ * expression.
+ *
+ * This method involves two phases.
+ * (1) Processing the operator represented by p,
+ * (2) Applying that operator to the set of arguments.
+ *
+ * For (1), this involves determining the kind of the overall expression. We
+ * may be in one the following cases:
+ * - If p's expression field is set, we may choose to prepend it to args, or
+ * otherwise determine the appropriate kind of the overall expression based on
+ * this expression.
+ * - If p's name field is set, then we get the appropriate symbol for that
+ * name, which may involve disambiguating that name if it is overloaded based
+ * on the types of args. We then determine the overall kind of the return
+ * expression based on that symbol.
+ * - p's kind field may be already set.
+ *
+ * For (2), we construct the overall expression, which may involve the
+ * following:
+ * - If p is an array constant specification (as const (Array T1 T2)), then
+ * we return the appropriate array constant based on args[0].
+ * - If p represents a tuple selector, then we infer the appropriate tuple
+ * selector expression based on the type of args[0].
+ * - If the overall kind of the expression is chainable, we may convert it
+ * to a left- or right-associative chain.
+ * - If the overall kind is MINUS and args has size 1, then we return an
+ * application of UMINUS.
+ * - If the overall expression is a partial application, then we process this
+ * as a chain of HO_APPLY terms.
+ */
+ Expr applyParseOp(ParseOp& p, std::vector<Expr>& args);
+ //------------------------- end processing parse operators
+ private:
std::map< CVC4::Expr, CVC4::Type > d_sygus_bound_var_type;
- std::map< CVC4::Expr, std::vector< CVC4::Expr > > d_sygus_let_func_to_vars;
- std::map< CVC4::Expr, CVC4::Expr > d_sygus_let_func_to_body;
- std::map< CVC4::Expr, unsigned > d_sygus_let_func_to_num_input_vars;
- //auxiliary define-fun functions introduced for production rules
- std::vector< CVC4::Expr > d_sygus_defined_funs;
-
- void collectSygusLetArgs( CVC4::Expr e, std::vector< CVC4::Type >& sygusArgs, std::vector< CVC4::Expr >& builtinArgs );
Type processSygusNestedGTerm( int sub_dt_index, std::string& sub_dname, std::vector< CVC4::Datatype >& datatypes,
std::vector< CVC4::Type>& sorts,
@@ -363,16 +519,6 @@ private:
std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr, Type sub_ret );
- void processSygusLetConstructor( std::vector< CVC4::Expr >& let_vars, int index,
- std::vector< CVC4::Datatype >& datatypes,
- std::vector< CVC4::Type>& sorts,
- std::vector< std::vector<CVC4::Expr> >& ops,
- std::vector< std::vector<std::string> >& cnames,
- std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
- std::vector<CVC4::Expr>& sygus_vars,
- std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
- std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr );
-
/** make sygus bound var list
*
* This is used for converting non-builtin sygus operators to lambda
@@ -386,12 +532,32 @@ private:
const std::vector<Type>& ltypes,
std::vector<Expr>& lvars);
+ /** Purify sygus grammar term
+ *
+ * This returns a term where all occurrences of non-terminal symbols (those
+ * in the domain of ntsToUnres) are replaced by fresh variables. For each
+ * variable replaced in this way, we add the fresh variable it is replaced
+ * with to args, and the unresolved type corresponding to the non-terminal
+ * symbol to cargs (constructor args). In other words, args contains the
+ * free variables in the term returned by this method (which should be bound
+ * by a lambda), and cargs contains the types of the arguments of the
+ * sygus constructor.
+ */
+ Expr purifySygusGTerm(Expr term,
+ std::map<Expr, Type>& ntsToUnres,
+ std::vector<Expr>& args,
+ std::vector<Type>& cargs) const;
+
void addArithmeticOperators();
void addTranscendentalOperators();
+ void addQuantifiersOperators();
+
void addBitvectorOperators();
+ void addDatatypesOperators();
+
void addStringOperators();
void addFloatingPointOperators();
@@ -399,9 +565,9 @@ private:
void addSepOperators();
InputLanguage getLanguage() const;
-};/* class Smt2 */
+}; /* class Smt2 */
}/* CVC4::parser namespace */
}/* CVC4 namespace */
-#endif /* __CVC4__PARSER__SMT2_H */
+#endif /* CVC4__PARSER__SMT2_H */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback