GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/expr/type_checker_util.h Lines: 36 48 75.0 %
Date: 2021-05-22 Branches: 164 1478 11.1 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andres Noetzli
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Templates for simple type rules
14
 *
15
 * This file defines templates for simple type rules. If a kind has the a
16
 * type rule where each argument matches exactly a specific sort, these
17
 * templates can be used to define typechecks without writing dedicated classes
18
 * for them.
19
 */
20
21
#include <sstream>
22
23
#include "cvc5_private.h"
24
#include "expr/kind.h"
25
#include "expr/node.h"
26
#include "expr/node_manager.h"
27
#include "expr/type_node.h"
28
29
namespace cvc5 {
30
namespace expr {
31
32
/** Type check returns the builtin operator sort */
33
struct RBuiltinOperator
34
{
35
4863
  static TypeNode mkType(NodeManager* nm) { return nm->builtinOperatorType(); }
36
};
37
38
/** Type check returns the Boolean sort */
39
struct RBool
40
{
41
826378
  static TypeNode mkType(NodeManager* nm) { return nm->booleanType(); }
42
};
43
44
/** Type check returns the integer sort */
45
struct RInteger
46
{
47
9057
  static TypeNode mkType(NodeManager* nm) { return nm->integerType(); }
48
};
49
50
/** Type check returns the real sort */
51
struct RReal
52
{
53
1989
  static TypeNode mkType(NodeManager* nm) { return nm->realType(); }
54
};
55
56
/** Type check returns the regexp sort */
57
struct RRegExp
58
{
59
31995
  static TypeNode mkType(NodeManager* nm) { return nm->regExpType(); }
60
};
61
62
/** Type check returns the string sort */
63
struct RString
64
{
65
29668
  static TypeNode mkType(NodeManager* nm) { return nm->stringType(); }
66
};
67
68
/** Argument does not exist */
69
struct ANone
70
{
71
1013867
  static bool checkArg(TNode n, size_t arg)
72
  {
73
1013867
    Assert(arg >= n.getNumChildren());
74
1013867
    return true;
75
  }
76
  constexpr static const char* typeName = "<none>";
77
};
78
79
/** Argument is optional */
80
template<class A>
81
struct AOptional
82
{
83
  static bool checkArg(TNode n, size_t arg)
84
  {
85
    if (arg < n.getNumChildren()) {
86
      return A::checkArg(n, arg);
87
    }
88
    return true;
89
  }
90
  constexpr static const char* typeName = A::typeName;
91
};
92
93
/** Argument is an integer */
94
struct AInteger
95
{
96
13101
  static bool checkArg(TNode n, size_t arg)
97
  {
98
26202
    TypeNode t = n[arg].getType(true);
99
26202
    return t.isInteger();
100
  }
101
  constexpr static const char* typeName = "integer";
102
};
103
104
/** Argument is a real */
105
struct AReal
106
{
107
1640626
  static bool checkArg(TNode n, size_t arg)
108
  {
109
3281252
    TypeNode t = n[arg].getType(true);
110
3281252
    return t.isReal();
111
  }
112
  constexpr static const char* typeName = "real";
113
};
114
115
/** Argument is a regexp */
116
struct ARegExp
117
{
118
20782
  static bool checkArg(TNode n, size_t arg)
119
  {
120
41564
    TypeNode t = n[arg].getType(true);
121
41564
    return t.isRegExp();
122
  }
123
  constexpr static const char* typeName = "regexp";
124
};
125
126
/** Argument is a string */
127
struct AString
128
{
129
18633
  static bool checkArg(TNode n, size_t arg)
130
  {
131
37266
    TypeNode t = n[arg].getType(true);
132
37266
    return t.isString();
133
  }
134
  constexpr static const char* typeName = "string";
135
};
136
137
/**
138
 * The SimpleTypeRule template can be used to obtain a simple type rule by
139
 * defining a return type and the argument types (up to three arguments are
140
 * supported).
141
 * */
142
template <class R, class A0 = ANone, class A1 = ANone, class A2 = ANone>
143
class SimpleTypeRule
144
{
145
 public:
146
901802
  static TypeNode computeType(NodeManager* nm, TNode n, bool check)
147
  {
148
901802
    if (check)
149
    {
150
900292
      if (!A0::checkArg(n, 0))
151
      {
152
4
        std::stringstream msg;
153
2
        msg << "Expecting a " << A0::typeName
154
2
            << " term as the first argument in '" << n.getKind() << "'";
155
2
        throw TypeCheckingExceptionPrivate(n, msg.str());
156
      }
157
900290
      if (!A1::checkArg(n, 1))
158
      {
159
        std::stringstream msg;
160
        msg << "Expecting a " << A1::typeName
161
            << " term as the second argument in '" << n.getKind() << "'";
162
        throw TypeCheckingExceptionPrivate(n, msg.str());
163
      }
164
900290
      if (!A2::checkArg(n, 2))
165
      {
166
        std::stringstream msg;
167
        msg << "Expecting a " << A2::typeName
168
            << " term as the third argument in '" << n.getKind() << "'";
169
        throw TypeCheckingExceptionPrivate(n, msg.str());
170
      }
171
    }
172
901800
    return R::mkType(nm);
173
  }
174
};
175
176
/**
177
 * The SimpleTypeRuleVar template can be used to obtain a simple type rule for
178
 * operators with a variable number of arguments. It takes the return type and
179
 * the type of the arguments as template parameters.
180
 * */
181
template <class R, class A>
182
class SimpleTypeRuleVar
183
{
184
 public:
185
2150
  static TypeNode computeType(NodeManager* nm, TNode n, bool check)
186
  {
187
2150
    if (check)
188
    {
189
8287
      for (size_t i = 0, size = n.getNumChildren(); i < size; i++)
190
      {
191
6137
        if (!A::checkArg(n, i))
192
        {
193
          std::stringstream msg;
194
          msg << "Expecting a " << A::typeName << " term as argument " << i
195
              << " in '" << n.getKind() << "'";
196
          throw TypeCheckingExceptionPrivate(n, msg.str());
197
        }
198
      }
199
    }
200
2150
    return R::mkType(nm);
201
  }
202
};
203
204
}  // namespace expr
205
}  // namespace cvc5