GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/uf/theory_uf_type_rules.cpp Lines: 51 75 68.0 %
Date: 2021-05-22 Branches: 88 320 27.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Tim King, Morgan Deters
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
 * Typing and cardinality rules for the theory of UF.
14
 */
15
16
#include "theory/uf/theory_uf_type_rules.h"
17
18
#include <climits>
19
#include <sstream>
20
21
namespace cvc5 {
22
namespace theory {
23
namespace uf {
24
25
469914
TypeNode UfTypeRule::computeType(NodeManager* nodeManager, TNode n, bool check)
26
{
27
939828
  TNode f = n.getOperator();
28
939828
  TypeNode fType = f.getType(check);
29
469914
  if (!fType.isFunction())
30
  {
31
    throw TypeCheckingExceptionPrivate(n,
32
                                       "operator does not have function type");
33
  }
34
469914
  if (check)
35
  {
36
469914
    if (n.getNumChildren() != fType.getNumChildren() - 1)
37
    {
38
      throw TypeCheckingExceptionPrivate(
39
          n, "number of arguments does not match the function type");
40
    }
41
469914
    TNode::iterator argument_it = n.begin();
42
469914
    TNode::iterator argument_it_end = n.end();
43
469914
    TypeNode::iterator argument_type_it = fType.begin();
44
14348414
    for (; argument_it != argument_it_end; ++argument_it, ++argument_type_it)
45
    {
46
13878500
      TypeNode currentArgument = (*argument_it).getType();
47
13878500
      TypeNode currentArgumentType = *argument_type_it;
48
6939250
      if (!currentArgument.isSubtypeOf(currentArgumentType))
49
      {
50
        std::stringstream ss;
51
        ss << "argument type is not a subtype of the function's argument "
52
           << "type:\n"
53
           << "argument:  " << *argument_it << "\n"
54
           << "has type:  " << (*argument_it).getType() << "\n"
55
           << "not subtype: " << *argument_type_it << "\n"
56
           << "in term : " << n;
57
        throw TypeCheckingExceptionPrivate(n, ss.str());
58
      }
59
    }
60
  }
61
939828
  return fType.getRangeType();
62
}
63
64
1112
TypeNode CardinalityConstraintTypeRule::computeType(NodeManager* nodeManager,
65
                                                    TNode n,
66
                                                    bool check)
67
{
68
1112
  if (check)
69
  {
70
    // don't care what it is, but it should be well-typed
71
1112
    n[0].getType(check);
72
73
2224
    TypeNode valType = n[1].getType(check);
74
1112
    if (valType != nodeManager->integerType())
75
    {
76
      throw TypeCheckingExceptionPrivate(
77
          n, "cardinality constraint must be integer");
78
    }
79
1112
    if (n[1].getKind() != kind::CONST_RATIONAL)
80
    {
81
      throw TypeCheckingExceptionPrivate(
82
          n, "cardinality constraint must be a constant");
83
    }
84
2224
    cvc5::Rational r(INT_MAX);
85
1112
    if (n[1].getConst<Rational>() > r)
86
    {
87
      throw TypeCheckingExceptionPrivate(
88
          n, "Exceeded INT_MAX in cardinality constraint");
89
    }
90
1112
    if (n[1].getConst<Rational>().getNumerator().sgn() != 1)
91
    {
92
      throw TypeCheckingExceptionPrivate(
93
          n, "cardinality constraint must be positive");
94
    }
95
  }
96
1112
  return nodeManager->booleanType();
97
}
98
99
641
TypeNode CombinedCardinalityConstraintTypeRule::computeType(
100
    NodeManager* nodeManager, TNode n, bool check)
101
{
102
641
  if (check)
103
  {
104
1282
    TypeNode valType = n[0].getType(check);
105
641
    if (valType != nodeManager->integerType())
106
    {
107
      throw TypeCheckingExceptionPrivate(
108
          n, "combined cardinality constraint must be integer");
109
    }
110
641
    if (n[0].getKind() != kind::CONST_RATIONAL)
111
    {
112
      throw TypeCheckingExceptionPrivate(
113
          n, "combined cardinality constraint must be a constant");
114
    }
115
1282
    cvc5::Rational r(INT_MAX);
116
641
    if (n[0].getConst<Rational>() > r)
117
    {
118
      throw TypeCheckingExceptionPrivate(
119
          n, "Exceeded INT_MAX in combined cardinality constraint");
120
    }
121
641
    if (n[0].getConst<Rational>().getNumerator().sgn() == -1)
122
    {
123
      throw TypeCheckingExceptionPrivate(
124
          n, "combined cardinality constraint must be non-negative");
125
    }
126
  }
127
641
  return nodeManager->booleanType();
128
}
129
130
TypeNode PartialTypeRule::computeType(NodeManager* nodeManager,
131
                                      TNode n,
132
                                      bool check)
133
{
134
  return n.getOperator().getType().getRangeType();
135
}
136
137
TypeNode CardinalityValueTypeRule::computeType(NodeManager* nodeManager,
138
                                               TNode n,
139
                                               bool check)
140
{
141
  if (check)
142
  {
143
    n[0].getType(check);
144
  }
145
  return nodeManager->integerType();
146
}
147
148
15022
TypeNode HoApplyTypeRule::computeType(NodeManager* nodeManager,
149
                                      TNode n,
150
                                      bool check)
151
{
152
15022
  Assert(n.getKind() == kind::HO_APPLY);
153
30044
  TypeNode fType = n[0].getType(check);
154
15022
  if (!fType.isFunction())
155
  {
156
    throw TypeCheckingExceptionPrivate(
157
        n, "first argument does not have function type");
158
  }
159
15022
  Assert(fType.getNumChildren() >= 2);
160
15022
  if (check)
161
  {
162
30044
    TypeNode aType = n[1].getType(check);
163
15022
    if (!aType.isSubtypeOf(fType[0]))
164
    {
165
      throw TypeCheckingExceptionPrivate(
166
          n, "argument does not match function type");
167
    }
168
  }
169
15022
  if (fType.getNumChildren() == 2)
170
  {
171
7216
    return fType.getRangeType();
172
  }
173
  else
174
  {
175
15612
    std::vector<TypeNode> children;
176
7806
    TypeNode::iterator argument_type_it = fType.begin();
177
7806
    TypeNode::iterator argument_type_it_end = fType.end();
178
7806
    ++argument_type_it;
179
43280
    for (; argument_type_it != argument_type_it_end; ++argument_type_it)
180
    {
181
17737
      children.push_back(*argument_type_it);
182
    }
183
7806
    return nodeManager->mkFunctionType(children);
184
  }
185
}
186
187
}  // namespace uf
188
}  // namespace theory
189
28194
}  // namespace cvc5