GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/omt/omt_optimizer.cpp Lines: 7 69 10.1 %
Date: 2021-05-22 Branches: 12 604 2.0 %

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