GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/omt/omt_optimizer.cpp Lines: 34 74 45.9 %
Date: 2021-09-18 Branches: 60 630 9.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Yancheng Ou, Aina Niemetz
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
 * The base class for optimizers of individual cvc5 type.
14
 */
15
16
#include "omt/omt_optimizer.h"
17
18
#include "omt/bitvector_optimizer.h"
19
#include "omt/integer_optimizer.h"
20
21
using namespace cvc5::theory;
22
using namespace cvc5::smt;
23
namespace cvc5::omt {
24
25
40
bool OMTOptimizer::nodeSupportsOptimization(TNode node)
26
{
27
80
  TypeNode type = node.getType();
28
  // only supports Integer and BitVectors as of now
29
80
  return (type.isInteger() || type.isBitVector());
30
}
31
32
38
std::unique_ptr<OMTOptimizer> OMTOptimizer::getOptimizerForObjective(
33
    const OptimizationObjective& objective)
34
{
35
  // the datatype of the target node
36
76
  TypeNode objectiveType = objective.getTarget().getType(true);
37
38
  if (objectiveType.isInteger())
38
  {
39
    // integer type: use OMTOptimizerInteger
40
8
    return std::unique_ptr<OMTOptimizer>(new OMTOptimizerInteger());
41
  }
42
30
  else if (objectiveType.isBitVector())
43
  {
44
    // bitvector type: use OMTOptimizerBitVector
45
    return std::unique_ptr<OMTOptimizer>(
46
30
        new OMTOptimizerBitVector(objective.bvIsSigned()));
47
  }
48
  else
49
  {
50
    Unimplemented() << "Target type " << objectiveType
51
                    << " does not support optimization";
52
  }
53
}
54
55
24
Node OMTOptimizer::mkStrongIncrementalExpression(
56
    NodeManager* nm,
57
    TNode lhs,
58
    TNode rhs,
59
    const OptimizationObjective& objective)
60
{
61
24
  constexpr const char lhsTypeError[] =
62
      "lhs type does not match or is not implicitly convertable to the target "
63
      "type";
64
24
  constexpr const char rhsTypeError[] =
65
      "rhs type does not match or is not implicitly convertable to the target "
66
      "type";
67
48
  TypeNode targetType = objective.getTarget().getType();
68
24
  switch (objective.getType())
69
  {
70
    case OptimizationObjective::MINIMIZE:
71
    {
72
      if (targetType.isInteger())
73
      {
74
        Assert(lhs.getType().isInteger()) << lhsTypeError;
75
        Assert(rhs.getType().isInteger()) << rhsTypeError;
76
        return nm->mkNode(Kind::LT, lhs, rhs);
77
      }
78
      else if (targetType.isBitVector())
79
      {
80
        Assert(lhs.getType() == targetType) << lhsTypeError;
81
        Assert(rhs.getType() == targetType) << rhsTypeError;
82
        return (objective.bvIsSigned())
83
                   ? (nm->mkNode(Kind::BITVECTOR_SLT, lhs, rhs))
84
                   : (nm->mkNode(Kind::BITVECTOR_ULT, lhs, rhs));
85
      }
86
      else
87
      {
88
        Unimplemented() << "Target type " << targetType
89
                        << " does not support optimization";
90
      }
91
    }
92
24
    case OptimizationObjective::MAXIMIZE:
93
    {
94
24
      if (targetType.isInteger())
95
      {
96
        Assert(lhs.getType().isInteger()) << lhsTypeError;
97
        Assert(rhs.getType().isInteger()) << rhsTypeError;
98
        return nm->mkNode(Kind::GT, lhs, rhs);
99
      }
100
24
      else if (targetType.isBitVector())
101
      {
102
24
        Assert(lhs.getType() == targetType) << lhsTypeError;
103
24
        Assert(rhs.getType() == targetType) << rhsTypeError;
104
24
        return (objective.bvIsSigned())
105
                   ? (nm->mkNode(Kind::BITVECTOR_SGT, lhs, rhs))
106
24
                   : (nm->mkNode(Kind::BITVECTOR_UGT, lhs, rhs));
107
      }
108
      else
109
      {
110
        Unimplemented() << "Target type " << targetType
111
                        << " does not support optimization";
112
      }
113
    }
114
    default:
115
      CVC5_FATAL() << "Optimization objective is neither MAXIMIZE nor MINIMIZE";
116
  }
117
  Unreachable();
118
}
119
120
24
Node OMTOptimizer::mkWeakIncrementalExpression(
121
    NodeManager* nm,
122
    TNode lhs,
123
    TNode rhs,
124
    const OptimizationObjective& objective)
125
{
126
24
  constexpr const char lhsTypeError[] =
127
      "lhs type does not match or is not implicitly convertable to the target "
128
      "type";
129
24
  constexpr const char rhsTypeError[] =
130
      "rhs type does not match or is not implicitly convertable to the target "
131
      "type";
132
48
  TypeNode targetType = objective.getTarget().getType();
133
24
  switch (objective.getType())
134
  {
135
    case OptimizationObjective::MINIMIZE:
136
    {
137
      if (targetType.isInteger())
138
      {
139
        Assert(lhs.getType().isInteger()) << lhsTypeError;
140
        Assert(rhs.getType().isInteger()) << rhsTypeError;
141
        return nm->mkNode(Kind::LEQ, lhs, rhs);
142
      }
143
      else if (targetType.isBitVector())
144
      {
145
        Assert(lhs.getType() == targetType) << lhsTypeError;
146
        Assert(rhs.getType() == targetType) << rhsTypeError;
147
        return (objective.bvIsSigned())
148
                   ? (nm->mkNode(Kind::BITVECTOR_SLE, lhs, rhs))
149
                   : (nm->mkNode(Kind::BITVECTOR_ULE, lhs, rhs));
150
      }
151
      else
152
      {
153
        Unimplemented() << "Target type " << targetType
154
                        << " does not support optimization";
155
      }
156
    }
157
24
    case OptimizationObjective::MAXIMIZE:
158
    {
159
24
      if (targetType.isInteger())
160
      {
161
        Assert(lhs.getType().isInteger()) << lhsTypeError;
162
        Assert(rhs.getType().isInteger()) << rhsTypeError;
163
        return nm->mkNode(Kind::GEQ, lhs, rhs);
164
      }
165
24
      else if (targetType.isBitVector())
166
      {
167
24
        Assert(lhs.getType() == targetType) << lhsTypeError;
168
24
        Assert(rhs.getType() == targetType) << rhsTypeError;
169
24
        return (objective.bvIsSigned())
170
                   ? (nm->mkNode(Kind::BITVECTOR_SGE, lhs, rhs))
171
24
                   : (nm->mkNode(Kind::BITVECTOR_UGE, lhs, rhs));
172
      }
173
      else
174
      {
175
        Unimplemented() << "Target type " << targetType
176
                        << " does not support optimization";
177
      }
178
    }
179
    default:
180
      CVC5_FATAL() << "Optimization objective is neither MAXIMIZE nor MINIMIZE";
181
  }
182
  Unreachable();
183
}
184
185
29574
}  // namespace cvc5::omt