Branch data Line data Source code
1 : : /******************************************************************************
2 : : * Top contributors (to current version):
3 : : * Andrew Reynolds, Aina Niemetz, Mathias Preiner
4 : : *
5 : : * This file is part of the cvc5 project.
6 : : *
7 : : * Copyright (c) 2009-2024 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 : : * Inverse rules for bit-vector operators.
14 : : */
15 : :
16 : : #include "cvc5_private.h"
17 : :
18 : : #ifndef CVC5__BV_INVERTER_H
19 : : #define CVC5__BV_INVERTER_H
20 : :
21 : : #include <map>
22 : : #include <unordered_map>
23 : : #include <unordered_set>
24 : : #include <vector>
25 : :
26 : : #include "expr/node.h"
27 : :
28 : : namespace cvc5::internal {
29 : :
30 : : class Options;
31 : :
32 : : namespace theory {
33 : :
34 : : class Rewriter;
35 : :
36 : : namespace quantifiers {
37 : :
38 : : /** BvInverterQuery
39 : : *
40 : : * This is a virtual class for queries
41 : : * required by the BvInverter class.
42 : : */
43 : : class BvInverterQuery
44 : : {
45 : : public:
46 : 4149 : BvInverterQuery() {}
47 : 4149 : virtual ~BvInverterQuery() {}
48 : : /** returns the current model value of n */
49 : : virtual Node getModelValue(Node n) = 0;
50 : : /** returns a bound variable of type tn */
51 : : virtual Node getBoundVariable(TypeNode tn) = 0;
52 : : };
53 : :
54 : : // inverter class
55 : : // TODO : move to theory/bv/ if generally useful?
56 : : class BvInverter
57 : : {
58 : : public:
59 : : BvInverter(const Options& opts, Rewriter* r = nullptr);
60 : 37233 : ~BvInverter() {}
61 : : /** get dummy fresh variable of type tn, used as argument for sv */
62 : : Node getSolveVariable(TypeNode tn);
63 : :
64 : : /**
65 : : * Get path to pv in lit, replace that occurrence by sv and all others by
66 : : * pvs (if pvs is non-null). If return value R is non-null, then :
67 : : * lit.path = pv R.path = sv
68 : : * R.path' = pvs for all lit.path' = pv, where path' != path
69 : : *
70 : : * If the flag projectNl is false, we return the null node if the
71 : : * literal lit is non-linear with respect to pv.
72 : : */
73 : : Node getPathToPv(Node lit,
74 : : Node pv,
75 : : Node sv,
76 : : Node pvs,
77 : : std::vector<unsigned>& path,
78 : : bool projectNl);
79 : :
80 : : /**
81 : : * Same as above, but does not linearize lit for pv.
82 : : * Use this version if we know lit is linear wrt pv.
83 : : */
84 : 2007 : Node getPathToPv(Node lit, Node pv, std::vector<unsigned>& path)
85 : : {
86 : 2007 : return getPathToPv(lit, pv, pv, Node::null(), path, false);
87 : : }
88 : :
89 : : /** solveBvLit
90 : : *
91 : : * Solve for sv in lit, where lit.path = sv. If this function returns a
92 : : * non-null node t, then sv = t is the solved form of lit.
93 : : *
94 : : * If the BvInverterQuery provided to this function call is null, then
95 : : * the solution returned by this call will not contain WITNESS expressions.
96 : : * If the solved form for lit requires introducing a WITNESS expression,
97 : : * then this call will return null.
98 : : */
99 : : Node solveBvLit(Node sv,
100 : : Node lit,
101 : : std::vector<unsigned>& path,
102 : : BvInverterQuery* m);
103 : :
104 : : private:
105 : : /** Helper function for getPathToPv */
106 : : Node getPathToPv(Node lit,
107 : : Node pv,
108 : : Node sv,
109 : : std::vector<unsigned>& path,
110 : : std::unordered_set<TNode>& visited);
111 : :
112 : : /** Helper function for getInv.
113 : : *
114 : : * This expects a condition cond where:
115 : : * (exists x. cond)
116 : : * is a BV tautology where x is getSolveVariable( tn ).
117 : : *
118 : : * It returns a term of the form:
119 : : * (witness y. cond { x -> y })
120 : : * where y is a bound variable and x is getSolveVariable( tn ).
121 : : *
122 : : * In some cases, we may return a term t if cond implies an equality on
123 : : * the solve variable. For example, if cond is x = t where x is
124 : : * getSolveVariable(tn), then we return t instead of introducing the choice
125 : : * function.
126 : : *
127 : : * This function will return the null node if the BvInverterQuery m provided
128 : : * to this call is null.
129 : : */
130 : : Node getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m);
131 : : /** Reference to options */
132 : : const Options& d_opts;
133 : : /** (Optional) rewriter used as helper in getInversionNode */
134 : : Rewriter* d_rewriter;
135 : : /** Dummy variables for each type */
136 : : std::map<TypeNode, Node> d_solve_var;
137 : : };
138 : :
139 : : } // namespace quantifiers
140 : : } // namespace theory
141 : : } // namespace cvc5::internal
142 : :
143 : : #endif /* CVC5__BV_INVERTER_H */
|