forked from DrorFried/Synthesis-via-Decomposition
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAlgorithm.hpp
187 lines (153 loc) · 5.77 KB
/
Algorithm.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#pragma once
#include "Set.hpp"
#include "Vector.hpp"
#include "CNFFormula.hpp"
#include "MFSGenerator.hpp"
#include "MSSGenerator.hpp"
#include "Printing.hpp"
#include "Model.hpp"
#include <stdexcept>
/**
* Computes a new MSS covering a not-yet-covered MFS, and stored the MSS in the model.
* - componentId: Identifier for the component the MSS will be associated with.
* - mfsGen: MFS generator.
* - mssGen: MSS generator.
* - model: Function being synthesized, keeps track of the components and MSS associated with it. New MSS will be stored here.
*/
bool computeAndStoreNextMSS(size_t componentId,
MFSGenerator& mfsGen,
MSSGenerator& mssGen,
Model& model)
{
/*
* Generate an MFS (represented as a set of indicator variables) that
* has not been covered yet, or nothing if all MFS have been covered.
*/
Optional<Set<BVar>> mfs = mfsGen.newMFS();
if (!mfs)
{
return false; /*< no MFS left, indicate that enumeration has finished */
}
else
{
#if MYDEBUG >=2
printf("Printing MFS:");
print(*mfs, "x");
printf("\n");
#endif
/* Generate an new MSS covering the MFS */
Optional<Set<BVar>> mss = mssGen.newMSSCovering(*mfs);
if (!mss)
{
/* This branch will never be reached if the specification is realizable */
throw std::invalid_argument("Specification is unrealizable!");
}
else
{
#if MYDEBUG >=2
printf("Printing MSS:");
print(*mss, "z");
printf("\n");
#endif
model.addMSS(componentId, *mss);
mfsGen.blockMSS(*mss);
return true; /*< continue searching for maximal cliques */
}
};
}
/**
* Back-and-forth synthesis algorithm. Assumes specification is realizable.
* Input: F1 (specification from X to Z of the form e.g. (z_1 <-> ~(x_1 | ~x_2 | x_3)) & ...
* F2 (specification from Z to Y of the form e.g. (z_1 -> (~y_1 | ~y_2 | y_3)) & ...
* Output: List of sets representing assignments to the Z and Y variables, such that
* given the assignment to the Zs, the assignment to the Ys satisfies F2.
*/
Model BAFAlgorithm(const TrivialSpec& f1, const MSSSpec& f2)
{
/* Graph where every MIS corresponds to an MFS of F1 */
Graph<size_t> conflictGraph = f1.conflictGraph();
const Vector<BVar>& indicatorVars = f2.indicatorVars();
const Vector<CNFClause>& outputClauses = f2.outputCNF().clauses();
/* Set of all indicator variables */
Set<BVar> allIndicatorVars(indicatorVars.begin(), indicatorVars.end());
/* Initialize maximal-clique generator with graph and callback */
MFSGenerator mfsGen(allIndicatorVars, indicatorVars, conflictGraph);
/* Initialize MSS generator */
MSSGenerator mssGen(allIndicatorVars, indicatorVars, outputClauses);
/* Representation of the synthesized function */
Model model;
/* Since we are not decomposing specification into connected components,
* there is a single component composed of all indicator variables.*/
size_t componentId = model.addComponent(allIndicatorVars);
/* Repeat while there are still MSS to be computed */
while (computeAndStoreNextMSS(componentId, mfsGen, mssGen, model)) {}
#if MYDEBUG >=2 //printing the remaining of the mss
printf("No more mfs to cover, printing the remaining mss:\n");
Optional<Set<BVar>> mss;
mss = mssGen.newMSS();
while (mss)
{
printf("Printing MSS:");
print(*mss, "z");
printf("\n");
mss = mssGen.newMSS();
}
#endif
printf("No more mss\n");
return model;
}
/**
* Version of BAFAlgorithm that first decomposes specification into connected components. This method over-runs BAFAlgorithm,
*/
Model BAFConnectedComponents(const TrivialSpec& f1, const MSSSpec& f2)
{
/* Graph where every MIS corresponds to an MFS of F1 */
Graph<size_t> conflictGraph = f1.conflictGraph();
const Vector<BVar>& indicatorVars = f2.indicatorVars();
const CNFFormula& outputCNF = f2.outputCNF();
/* Representation of the synthesized function */
Model model;
Vector<Set<size_t>> connectedComponents = outputCNF.dualGraph().connectedComponents();
for (const Set<size_t>& indices : connectedComponents)
{
#if MYDEBUG
// printf("Printing Connected Component:\n");
//print(indices);
#endif
/* Restrict indicator variables, output clauses and cliques graph to the indices in the connected component */
Vector<BVar> subIndicatorVars = subsequence(indicatorVars, indices);
Vector<CNFClause> subOutputClauses = subsequence(outputCNF.clauses(), indices);
Graph<size_t> conflictSubgraph = conflictGraph.subgraph(indices);
#if MYDEBUG >=2
printf("**************************************************************************************\n");
printf("Printing graph components:\n");
print(subIndicatorVars, "z");
printf("\n");
print(subOutputClauses, "y");
#endif
/* Set of all indicator variables in the component */
Set<BVar> relevantIndicators(subIndicatorVars.begin(), subIndicatorVars.end());
/* Add connected component to model and get an identifier for it.
* Identifier will be used to associate an MSS with this component. */
size_t componentId = model.addComponent(relevantIndicators);
/* Initialize maximal-clique generator with graph and callback */
MFSGenerator mfsGen(relevantIndicators, indicatorVars, conflictSubgraph);
/* Initialize MSS generator */
MSSGenerator mssGen(relevantIndicators, subIndicatorVars, subOutputClauses);
/* Repeat while there are still MSS to be computed */
while (computeAndStoreNextMSS(componentId, mfsGen, mssGen, model)) {}
#if MYDEBUG >=2 //printing the remaining of the mss
printf("No more mfs to cover, printing the remaining mss:\n");
Optional<Set<BVar>> mss;
mss = mssGen.newMSS();
while (mss)
{
printf("Printing MSS:");
print(*mss, "z");
printf("\n");
mss = mssGen.newMSS();
}
#endif
}
return model;
}