From: Andres Noetzli Date: Sun, 29 Sep 2019 03:18:22 +0000 (-0700) Subject: Introduce template classes for simple type rules (#2835) X-Git-Tag: cvc5-1.0.0~3927 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d06cf394473cbe09c2e1acc333526c41a6dd9687;p=cvc5.git Introduce template classes for simple type rules (#2835) This commit introduces two template classes `SimpleTypeRule` and `SimpleTypeRuleVar` to help define simple type rules without writing lots of redundant code. The main advantages of this approach are: - Less code - More consistent error reporting - Easier to extend type checking with other functionality (e.g. getting the type of a symbol) --- diff --git a/src/expr/type_checker_template.cpp b/src/expr/type_checker_template.cpp index 078c275f8..9ca5f00cc 100644 --- a/src/expr/type_checker_template.cpp +++ b/src/expr/type_checker_template.cpp @@ -16,13 +16,14 @@ #line 18 "${template}" -#include "expr/type_checker.h" #include "expr/node_manager.h" #include "expr/node_manager_attributes.h" +#include "expr/type_checker.h" +#include "expr/type_checker_util.h" ${typechecker_includes} -#line 26 "${template}" +#line 27 "${template}" namespace CVC4 { namespace expr { @@ -43,7 +44,7 @@ TypeNode TypeChecker::computeType(NodeManager* nodeManager, TNode n, bool check) ${typerules} -#line 47 "${template}" +#line 48 "${template}" default: Debug("getType") << "FAILURE" << std::endl; @@ -65,7 +66,7 @@ bool TypeChecker::computeIsConst(NodeManager* nodeManager, TNode n) switch(n.getKind()) { ${construles} -#line 69 "${template}" +#line 70 "${template}" default:; } @@ -81,7 +82,7 @@ bool TypeChecker::neverIsConst(NodeManager* nodeManager, TNode n) switch(n.getKind()) { ${neverconstrules} -#line 85 "${template}" +#line 86 "${template}" default:; } diff --git a/src/expr/type_checker_util.h b/src/expr/type_checker_util.h new file mode 100644 index 000000000..fc5513d7b --- /dev/null +++ b/src/expr/type_checker_util.h @@ -0,0 +1,203 @@ +/********************* */ +/*! \file type_checker_util.h + ** \verbatim + ** Top contributors (to current version): + ** Andres Noetzli + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS + ** in the top-level source directory) and their institutional affiliations. + ** All rights reserved. See the file COPYING in the top-level source + ** directory for licensing information.\endverbatim + ** + ** \brief Templates for simple type rules + ** + ** This file defines templates for simple type rules. If a kind has the a + ** type rule where each argument matches exactly a specific sort, these + ** templates can be used to define typechecks without writing dedicated classes + ** for them. + **/ + +#include "cvc4_private.h" + +#include "expr/kind.h" +#include "expr/node.h" +#include "expr/node_manager.h" +#include "expr/type_node.h" + +namespace CVC4 { +namespace expr { + +/** Type check returns the builtin operator sort */ +struct RBuiltinOperator +{ + static TypeNode mkType(NodeManager* nm) { return nm->builtinOperatorType(); } +}; + +/** Type check returns the Boolean sort */ +struct RBool +{ + static TypeNode mkType(NodeManager* nm) { return nm->booleanType(); } +}; + +/** Type check returns the integer sort */ +struct RInteger +{ + static TypeNode mkType(NodeManager* nm) { return nm->integerType(); } +}; + +/** Type check returns the real sort */ +struct RReal +{ + static TypeNode mkType(NodeManager* nm) { return nm->realType(); } +}; + +/** Type check returns the regexp sort */ +struct RRegExp +{ + static TypeNode mkType(NodeManager* nm) { return nm->regExpType(); } +}; + +/** Type check returns the string sort */ +struct RString +{ + static TypeNode mkType(NodeManager* nm) { return nm->stringType(); } +}; + +/** Argument does not exist */ +struct ANone +{ + static bool checkArg(TNode n, size_t arg) + { + Assert(arg >= n.getNumChildren()); + return true; + } + constexpr static const char* typeName = ""; +}; + +/** Argument is optional */ +template +struct AOptional +{ + static bool checkArg(TNode n, size_t arg) + { + if (arg < n.getNumChildren()) { + return A::checkArg(n, arg); + } + return true; + } + constexpr static const char* typeName = A::typeName; +}; + +/** Argument is an integer */ +struct AInteger +{ + static bool checkArg(TNode n, size_t arg) + { + TypeNode t = n[arg].getType(true); + return t.isInteger(); + } + constexpr static const char* typeName = "integer"; +}; + +/** Argument is a real */ +struct AReal +{ + static bool checkArg(TNode n, size_t arg) + { + TypeNode t = n[arg].getType(true); + return t.isReal(); + } + constexpr static const char* typeName = "real"; +}; + +/** Argument is a regexp */ +struct ARegExp +{ + static bool checkArg(TNode n, size_t arg) + { + TypeNode t = n[arg].getType(true); + return t.isRegExp(); + } + constexpr static const char* typeName = "regexp"; +}; + +/** Argument is a string */ +struct AString +{ + static bool checkArg(TNode n, size_t arg) + { + TypeNode t = n[arg].getType(true); + return t.isString(); + } + constexpr static const char* typeName = "string"; +}; + +/** + * The SimpleTypeRule template can be used to obtain a simple type rule by + * defining a return type and the argument types (up to three arguments are + * supported). + * */ +template +class SimpleTypeRule +{ + public: + static TypeNode computeType(NodeManager* nm, TNode n, bool check) + { + if (check) + { + if (!A0::checkArg(n, 0)) + { + std::stringstream msg; + msg << "Expecting a " << A0::typeName + << " term as the first argument in '" << n.getKind() << "'"; + throw TypeCheckingExceptionPrivate(n, msg.str()); + } + if (!A1::checkArg(n, 1)) + { + std::stringstream msg; + msg << "Expecting a " << A1::typeName + << " term as the second argument in '" << n.getKind() << "'"; + throw TypeCheckingExceptionPrivate(n, msg.str()); + } + if (!A2::checkArg(n, 2)) + { + std::stringstream msg; + msg << "Expecting a " << A2::typeName + << " term as the third argument in '" << n.getKind() << "'"; + throw TypeCheckingExceptionPrivate(n, msg.str()); + } + } + return R::mkType(nm); + } +}; + +/** + * The SimpleTypeRuleVar template can be used to obtain a simple type rule for + * operators with a variable number of arguments. It takes the return type and + * the type of the arguments as template parameters. + * */ +template +class SimpleTypeRuleVar +{ + public: + static TypeNode computeType(NodeManager* nm, TNode n, bool check) + { + if (check) + { + for (size_t i = 0, size = n.getNumChildren(); i < size; i++) + { + if (!A::checkArg(n, i)) + { + std::stringstream msg; + msg << "Expecting a " << A::typeName << " term as argument " << i + << " in '" << n.getKind() << "'"; + throw TypeCheckingExceptionPrivate(n, msg.str()); + } + } + } + return R::mkType(nm); + } +}; + +} // namespace expr +} // namespace CVC4 diff --git a/src/theory/arith/kinds b/src/theory/arith/kinds index 95d1aa9c1..409534050 100644 --- a/src/theory/arith/kinds +++ b/src/theory/arith/kinds @@ -94,40 +94,40 @@ typerule POW ::CVC4::theory::arith::ArithOperatorTypeRule typerule CONST_RATIONAL ::CVC4::theory::arith::ArithConstantTypeRule -typerule LT ::CVC4::theory::arith::ArithPredicateTypeRule -typerule LEQ ::CVC4::theory::arith::ArithPredicateTypeRule -typerule GT ::CVC4::theory::arith::ArithPredicateTypeRule -typerule GEQ ::CVC4::theory::arith::ArithPredicateTypeRule +typerule LT "SimpleTypeRule" +typerule LEQ "SimpleTypeRule" +typerule GT "SimpleTypeRule" +typerule GEQ "SimpleTypeRule" typerule TO_REAL ::CVC4::theory::arith::ArithOperatorTypeRule typerule TO_INTEGER ::CVC4::theory::arith::ArithOperatorTypeRule -typerule IS_INTEGER ::CVC4::theory::arith::ArithUnaryPredicateTypeRule +typerule IS_INTEGER "SimpleTypeRule" -typerule ABS ::CVC4::theory::arith::IntOperatorTypeRule -typerule INTS_DIVISION ::CVC4::theory::arith::IntOperatorTypeRule -typerule INTS_MODULUS ::CVC4::theory::arith::IntOperatorTypeRule -typerule DIVISIBLE ::CVC4::theory::arith::IntUnaryPredicateTypeRule -typerule DIVISIBLE_OP ::CVC4::theory::arith::DivisibleOpTypeRule +typerule ABS "SimpleTypeRule" +typerule INTS_DIVISION "SimpleTypeRule" +typerule INTS_MODULUS "SimpleTypeRule" +typerule DIVISIBLE "SimpleTypeRule" +typerule DIVISIBLE_OP "SimpleTypeRule" typerule DIVISION_TOTAL ::CVC4::theory::arith::ArithOperatorTypeRule -typerule INTS_DIVISION_TOTAL ::CVC4::theory::arith::IntOperatorTypeRule -typerule INTS_MODULUS_TOTAL ::CVC4::theory::arith::IntOperatorTypeRule - -typerule EXPONENTIAL ::CVC4::theory::arith::RealOperatorTypeRule -typerule SINE ::CVC4::theory::arith::RealOperatorTypeRule -typerule COSINE ::CVC4::theory::arith::RealOperatorTypeRule -typerule TANGENT ::CVC4::theory::arith::RealOperatorTypeRule -typerule COSECANT ::CVC4::theory::arith::RealOperatorTypeRule -typerule SECANT ::CVC4::theory::arith::RealOperatorTypeRule -typerule COTANGENT ::CVC4::theory::arith::RealOperatorTypeRule -typerule ARCSINE ::CVC4::theory::arith::RealOperatorTypeRule -typerule ARCCOSINE ::CVC4::theory::arith::RealOperatorTypeRule -typerule ARCTANGENT ::CVC4::theory::arith::RealOperatorTypeRule -typerule ARCCOSECANT ::CVC4::theory::arith::RealOperatorTypeRule -typerule ARCSECANT ::CVC4::theory::arith::RealOperatorTypeRule -typerule ARCCOTANGENT ::CVC4::theory::arith::RealOperatorTypeRule - -typerule SQRT ::CVC4::theory::arith::RealOperatorTypeRule +typerule INTS_DIVISION_TOTAL "SimpleTypeRule" +typerule INTS_MODULUS_TOTAL "SimpleTypeRule" + +typerule EXPONENTIAL "SimpleTypeRule" +typerule SINE "SimpleTypeRule" +typerule COSINE "SimpleTypeRule" +typerule TANGENT "SimpleTypeRule" +typerule COSECANT "SimpleTypeRule" +typerule SECANT "SimpleTypeRule" +typerule COTANGENT "SimpleTypeRule" +typerule ARCSINE "SimpleTypeRule" +typerule ARCCOSINE "SimpleTypeRule" +typerule ARCTANGENT "SimpleTypeRule" +typerule ARCCOSECANT "SimpleTypeRule" +typerule ARCSECANT "SimpleTypeRule" +typerule ARCCOTANGENT "SimpleTypeRule" + +typerule SQRT "SimpleTypeRule" nullaryoperator PI "pi" diff --git a/src/theory/arith/theory_arith_type_rules.h b/src/theory/arith/theory_arith_type_rules.h index c32b612e2..8b587c0fb 100644 --- a/src/theory/arith/theory_arith_type_rules.h +++ b/src/theory/arith/theory_arith_type_rules.h @@ -73,88 +73,6 @@ public: } };/* class ArithOperatorTypeRule */ -class IntOperatorTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - TNode::iterator child_it = n.begin(); - TNode::iterator child_it_end = n.end(); - if(check) { - for(; child_it != child_it_end; ++child_it) { - TypeNode childType = (*child_it).getType(check); - if (!childType.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer subterm"); - } - } - } - return nodeManager->integerType(); - } -};/* class IntOperatorTypeRule */ - -class RealOperatorTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - TNode::iterator child_it = n.begin(); - TNode::iterator child_it_end = n.end(); - if(check) { - for(; child_it != child_it_end; ++child_it) { - TypeNode childType = (*child_it).getType(check); - if (!childType.isReal()) { - throw TypeCheckingExceptionPrivate(n, "expecting a real subterm"); - } - } - } - return nodeManager->realType(); - } -};/* class RealOperatorTypeRule */ - -class ArithPredicateTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode lhsType = n[0].getType(check); - if (!lhsType.isReal()) { - throw TypeCheckingExceptionPrivate(n, "expecting an arithmetic term on the left-hand-side"); - } - TypeNode rhsType = n[1].getType(check); - if (!rhsType.isReal()) { - throw TypeCheckingExceptionPrivate(n, "expecting an arithmetic term on the right-hand-side"); - } - } - return nodeManager->booleanType(); - } -};/* class ArithPredicateTypeRule */ - -class ArithUnaryPredicateTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isReal()) { - throw TypeCheckingExceptionPrivate(n, "expecting an arithmetic term"); - } - } - return nodeManager->booleanType(); - } -};/* class ArithUnaryPredicateTypeRule */ - -class IntUnaryPredicateTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term"); - } - } - return nodeManager->booleanType(); - } -};/* class IntUnaryPredicateTypeRule */ - class RealNullaryOperatorTypeRule { public: inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) @@ -169,18 +87,6 @@ public: } };/* class RealNullaryOperatorTypeRule */ -class DivisibleOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::DIVISIBLE_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class DivisibleOpTypeRule */ - }/* CVC4::theory::arith namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */ diff --git a/src/theory/bv/kinds b/src/theory/bv/kinds index fe451603b..f9caf119a 100644 --- a/src/theory/bv/kinds +++ b/src/theory/bv/kinds @@ -222,19 +222,19 @@ typerule BITVECTOR_EAGER_ATOM ::CVC4::theory::bv::BitVectorEagerAtomTypeRule ### type rules for parameterized operator kinds ------------------------------- -typerule BITVECTOR_BITOF_OP ::CVC4::theory::bv::BitVectorBitOfOpTypeRule +typerule BITVECTOR_BITOF_OP "SimpleTypeRule" typerule BITVECTOR_BITOF ::CVC4::theory::bv::BitVectorBitOfTypeRule -typerule BITVECTOR_EXTRACT_OP ::CVC4::theory::bv::BitVectorExtractOpTypeRule +typerule BITVECTOR_EXTRACT_OP "SimpleTypeRule" typerule BITVECTOR_EXTRACT ::CVC4::theory::bv::BitVectorExtractTypeRule -typerule BITVECTOR_REPEAT_OP ::CVC4::theory::bv::BitVectorRepeatOpTypeRule +typerule BITVECTOR_REPEAT_OP "SimpleTypeRule" typerule BITVECTOR_REPEAT ::CVC4::theory::bv::BitVectorRepeatTypeRule -typerule BITVECTOR_ROTATE_LEFT_OP ::CVC4::theory::bv::BitVectorRotateLeftOpTypeRule +typerule BITVECTOR_ROTATE_LEFT_OP "SimpleTypeRule" typerule BITVECTOR_ROTATE_LEFT ::CVC4::theory::bv::BitVectorFixedWidthTypeRule -typerule BITVECTOR_ROTATE_RIGHT_OP ::CVC4::theory::bv::BitVectorRotateRightOpTypeRule +typerule BITVECTOR_ROTATE_RIGHT_OP "SimpleTypeRule" typerule BITVECTOR_ROTATE_RIGHT ::CVC4::theory::bv::BitVectorFixedWidthTypeRule -typerule BITVECTOR_SIGN_EXTEND_OP ::CVC4::theory::bv::BitVectorSignExtendOpTypeRule +typerule BITVECTOR_SIGN_EXTEND_OP "SimpleTypeRule" typerule BITVECTOR_SIGN_EXTEND ::CVC4::theory::bv::BitVectorExtendTypeRule -typerule BITVECTOR_ZERO_EXTEND_OP ::CVC4::theory::bv::BitVectorZeroExtendOpTypeRule +typerule BITVECTOR_ZERO_EXTEND_OP "SimpleTypeRule" typerule BITVECTOR_ZERO_EXTEND ::CVC4::theory::bv::BitVectorExtendTypeRule typerule INT_TO_BITVECTOR_OP ::CVC4::theory::bv::IntToBitVectorOpTypeRule typerule INT_TO_BITVECTOR ::CVC4::theory::bv::BitVectorConversionTypeRule diff --git a/src/theory/bv/theory_bv_type_rules.h b/src/theory/bv/theory_bv_type_rules.h index 64d04a37e..e56f752af 100644 --- a/src/theory/bv/theory_bv_type_rules.h +++ b/src/theory/bv/theory_bv_type_rules.h @@ -224,18 +224,6 @@ class BitVectorITETypeRule /* parameterized operator kinds */ /* -------------------------------------------------------------------------- */ -class BitVectorBitOfOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_BITOF_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorBitOfOpTypeRule */ - class BitVectorBitOfTypeRule { public: @@ -262,18 +250,6 @@ class BitVectorBitOfTypeRule } }; /* class BitVectorBitOfTypeRule */ -class BitVectorExtractOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_EXTRACT_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorExtractOpTypeRule */ - class BitVectorExtractTypeRule { public: @@ -309,18 +285,6 @@ class BitVectorExtractTypeRule } }; /* class BitVectorExtractTypeRule */ -class BitVectorRepeatOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_REPEAT_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorRepeatOpTypeRule */ - class BitVectorRepeatTypeRule { public: @@ -341,54 +305,6 @@ class BitVectorRepeatTypeRule } }; /* class BitVectorRepeatTypeRule */ -class BitVectorRotateLeftOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_ROTATE_LEFT_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorRotateLeftOpTypeRule */ - -class BitVectorRotateRightOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_ROTATE_RIGHT_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorRotateRightOpTypeRule */ - -class BitVectorSignExtendOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_SIGN_EXTEND_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorSignExtendOpTypeRule */ - -class BitVectorZeroExtendOpTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - Assert(n.getKind() == kind::BITVECTOR_ZERO_EXTEND_OP); - return nodeManager->builtinOperatorType(); - } -}; /* class BitVectorZeroExtendOpTypeRule */ - class BitVectorExtendTypeRule { public: diff --git a/src/theory/strings/kinds b/src/theory/strings/kinds index 715ea8f50..4e90d1583 100644 --- a/src/theory/strings/kinds +++ b/src/theory/strings/kinds @@ -55,7 +55,7 @@ constant CONST_STRING \ "util/regexp.h" \ "a string of characters" -typerule CONST_STRING ::CVC4::theory::strings::StringConstantTypeRule +typerule CONST_STRING "SimpleTypeRule" # equal equal / less than / output operator STRING_TO_REGEXP 1 "convert string to regexp" @@ -73,41 +73,41 @@ operator REGEXP_SIGMA 0 "regexp all characters" #internal operator REGEXP_RV 1 "regexp rv (internal use only)" -typerule REGEXP_RV ::CVC4::theory::strings::RegExpRVTypeRule +typerule REGEXP_RV "SimpleTypeRule" #typerules -typerule REGEXP_CONCAT ::CVC4::theory::strings::RegExpConcatTypeRule -typerule REGEXP_UNION ::CVC4::theory::strings::RegExpUnionTypeRule -typerule REGEXP_INTER ::CVC4::theory::strings::RegExpInterTypeRule -typerule REGEXP_STAR ::CVC4::theory::strings::RegExpStarTypeRule -typerule REGEXP_PLUS ::CVC4::theory::strings::RegExpPlusTypeRule -typerule REGEXP_OPT ::CVC4::theory::strings::RegExpOptTypeRule +typerule REGEXP_CONCAT "SimpleTypeRuleVar" +typerule REGEXP_UNION "SimpleTypeRuleVar" +typerule REGEXP_INTER "SimpleTypeRuleVar" +typerule REGEXP_STAR "SimpleTypeRule" +typerule REGEXP_PLUS "SimpleTypeRule" +typerule REGEXP_OPT "SimpleTypeRule" typerule REGEXP_RANGE ::CVC4::theory::strings::RegExpRangeTypeRule -typerule REGEXP_LOOP ::CVC4::theory::strings::RegExpLoopTypeRule - -typerule STRING_TO_REGEXP ::CVC4::theory::strings::StringToRegExpTypeRule - -typerule STRING_CONCAT ::CVC4::theory::strings::StringConcatTypeRule -typerule STRING_LENGTH ::CVC4::theory::strings::StringLengthTypeRule -typerule STRING_SUBSTR ::CVC4::theory::strings::StringSubstrTypeRule -typerule STRING_CHARAT ::CVC4::theory::strings::StringCharAtTypeRule -typerule STRING_STRCTN ::CVC4::theory::strings::StringRelationTypeRule -typerule STRING_LT ::CVC4::theory::strings::StringRelationTypeRule -typerule STRING_LEQ ::CVC4::theory::strings::StringRelationTypeRule -typerule STRING_STRIDOF ::CVC4::theory::strings::StringIndexOfTypeRule -typerule STRING_STRREPL ::CVC4::theory::strings::StringReplaceTypeRule -typerule STRING_STRREPLALL ::CVC4::theory::strings::StringReplaceTypeRule -typerule STRING_PREFIX ::CVC4::theory::strings::StringPrefixOfTypeRule -typerule STRING_SUFFIX ::CVC4::theory::strings::StringSuffixOfTypeRule -typerule STRING_ITOS ::CVC4::theory::strings::StringIntToStrTypeRule -typerule STRING_STOI ::CVC4::theory::strings::StringStrToIntTypeRule -typerule STRING_CODE ::CVC4::theory::strings::StringStrToIntTypeRule -typerule STRING_TOUPPER ::CVC4::theory::strings::StringStrToStrTypeRule -typerule STRING_TOLOWER ::CVC4::theory::strings::StringStrToStrTypeRule - -typerule STRING_IN_REGEXP ::CVC4::theory::strings::StringInRegExpTypeRule - -typerule REGEXP_EMPTY ::CVC4::theory::strings::EmptyRegExpTypeRule -typerule REGEXP_SIGMA ::CVC4::theory::strings::SigmaRegExpTypeRule +typerule REGEXP_LOOP "SimpleTypeRule>" + +typerule STRING_TO_REGEXP "SimpleTypeRule" + +typerule STRING_CONCAT "SimpleTypeRuleVar" +typerule STRING_LENGTH "SimpleTypeRule" +typerule STRING_SUBSTR "SimpleTypeRule" +typerule STRING_CHARAT "SimpleTypeRule" +typerule STRING_STRCTN "SimpleTypeRule" +typerule STRING_LT "SimpleTypeRule" +typerule STRING_LEQ "SimpleTypeRule" +typerule STRING_STRIDOF "SimpleTypeRule" +typerule STRING_STRREPL "SimpleTypeRule" +typerule STRING_STRREPLALL "SimpleTypeRule" +typerule STRING_PREFIX "SimpleTypeRule" +typerule STRING_SUFFIX "SimpleTypeRule" +typerule STRING_ITOS "SimpleTypeRule" +typerule STRING_STOI "SimpleTypeRule" +typerule STRING_CODE "SimpleTypeRule" +typerule STRING_TOUPPER "SimpleTypeRule" +typerule STRING_TOLOWER "SimpleTypeRule" + +typerule STRING_IN_REGEXP "SimpleTypeRule" + +typerule REGEXP_EMPTY "SimpleTypeRule" +typerule REGEXP_SIGMA "SimpleTypeRule" endtheory diff --git a/src/theory/strings/theory_strings_type_rules.h b/src/theory/strings/theory_strings_type_rules.h index de77315fc..497366f40 100644 --- a/src/theory/strings/theory_strings_type_rules.h +++ b/src/theory/strings/theory_strings_type_rules.h @@ -9,9 +9,9 @@ ** All rights reserved. See the file COPYING in the top-level source ** directory for licensing information.\endverbatim ** - ** \brief Typing and cardinality rules for the theory of arrays + ** \brief Typing rules for the theory of strings and regexps ** - ** Typing and cardinality rules for the theory of arrays. + ** Typing rules for the theory of strings and regexps **/ #include "cvc4_private.h" @@ -24,344 +24,6 @@ namespace CVC4 { namespace theory { namespace strings { -class StringConstantTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - return nodeManager->stringType(); - } -}; - -class StringConcatTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ){ - TNode::iterator it = n.begin(); - TNode::iterator it_end = n.end(); - int size = 0; - for (; it != it_end; ++ it) { - TypeNode t = (*it).getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting string terms in string concat"); - } - ++size; - } - if(size < 2) { - throw TypeCheckingExceptionPrivate(n, "expecting at least 2 terms in string concat"); - } - } - return nodeManager->stringType(); - } -}; - -class StringLengthTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting string terms in string length"); - } - } - return nodeManager->integerType(); - } -}; - -class StringSubstrTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in substr"); - } - t = n[1].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting a start int term in substr"); - } - t = n[2].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting a length int term in substr"); - } - } - return nodeManager->stringType(); - } -}; - -class StringRelationTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate( - n, "expecting a string term in string relation"); - } - t = n[1].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate( - n, "expecting a string term in string relation"); - } - } - return nodeManager->booleanType(); - } -}; - -class StringCharAtTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string char at 0"); - } - t = n[1].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term in string char at 1"); - } - } - return nodeManager->stringType(); - } -}; - -class StringIndexOfTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string indexof 0"); - } - t = n[1].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string indexof 1"); - } - t = n[2].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term in string indexof 2"); - } - } - return nodeManager->integerType(); - } -}; - -class StringReplaceTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string replace 0"); - } - t = n[1].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string replace 1"); - } - t = n[2].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string replace 2"); - } - } - return nodeManager->stringType(); - } -}; - -class StringPrefixOfTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string prefixof 0"); - } - t = n[1].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string prefixof 1"); - } - } - return nodeManager->booleanType(); - } -}; - -class StringSuffixOfTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string suffixof 0"); - } - t = n[1].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting a string term in string suffixof 1"); - } - } - return nodeManager->booleanType(); - } -}; - -class StringIntToStrTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term in int to string 0"); - } - } - return nodeManager->stringType(); - } -}; - -class StringStrToIntTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - std::stringstream ss; - ss << "expecting a string term in argument of " << n.getKind(); - throw TypeCheckingExceptionPrivate(n, ss.str()); - } - } - return nodeManager->integerType(); - } -}; - -class StringStrToStrTypeRule -{ - public: - inline static TypeNode computeType(NodeManager* nodeManager, - TNode n, - bool check) - { - if (check) - { - TypeNode t = n[0].getType(check); - if (!t.isString()) - { - std::stringstream ss; - ss << "expecting a string term in argument of " << n.getKind(); - throw TypeCheckingExceptionPrivate(n, ss.str()); - } - } - return nodeManager->stringType(); - } -}; - -class RegExpConcatTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TNode::iterator it = n.begin(); - TNode::iterator it_end = n.end(); - int size = 0; - for (; it != it_end; ++ it) { - TypeNode t = (*it).getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms in regexp concat"); - } - ++size; - } - if(size < 2) { - throw TypeCheckingExceptionPrivate(n, "expecting at least 2 terms in regexp concat"); - } - } - return nodeManager->regExpType(); - } -}; - -class RegExpUnionTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TNode::iterator it = n.begin(); - TNode::iterator it_end = n.end(); - for (; it != it_end; ++ it) { - TypeNode t = (*it).getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms"); - } - } - } - return nodeManager->regExpType(); - } -}; - -class RegExpInterTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TNode::iterator it = n.begin(); - TNode::iterator it_end = n.end(); - for (; it != it_end; ++ it) { - TypeNode t = (*it).getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms"); - } - } - } - return nodeManager->regExpType(); - } -}; - -class RegExpStarTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms"); - } - } - return nodeManager->regExpType(); - } -}; - -class RegExpPlusTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms"); - } - } - return nodeManager->regExpType(); - } -}; - -class RegExpOptTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms"); - } - } - return nodeManager->regExpType(); - } -}; - class RegExpRangeTypeRule { public: inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) @@ -401,112 +63,6 @@ public: } }; -class RegExpLoopTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TNode::iterator it = n.begin(); - TNode::iterator it_end = n.end(); - TypeNode t = (*it).getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting a regexp term in regexp loop 1"); - } - ++it; t = (*it).getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term in regexp loop 2"); - } - //if(!(*it).isConst()) { - //throw TypeCheckingExceptionPrivate(n, "expecting an const integer term in regexp loop 2"); - //} - ++it; - if(it != it_end) { - t = (*it).getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term in regexp loop 3"); - } - //if(!(*it).isConst()) { - //throw TypeCheckingExceptionPrivate(n, "expecting an const integer term in regexp loop 3"); - //} - //if(++it != it_end) { - // throw TypeCheckingExceptionPrivate(n, "too many regexp"); - //} - } - } - return nodeManager->regExpType(); - } -}; - -class StringToRegExpTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting string terms"); - } - //if( (*it).getKind() != kind::CONST_STRING ) { - // throw TypeCheckingExceptionPrivate(n, "expecting constant string terms"); - //} - } - return nodeManager->regExpType(); - } -}; - -class StringInRegExpTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TNode::iterator it = n.begin(); - TypeNode t = (*it).getType(check); - if (!t.isString()) { - throw TypeCheckingExceptionPrivate(n, "expecting string terms"); - } - ++it; - t = (*it).getType(check); - if (!t.isRegExp()) { - throw TypeCheckingExceptionPrivate(n, "expecting regexp terms"); - } - } - return nodeManager->booleanType(); - } -}; - -class EmptyRegExpTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - Assert(n.getKind() == kind::REGEXP_EMPTY); - return nodeManager->regExpType(); - } -}; - -class SigmaRegExpTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - Assert(n.getKind() == kind::REGEXP_SIGMA); - return nodeManager->regExpType(); - } -}; - -class RegExpRVTypeRule { -public: - inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check) - { - if( check ) { - TypeNode t = n[0].getType(check); - if (!t.isInteger()) { - throw TypeCheckingExceptionPrivate(n, "expecting an integer term in RV"); - } - } - return nodeManager->regExpType(); - } -}; - - }/* CVC4::theory::strings namespace */ }/* CVC4::theory namespace */ }/* CVC4 namespace */