GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/uf/theory_uf_type_rules.cpp Lines: 36 62 58.1 %
Date: 2021-11-05 Branches: 50 218 22.9 %

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
#include "expr/cardinality_constraint.h"
22
#include "util/rational.h"
23
24
namespace cvc5 {
25
namespace theory {
26
namespace uf {
27
28
483082
TypeNode UfTypeRule::computeType(NodeManager* nodeManager, TNode n, bool check)
29
{
30
966164
  TNode f = n.getOperator();
31
966164
  TypeNode fType = f.getType(check);
32
483082
  if (!fType.isFunction())
33
  {
34
    throw TypeCheckingExceptionPrivate(n,
35
                                       "operator does not have function type");
36
  }
37
483082
  if (check)
38
  {
39
483082
    if (n.getNumChildren() != fType.getNumChildren() - 1)
40
    {
41
      throw TypeCheckingExceptionPrivate(
42
          n, "number of arguments does not match the function type");
43
    }
44
483082
    TNode::iterator argument_it = n.begin();
45
483082
    TNode::iterator argument_it_end = n.end();
46
483082
    TypeNode::iterator argument_type_it = fType.begin();
47
14486702
    for (; argument_it != argument_it_end; ++argument_it, ++argument_type_it)
48
    {
49
14003620
      TypeNode currentArgument = (*argument_it).getType();
50
14003620
      TypeNode currentArgumentType = *argument_type_it;
51
7001810
      if (!currentArgument.isSubtypeOf(currentArgumentType))
52
      {
53
        std::stringstream ss;
54
        ss << "argument type is not a subtype of the function's argument "
55
           << "type:\n"
56
           << "argument:  " << *argument_it << "\n"
57
           << "has type:  " << (*argument_it).getType() << "\n"
58
           << "not subtype: " << *argument_type_it << "\n"
59
           << "in term : " << n;
60
        throw TypeCheckingExceptionPrivate(n, ss.str());
61
      }
62
    }
63
  }
64
966164
  return fType.getRangeType();
65
}
66
67
TypeNode CardinalityConstraintOpTypeRule::computeType(NodeManager* nodeManager,
68
                                                      TNode n,
69
                                                      bool check)
70
{
71
  if (check)
72
  {
73
    const CardinalityConstraint& cc = n.getConst<CardinalityConstraint>();
74
    if (!cc.getType().isSort())
75
    {
76
      throw TypeCheckingExceptionPrivate(
77
          n, "cardinality constraint must apply to uninterpreted sort");
78
    }
79
    if (cc.getUpperBound().sgn() != 1)
80
    {
81
      throw TypeCheckingExceptionPrivate(
82
          n, "cardinality constraint must be positive");
83
    }
84
  }
85
  return nodeManager->booleanType();
86
}
87
88
909
TypeNode CardinalityConstraintTypeRule::computeType(NodeManager* nodeManager,
89
                                                    TNode n,
90
                                                    bool check)
91
{
92
909
  return nodeManager->booleanType();
93
}
94
95
TypeNode CombinedCardinalityConstraintOpTypeRule::computeType(
96
    NodeManager* nodeManager, TNode n, bool check)
97
{
98
  if (check)
99
  {
100
    const CombinedCardinalityConstraint& cc =
101
        n.getConst<CombinedCardinalityConstraint>();
102
    if (cc.getUpperBound().sgn() != 1)
103
    {
104
      throw TypeCheckingExceptionPrivate(
105
          n, "combined cardinality constraint must be positive");
106
    }
107
  }
108
  return nodeManager->booleanType();
109
}
110
111
641
TypeNode CombinedCardinalityConstraintTypeRule::computeType(
112
    NodeManager* nodeManager, TNode n, bool check)
113
{
114
641
  return nodeManager->booleanType();
115
}
116
117
TypeNode PartialTypeRule::computeType(NodeManager* nodeManager,
118
                                      TNode n,
119
                                      bool check)
120
{
121
  return n.getOperator().getType().getRangeType();
122
}
123
124
13100
TypeNode HoApplyTypeRule::computeType(NodeManager* nodeManager,
125
                                      TNode n,
126
                                      bool check)
127
{
128
13100
  Assert(n.getKind() == kind::HO_APPLY);
129
26200
  TypeNode fType = n[0].getType(check);
130
13100
  if (!fType.isFunction())
131
  {
132
    throw TypeCheckingExceptionPrivate(
133
        n, "first argument does not have function type");
134
  }
135
13100
  Assert(fType.getNumChildren() >= 2);
136
13100
  if (check)
137
  {
138
26200
    TypeNode aType = n[1].getType(check);
139
13100
    if (!aType.isSubtypeOf(fType[0]))
140
    {
141
      throw TypeCheckingExceptionPrivate(
142
          n, "argument does not match function type");
143
    }
144
  }
145
13100
  if (fType.getNumChildren() == 2)
146
  {
147
5970
    return fType.getRangeType();
148
  }
149
  else
150
  {
151
14260
    std::vector<TypeNode> children;
152
7130
    TypeNode::iterator argument_type_it = fType.begin();
153
7130
    TypeNode::iterator argument_type_it_end = fType.end();
154
7130
    ++argument_type_it;
155
39540
    for (; argument_type_it != argument_type_it_end; ++argument_type_it)
156
    {
157
16205
      children.push_back(*argument_type_it);
158
    }
159
7130
    return nodeManager->mkFunctionType(children);
160
  }
161
}
162
163
}  // namespace uf
164
}  // namespace theory
165
31125
}  // namespace cvc5