1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Abdalrhman Mohamed |
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 |
|
* Utility class for Sygus Reconstruct module. |
14 |
|
*/ |
15 |
|
|
16 |
|
#include "cvc5_private.h" |
17 |
|
|
18 |
|
#ifndef CVC5__THEORY__QUANTIFIERS__RCONS_OBLIGATION_H |
19 |
|
#define CVC5__THEORY__QUANTIFIERS__RCONS_OBLIGATION_H |
20 |
|
|
21 |
|
#include "expr/node.h" |
22 |
|
|
23 |
|
namespace cvc5 { |
24 |
|
namespace theory { |
25 |
|
namespace quantifiers { |
26 |
|
|
27 |
|
/** |
28 |
|
* A class for holding Sygus Reconstruct obligations. An obligation is a builtin |
29 |
|
* term t and a SyGuS type T, and indicates that we are trying to build a term |
30 |
|
* of type T whose builtin analog is equivalent to t. This class encodes each |
31 |
|
* obligation (T, t) as a skolem k of type T to embed obligations in candidate |
32 |
|
* solutions (see d_candSols below). Notice that the SyGuS type T of an |
33 |
|
* obligation is not stored in this class as it can be inferred from the type of |
34 |
|
* the skolem k. |
35 |
|
*/ |
36 |
720 |
class RConsObligation |
37 |
|
{ |
38 |
|
public: |
39 |
|
/** |
40 |
|
* Constructor. Default value needed for maps. |
41 |
|
* |
42 |
|
* @param stn sygus datatype type to reconstruct `t` into |
43 |
|
* @param t builtin term to reconstruct |
44 |
|
*/ |
45 |
|
RConsObligation(TypeNode stn, Node t); |
46 |
|
|
47 |
|
/** |
48 |
|
* @return sygus datatype type to reconstruct equivalent builtin terms into |
49 |
|
*/ |
50 |
|
TypeNode getType() const; |
51 |
|
|
52 |
|
/** |
53 |
|
* @return skolem representing this obligation |
54 |
|
*/ |
55 |
|
Node getSkolem() const; |
56 |
|
|
57 |
|
/** |
58 |
|
* Add `t` to the set of equivalent builtins this obligation solves. |
59 |
|
* |
60 |
|
* \note `t` MUST be equivalent to the builtin terms in `d_ts` |
61 |
|
* |
62 |
|
* @param t builtin term to add |
63 |
|
*/ |
64 |
|
void addBuiltin(Node t); |
65 |
|
|
66 |
|
/** |
67 |
|
* @return equivalent builtin terms to reconstruct for this obligation |
68 |
|
*/ |
69 |
|
const std::unordered_set<Node>& getBuiltins() const; |
70 |
|
|
71 |
|
/** |
72 |
|
* Add candidate solution to the set of candidate solutions for the |
73 |
|
* corresponding obligation. |
74 |
|
* |
75 |
|
* @param candSol the candidate solution to add |
76 |
|
*/ |
77 |
|
void addCandidateSolution(Node candSol); |
78 |
|
|
79 |
|
/** |
80 |
|
* @return set of candidate solutions for this obligation |
81 |
|
*/ |
82 |
|
const std::unordered_set<Node>& getCandidateSolutions() const; |
83 |
|
|
84 |
|
/** |
85 |
|
* Add candidate solution to the set of candidate solutions waiting for the |
86 |
|
* corresponding obligation to be solved. |
87 |
|
* |
88 |
|
* @param candSol the candidate solution to add to watch set |
89 |
|
*/ |
90 |
|
void addCandidateSolutionToWatchSet(Node candSol); |
91 |
|
|
92 |
|
/** |
93 |
|
* @return set of candidate solutions waiting for this obligation to be solved |
94 |
|
*/ |
95 |
|
const std::unordered_set<Node>& getWatchSet() const; |
96 |
|
|
97 |
|
/** |
98 |
|
* Print all reachable obligations and their candidate solutions from |
99 |
|
* the `root` obligation and its candidate solutions. |
100 |
|
* |
101 |
|
* An obligation is reachable from the `root` obligation if it is the `root` |
102 |
|
* obligation or is needed by one of the candidate solutions of other |
103 |
|
* reachable obligations. |
104 |
|
* |
105 |
|
* For example, if we have: |
106 |
|
* |
107 |
|
* Obs = [(k1, {(+ 1 (- x))}, (k2, (- x)), (k3, x), (k4, 0)] |
108 |
|
* CandSols = {k1 -> {(c_+ c_1 k2)}, k2 -> {(c_- k3)}, |
109 |
|
* k3 -> {c_x}, k4 -> {c_0}} |
110 |
|
* root = k1 |
111 |
|
* |
112 |
|
* Then, the set of reachable obligations from `root` is {k1, k2, k3} |
113 |
|
* |
114 |
|
* \note requires enabling "sygus-rcons" trace |
115 |
|
* |
116 |
|
* @param root the root obligation to start from |
117 |
|
* @param obs a list of obligations containing at least 1 obligation |
118 |
|
* @param |
119 |
|
*/ |
120 |
|
static void printCandSols( |
121 |
|
const RConsObligation* root, |
122 |
|
const std::vector<std::unique_ptr<RConsObligation>>& obs); |
123 |
|
|
124 |
|
private: |
125 |
|
/** Skolem representing this obligation used to embed obligations in candidate |
126 |
|
* solutions. */ |
127 |
|
Node d_k; |
128 |
|
/** Equivalent builtin terms for this obligation. |
129 |
|
* |
130 |
|
* To solve the obligation, one of these builtin terms must be reconstructed |
131 |
|
* in the specified grammar (sygus datatype type) of the obligation. |
132 |
|
*/ |
133 |
|
std::unordered_set<Node> d_ts; |
134 |
|
/** A set of candidate solutions to this obligation. |
135 |
|
* |
136 |
|
* Each candidate solution is a sygus datatype term containing skolem subterms |
137 |
|
* (sub-obligations). By replacing all sub-obligations with their |
138 |
|
* corresponding solutions, we get a term whose builtin analog rewrites to |
139 |
|
* a term in `d_ts` and hence solves this obligation. For example, given: |
140 |
|
* d_ts = {(+ x y)} |
141 |
|
* a possible set of candidate solutions would be: |
142 |
|
* d_candSols = {(c_+ k1 k2), (c_+ c_x k2), (c_+ k1 c_y), (c_+ c_x c_y)} |
143 |
|
* where k1 and k2 are skolems. Notice that `d_candSols` may contain a |
144 |
|
* pure term that solves the obligation ((c_+ c_x c_y) in this example). |
145 |
|
*/ |
146 |
|
std::unordered_set<Node> d_candSols; |
147 |
|
/** A set of candidate solutions waiting for this obligation to be solved. |
148 |
|
* |
149 |
|
* In the example above, (c_+ k1 k2) and (c_+ c_x k2) are in the watch-set of |
150 |
|
* k2. Similarly, (c_+ k1 k2) and (c_+ k1 c_y) are in the watch-set of k1. |
151 |
|
*/ |
152 |
|
std::unordered_set<Node> d_watchSet; |
153 |
|
}; |
154 |
|
|
155 |
|
/** |
156 |
|
* Print obligation `ob` into the given output stream `out` |
157 |
|
* |
158 |
|
* @param out the output stream to print `ob` into |
159 |
|
* @param ob the obligation to print |
160 |
|
* @return a reference to the given output stream `out` |
161 |
|
*/ |
162 |
|
std::ostream& operator<<(std::ostream& out, const RConsObligation& ob); |
163 |
|
|
164 |
|
} // namespace quantifiers |
165 |
|
} // namespace theory |
166 |
|
} // namespace cvc5 |
167 |
|
|
168 |
|
#endif // CVC5__THEORY__QUANTIFIERS__RCONS_OBLIGATION_H |