GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/cegqi/ceg_bv_instantiator.h Lines: 3 3 100.0 %
Date: 2021-05-22 Branches: 1 2 50.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Tim King, Mathias Preiner
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
 * ceg_bv_instantiator
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__QUANTIFIERS__CEG_BV_INSTANTIATOR_H
19
#define CVC5__THEORY__QUANTIFIERS__CEG_BV_INSTANTIATOR_H
20
21
#include <unordered_map>
22
#include "theory/quantifiers/bv_inverter.h"
23
#include "theory/quantifiers/cegqi/ceg_instantiator.h"
24
25
namespace cvc5 {
26
namespace theory {
27
namespace quantifiers {
28
29
/** Bitvector instantiator
30
 *
31
 * This implements an approach for counterexample-guided instantiation
32
 * for bit-vector variables based on word-level inversions. For details,
33
 * see Niemetz et al, "Solving Quantified Bit-Vectors Using Invertibility
34
 * Conditions", CAV 2018. It is enabled by --cbqi-bv.
35
 *
36
 * This class contains all necessary information for instantiating a single
37
 * bit-vector variable of a single quantified formula.
38
 */
39
class BvInstantiator : public Instantiator
40
{
41
 public:
42
  BvInstantiator(TypeNode tn, BvInverter* inv);
43
  ~BvInstantiator() override;
44
  /** reset */
45
  void reset(CegInstantiator* ci,
46
             SolvedForm& sf,
47
             Node pv,
48
             CegInstEffort effort) override;
49
  /** this instantiator processes assertions */
50
  bool hasProcessAssertion(CegInstantiator* ci,
51
                           SolvedForm& sf,
52
                           Node pv,
53
                           CegInstEffort effort) override;
54
  /** this instantiator processes bit-vector equalities and inequalities
55
   *
56
   * Based on the configuration --cbqi-bv-ineq, it may modify the form of lit
57
   * based on a projection. For lit (not) s <> t, this may be one of:
58
   * - eq-slack: s = t + ( s^M - t^M )
59
   * - eq-boundary: s = t + ( s^M > t^M ? 1 : -1 )
60
   * - keep: (not) s <> t, i.e. unchanged.
61
   * Additionally for eq-boundary, inequalities s != t become s < t or t < s.
62
   * This is the method project_* from Figure 3 of Niemetz et al, CAV 2018.
63
   */
64
  Node hasProcessAssertion(CegInstantiator* ci,
65
                           SolvedForm& sf,
66
                           Node pv,
67
                           Node lit,
68
                           CegInstEffort effort) override;
69
  /** process assertion
70
   *
71
   * Computes a solved form for pv in lit based on Figure 1 of Niemetz et al,
72
   * CAV 2018.
73
   */
74
  bool processAssertion(CegInstantiator* ci,
75
                        SolvedForm& sf,
76
                        Node pv,
77
                        Node lit,
78
                        Node alit,
79
                        CegInstEffort effort) override;
80
  /** process assertions
81
   *
82
   * This is called after processAssertion has been called on all currently
83
   * asserted literals that involve pv. This chooses the best solved form for pv
84
   * based on heuristics. Currently, by default, we choose a random solved form.
85
   * We may try multiple or zero bounds based on the options
86
   * --cbqi-multi-inst and --cbqi-bv-interleave-value.
87
   */
88
  bool processAssertions(CegInstantiator* ci,
89
                         SolvedForm& sf,
90
                         Node pv,
91
                         CegInstEffort effort) override;
92
  /** use model value
93
   *
94
   * We allow model values if we have not already tried an assertion,
95
   * and only at levels below full if cbqiFullEffort is false.
96
   */
97
  bool useModelValue(CegInstantiator* ci,
98
                     SolvedForm& sf,
99
                     Node pv,
100
                     CegInstEffort effort) override;
101
  /** identify */
102
3483
  std::string identify() const override { return "Bv"; }
103
104
 private:
105
  /** pointer to the bv inverter class */
106
  BvInverter* d_inverter;
107
  //--------------------------------solved forms
108
  /** identifier counter, used to allocate ids to each solve form */
109
  unsigned d_inst_id_counter;
110
  /** map from variables to list of solved form ids */
111
  std::unordered_map<Node, std::vector<unsigned>> d_var_to_inst_id;
112
  /** for each solved form id, the term for instantiation */
113
  std::unordered_map<unsigned, Node> d_inst_id_to_term;
114
  /** for each solved form id, the corresponding asserted literal */
115
  std::unordered_map<unsigned, Node> d_inst_id_to_alit;
116
  /** map from variable to current id we are processing */
117
  std::unordered_map<Node, unsigned> d_var_to_curr_inst_id;
118
  /** the amount of slack we added for asserted literals */
119
  std::unordered_map<Node, Node> d_alit_to_model_slack;
120
  //--------------------------------end solved forms
121
  /** rewrite assertion for solve pv
122
   *
123
   * Returns a literal that is equivalent to lit that leads to best solved form
124
   * for pv.
125
   */
126
  Node rewriteAssertionForSolvePv(CegInstantiator* ci, Node pv, Node lit);
127
  /** rewrite term for solve pv
128
   *
129
   * This is a helper function for rewriteAssertionForSolvePv.
130
   * If this returns non-null value ret, then this indicates
131
   * that n should be rewritten to ret. It is called as
132
   * a "post-rewrite", that is, after the children of n
133
   * have been rewritten and stored in the vector children.
134
   *
135
   * contains_pv stores whether certain nodes contain pv.
136
   * where we guarantee that all subterms of terms in children
137
   * appear in the domain of contains_pv.
138
   */
139
  Node rewriteTermForSolvePv(Node pv,
140
                             Node n,
141
                             std::vector<Node>& children,
142
                             std::unordered_map<Node, bool>& contains_pv);
143
  /** process literal, called from processAssertion
144
   *
145
   * lit is the literal to solve for pv that has been rewritten according to
146
   * internal rules here.
147
   * alit is the asserted literal that lit is derived from.
148
   */
149
  void processLiteral(CegInstantiator* ci,
150
                      SolvedForm& sf,
151
                      Node pv,
152
                      Node lit,
153
                      Node alit,
154
                      CegInstEffort effort);
155
};
156
157
/** Bitvector instantiator preprocess
158
 *
159
 * This class implements preprocess techniques that are helpful for
160
 * counterexample-guided instantiation, such as introducing variables
161
 * that refer to disjoint bit-vector extracts.
162
 */
163
class BvInstantiatorPreprocess : public InstantiatorPreprocess
164
{
165
 public:
166
706
  BvInstantiatorPreprocess() {}
167
1412
  ~BvInstantiatorPreprocess() override {}
168
  /** register counterexample lemma
169
   *
170
   * This method adds to auxLems based on the extract terms that lem
171
   * contains when the option --cbqi-bv-rm-extract is enabled. It introduces
172
   * a dummy equality so that segments of terms t under extracts can be solved
173
   * independently.
174
   *
175
   * For example, if lem is:
176
   *   P[ ((extract 7 4) t), ((extract 3 0) t)]
177
   *     then we add:
178
   *   t = concat( x74, x30 )
179
   * to auxLems, where x74 and x30 are fresh variables of type BV_4, which are
180
   * added to ceVars.
181
   *
182
   * Another example, for:
183
   *   P[ ((extract 7 3) t), ((extract 4 0) t)]
184
   *     we add:
185
   *   t = concat( x75, x44, x30 )
186
   * to auxLems where x75, x44 and x30 are fresh variables of type BV_3, BV_1,
187
   * and BV_4 respectively, which are added to ceVars.
188
   *
189
   * Notice we leave the original lem alone. This is done for performance
190
   * since the added equalities ensure we are able to construct the proper
191
   * solved forms for variables in t and for the intermediate variables above.
192
   */
193
  void registerCounterexampleLemma(Node lem,
194
                                   std::vector<Node>& ceVars,
195
                                   std::vector<Node>& auxLems) override;
196
197
 private:
198
  /** collect extracts
199
   *
200
   * This method collects all extract terms in lem
201
   * and stores them in d_extract_map.
202
   * visited is the terms we've already visited.
203
   */
204
  void collectExtracts(Node lem,
205
                       std::map<Node, std::vector<Node>>& extract_map,
206
                       std::unordered_set<TNode>& visited);
207
};
208
209
}  // namespace quantifiers
210
}  // namespace theory
211
}  // namespace cvc5
212
213
#endif /* CVC5__THEORY__QUANTIFIERS__CEG_BV_INSTANTIATOR_H */