GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arith/theory_arith_type_rules.cpp Lines: 54 63 85.7 %
Date: 2021-05-21 Branches: 73 203 36.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Gereon Kremer, Dejan Jovanovic
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 theory arithmetic.
14
 */
15
16
#include "theory/arith/theory_arith_type_rules.h"
17
18
namespace cvc5 {
19
namespace theory {
20
namespace arith {
21
22
245890
TypeNode ArithConstantTypeRule::computeType(NodeManager* nodeManager,
23
                                            TNode n,
24
                                            bool check)
25
{
26
245890
  Assert(n.getKind() == kind::CONST_RATIONAL);
27
245890
  if (n.getConst<Rational>().isIntegral())
28
  {
29
121990
    return nodeManager->integerType();
30
  }
31
  else
32
  {
33
123900
    return nodeManager->realType();
34
  }
35
}
36
37
3357047
TypeNode ArithOperatorTypeRule::computeType(NodeManager* nodeManager,
38
                                            TNode n,
39
                                            bool check)
40
{
41
6714094
  TypeNode integerType = nodeManager->integerType();
42
6714094
  TypeNode realType = nodeManager->realType();
43
3357047
  TNode::iterator child_it = n.begin();
44
3357047
  TNode::iterator child_it_end = n.end();
45
3357047
  bool isInteger = true;
46
3357047
  Kind k = n.getKind();
47
20668475
  for (; child_it != child_it_end; ++child_it)
48
  {
49
17311428
    TypeNode childType = (*child_it).getType(check);
50
8655714
    if (!childType.isInteger())
51
    {
52
1884061
      isInteger = false;
53
1884061
      if (!check)
54
      {  // if we're not checking, nothing left to do
55
        break;
56
      }
57
    }
58
8655714
    if (check)
59
    {
60
8655714
      if (!childType.isReal())
61
      {
62
        throw TypeCheckingExceptionPrivate(n,
63
                                           "expecting an arithmetic subterm");
64
      }
65
8655714
      if (k == kind::TO_REAL && !childType.isInteger())
66
      {
67
        throw TypeCheckingExceptionPrivate(n, "expecting an integer subterm");
68
      }
69
    }
70
  }
71
3357047
  switch (k)
72
  {
73
1553
    case kind::TO_REAL:
74
1553
    case kind::CAST_TO_REAL: return realType;
75
628
    case kind::TO_INTEGER: return integerType;
76
3354866
    default:
77
    {
78
3354866
      bool isDivision = k == kind::DIVISION || k == kind::DIVISION_TOTAL;
79
3354866
      return (isInteger && !isDivision ? integerType : realType);
80
    }
81
  }
82
}
83
84
1512
TypeNode RealNullaryOperatorTypeRule::computeType(NodeManager* nodeManager,
85
                                                  TNode n,
86
                                                  bool check)
87
{
88
  // for nullary operators, we only computeType for check=true, since they are
89
  // given TypeAttr() on creation
90
1512
  Assert(check);
91
1512
  TypeNode realType = n.getType();
92
1512
  if (realType != NodeManager::currentNM()->realType())
93
  {
94
    throw TypeCheckingExceptionPrivate(n, "expecting real type");
95
  }
96
1512
  return realType;
97
}
98
99
65
TypeNode IAndOpTypeRule::computeType(NodeManager* nodeManager,
100
                                     TNode n,
101
                                     bool check)
102
{
103
65
  if (n.getKind() != kind::IAND_OP)
104
  {
105
    InternalError() << "IAND_OP typerule invoked for IAND_OP kind";
106
  }
107
130
  TypeNode iType = nodeManager->integerType();
108
130
  std::vector<TypeNode> argTypes;
109
65
  argTypes.push_back(iType);
110
65
  argTypes.push_back(iType);
111
130
  return nodeManager->mkFunctionType(argTypes, iType);
112
}
113
114
274
TypeNode IAndTypeRule::computeType(NodeManager* nodeManager,
115
                                   TNode n,
116
                                   bool check)
117
{
118
274
  if (n.getKind() != kind::IAND)
119
  {
120
    InternalError() << "IAND typerule invoked for IAND kind";
121
  }
122
274
  if (check)
123
  {
124
548
    TypeNode arg1 = n[0].getType(check);
125
548
    TypeNode arg2 = n[1].getType(check);
126
274
    if (!arg1.isInteger() || !arg2.isInteger())
127
    {
128
      throw TypeCheckingExceptionPrivate(n, "expecting integer terms");
129
    }
130
  }
131
274
  return nodeManager->integerType();
132
}
133
134
5
TypeNode IndexedRootPredicateTypeRule::computeType(NodeManager* nodeManager,
135
                                                   TNode n,
136
                                                   bool check)
137
{
138
5
  if (check)
139
  {
140
10
    TypeNode t1 = n[0].getType(check);
141
5
    if (!t1.isBoolean())
142
    {
143
      throw TypeCheckingExceptionPrivate(
144
          n, "expecting boolean term as first argument");
145
    }
146
10
    TypeNode t2 = n[1].getType(check);
147
5
    if (!t2.isReal())
148
    {
149
      throw TypeCheckingExceptionPrivate(
150
          n, "expecting polynomial as second argument");
151
    }
152
  }
153
5
  return nodeManager->booleanType();
154
}
155
156
}  // namespace arith
157
}  // namespace theory
158
27735
}  // namespace cvc5