1 package org.sat4j.sat.visu;
2
3 import java.awt.Color;
4 import java.io.BufferedReader;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStreamReader;
8 import java.io.PrintStream;
9
10 import org.sat4j.minisat.core.ICDCLLogger;
11
12 public class GnuplotBasedSolverVisualisation implements SolverVisualisation {
13
14 private VisuPreferences visuPreferences;
15 private int nVar;
16 private Process gnuplotProcess;
17 private String dataPath;
18 private ICDCLLogger logger;
19
20 public GnuplotBasedSolverVisualisation(VisuPreferences visuPref, int nbVar,
21 String path, ICDCLLogger logger) {
22 this.visuPreferences = visuPref;
23 this.nVar = nbVar;
24 this.dataPath = path;
25 this.logger = logger;
26 }
27
28 public void start() {
29 traceGnuplot();
30 }
31
32 public void end() {
33 stopGnuplot();
34 }
35
36 public void traceGnuplot() {
37
38 if (this.gnuplotProcess == null) {
39 try {
40
41 double verybottom = 0.0;
42 double bottom = 0.33;
43 double top = 0.66;
44 double left = 0.0;
45 double middle = 0.33;
46 double right = 0.66;
47
48 double width = 0.33;
49 double height = 0.33;
50
51 PrintStream out = new PrintStream(new FileOutputStream(
52 this.dataPath + "-gnuplot.gnuplot"));
53 out.println("set terminal x11");
54 out.println("set multiplot");
55 out.println("set autoscale x");
56 out.println("set autoscale y");
57 out.println("set nologscale x");
58 out.println("set nologscale y");
59 out.println("set ytics auto");
60
61 GnuplotFunction f = new GnuplotFunction("2", Color.black, "");
62
63
64 if (this.visuPreferences.isDisplayConflictsDecision()) {
65 out.println("set size " + width + "," + height);
66 out.println("set origin " + right + "," + bottom);
67 out.println("set title \"Decision level at which the conflict occurs\"");
68 out.println("set autoscale ymax");
69 out.println("set y2range [0:]");
70 GnuplotDataFile conflictLevelDF = new GnuplotDataFile(
71 this.dataPath + "-conflict-level.dat",
72 Color.magenta, "Conflict Level");
73 GnuplotDataFile conflictLevelRestartDF = new GnuplotDataFile(
74 this.dataPath + "-conflict-level-restart.dat",
75 Color.gray, "Restart", "impulses");
76 GnuplotDataFile conflictLevelCleanDF = new GnuplotDataFile(
77 this.dataPath + "-conflict-level-clean.dat",
78 Color.orange, "Clean", "impulses");
79
80
81 out.println(this.visuPreferences
82 .generatePlotLineOnDifferenteAxes(
83 new GnuplotDataFile[] { conflictLevelDF },
84 new GnuplotDataFile[] {
85 conflictLevelRestartDF,
86 conflictLevelCleanDF }, true));
87
88
89 }
90
91
92 if (this.visuPreferences.isDisplayClausesSize()) {
93 out.println("unset autoscale");
94 out.println("set autoscale x");
95 out.println("set autoscale ymax");
96 out.println("set y2range [0:]");
97
98
99
100
101 out.println("set size " + width + "," + height);
102 out.println("set origin " + left + "," + top);
103 out.println("set title \"Size of the clause learned (after minimization if any)\"");
104 GnuplotDataFile learnedClausesDF = new GnuplotDataFile(
105 this.dataPath + "-learned-clauses-size.dat",
106 Color.blue, "Size");
107 GnuplotDataFile learnedClausesRestartDF = new GnuplotDataFile(
108 this.dataPath + "-learned-clauses-size-restart.dat",
109 Color.gray, "Restart", "impulses");
110 GnuplotDataFile learnedClausesCleanDF = new GnuplotDataFile(
111 this.dataPath + "-learned-clauses-size-clean.dat",
112 Color.orange, "Clean", "impulses");
113
114
115 out.println(this.visuPreferences
116 .generatePlotLineOnDifferenteAxes(
117 new GnuplotDataFile[] { learnedClausesDF },
118 new GnuplotDataFile[] {
119 learnedClausesCleanDF,
120 learnedClausesRestartDF }, true));
121 }
122
123
124 if (this.visuPreferences.isDisplayConflictsDecision()) {
125 out.println("set autoscale x");
126 out.println("set autoscale y");
127 out.println("set size " + width + "," + height);
128 out.println("set origin " + middle + "," + top);
129 out.println("set title \"Value of learned clauses evaluation\"");
130 GnuplotDataFile learnedDF = new GnuplotDataFile(
131 this.dataPath + "-learned.dat", Color.blue,
132 "Evaluation");
133 out.println(this.visuPreferences.generatePlotLine(
134 learnedDF, f, "", false));
135 }
136
137
138 out.println("set autoscale x");
139 out.println("set nologscale x");
140 out.println("set nologscale y");
141 out.println("set autoscale y");
142 out.println("set yrange [1:" + this.nVar + "]");
143 out.println("set ytics add (1," + this.nVar + ")");
144
145
146 if (this.visuPreferences.isDisplayDecisionIndexes()) {
147 out.println("unset autoscale");
148 out.println("if(system(\"head "
149 + this.dataPath
150 + "-decision-indexes-pos.dat | wc -l\")!=0){set autoscale x;}");
151 out.println("if(system(\"head "
152 + this.dataPath
153 + "-decision-indexes-pos.dat | wc -l\")!=0){set yrange [1:"
154 + this.nVar + "]};");
155
156
157 out.println("set size " + width + "," + height);
158 out.println("set origin " + left + "," + bottom);
159 out.println("set title \"Index of the decision variables\"");
160 GnuplotDataFile negativeDF = new GnuplotDataFile(
161 this.dataPath + "-decision-indexes-neg.dat",
162 Color.red, "Negative Decision");
163 GnuplotDataFile decisionRestartDF = new GnuplotDataFile(
164 this.dataPath + "-decision-indexes-restart.dat",
165 Color.gray, "Restart", "impulses");
166 GnuplotDataFile decisionCleanDF = new GnuplotDataFile(
167 this.dataPath + "-decision-indexes-clean.dat",
168 Color.orange, "Clean", "impulses");
169
170
171 out.println(this.visuPreferences
172 .generatePlotLineOnDifferenteAxes(
173 new GnuplotDataFile[] { negativeDF },
174 new GnuplotDataFile[] { decisionRestartDF,
175 decisionCleanDF }, true,
176 this.visuPreferences.getNbLinesRead() * 4));
177
178
179
180
181
182 out.println("unset autoscale");
183 out.println("if(system(\"head "
184 + this.dataPath
185 + "-decision-indexes-pos.dat | wc -l\")!=0){set autoscale x;set yrange [1:"
186 + this.nVar + "]; set y2range [0:]; }");
187
188
189
190
191
192
193 out.println("set size " + width + "," + height);
194 out.println("set origin " + left + "," + verybottom);
195 out.println("set title \"Index of the decision variables\"");
196 GnuplotDataFile positiveDF = new GnuplotDataFile(
197 this.dataPath + "-decision-indexes-pos.dat",
198 Color.green, "Positive Decision");
199
200
201
202
203
204 out.println(this.visuPreferences
205 .generatePlotLineOnDifferenteAxes(
206 new GnuplotDataFile[] { positiveDF },
207 new GnuplotDataFile[] { decisionRestartDF,
208 decisionCleanDF }, true,
209 this.visuPreferences.getNbLinesRead() * 4));
210 }
211
212
213 if (this.visuPreferences.isDisplayConflictsTrail()) {
214 out.println("set autoscale x");
215 out.println("set autoscale y");
216 out.println("set nologscale x");
217 out.println("set nologscale y");
218 out.println("set size " + width + "," + height);
219 out.println("set origin " + right + "," + top);
220 out.println("set title \"Trail level when the conflict occurs\"");
221 out.println("set y2range [0:]");
222 GnuplotDataFile trailLevelDF = new GnuplotDataFile(
223 this.dataPath + "-conflict-depth.dat",
224 Color.magenta, "Trail level");
225 GnuplotFunction nbVar2 = new GnuplotFunction("" + this.nVar
226 / 2, Color.green, "#Var/2");
227 GnuplotDataFile trailLevelRestartDF = new GnuplotDataFile(
228 this.dataPath + "-conflict-depth-restart.dat",
229 Color.gray, "Restart", "impulses");
230 GnuplotDataFile trailLevelCleanDF = new GnuplotDataFile(
231 this.dataPath + "-conflict-depth-clean.dat",
232 Color.orange, "Clean", "impulses");
233
234 out.println(this.visuPreferences
235 .generatePlotLineOnDifferenteAxes(
236 new GnuplotDataFile[] { trailLevelDF },
237 new GnuplotDataFile[] {
238 trailLevelRestartDF,
239 trailLevelCleanDF },
240 new GnuplotFunction[] { nbVar2 }, true));
241 out.println(this.visuPreferences.generatePlotLine(
242 trailLevelDF, nbVar2, this.dataPath
243 + "-conflict-level-restart.dat", true));
244 }
245
246
247 if (this.visuPreferences.isDisplayVariablesEvaluation()) {
248 out.println("unset autoscale");
249 out.println("set autoscale y");
250 out.println("set nologscale x");
251 out.println("set nologscale y");
252 out.println("set yrange [1:" + this.nVar + "]");
253 out.println("set xrange [0.5:*]");
254 out.println("set size " + width + "," + height);
255 out.println("set origin " + middle + "," + bottom);
256 out.println("set title \"Value of variables activity\"");
257 GnuplotDataFile heuristicsDF = new GnuplotDataFile(
258 this.dataPath + "-heuristics.dat", Color.red,
259 "Activity", "lines");
260 out.println(this.visuPreferences.generatePlotLine(
261 heuristicsDF, f, "", false));
262 }
263
264
265
266 if (this.visuPreferences.isDisplaySpeed()) {
267 out.println("set autoscale x");
268 out.println("set nologscale x");
269 out.println("set nologscale y");
270 out.println("set size " + width + "," + height);
271 out.println("set origin " + middle + "," + verybottom);
272 out.println("set title \"Number of propagations per second\"");
273 out.println("set y2range [0:]");
274 GnuplotDataFile speedDF = new GnuplotDataFile(this.dataPath
275 + "-speed.dat", Color.cyan, "Speed", "lines");
276 GnuplotDataFile cleanDF = new GnuplotDataFile(this.dataPath
277 + "-speed-clean.dat", Color.orange, "Clean",
278 "impulses");
279 GnuplotDataFile restartDF = new GnuplotDataFile(
280 this.dataPath + "-speed-restart.dat", Color.gray,
281 "Restart", "impulses");
282 out.println(this.visuPreferences
283 .generatePlotLineOnDifferenteAxes(
284 new GnuplotDataFile[] { speedDF },
285 new GnuplotDataFile[] { cleanDF, restartDF },
286 true, 50));
287 }
288 out.println("unset multiplot");
289 double pauseTime = this.visuPreferences.getRefreshTime() / 1000;
290 out.println("pause " + pauseTime);
291 out.println("reread");
292 out.close();
293
294 this.logger.log("Gnuplot will start in a few seconds.");
295
296 Thread errorStreamThread = new Thread() {
297 @Override
298 public void run() {
299
300 try {
301 try {
302 Thread.sleep(GnuplotBasedSolverVisualisation.this.visuPreferences
303 .getTimeBeforeLaunching());
304 } catch (InterruptedException e) {
305 e.printStackTrace();
306 }
307
308 GnuplotBasedSolverVisualisation.this.logger
309 .log("reads "
310 + GnuplotBasedSolverVisualisation.this.dataPath
311 + "-gnuplot.gnuplot");
312 GnuplotBasedSolverVisualisation.this.gnuplotProcess = Runtime
313 .getRuntime()
314 .exec(GnuplotBasedSolverVisualisation.this.visuPreferences
315 .createCommandLine(GnuplotBasedSolverVisualisation.this.dataPath
316 + "-gnuplot.gnuplot"));
317
318 GnuplotBasedSolverVisualisation.this.logger
319 .log("Gnuplot should have started now.");
320
321 BufferedReader gnuInt = new BufferedReader(
322 new InputStreamReader(
323 GnuplotBasedSolverVisualisation.this.gnuplotProcess
324 .getErrorStream()));
325 String s;
326
327 while ((s = gnuInt.readLine()) != null) {
328 if (s.trim().length() > 0
329 && !s.toLowerCase().contains("warning")
330 && !s.toLowerCase().contains("plot")) {
331 System.out.println(s);
332 }
333 }
334 } catch (IOException e) {
335 e.printStackTrace();
336 }
337 }
338 };
339 errorStreamThread.start();
340
341 } catch (IOException e) {
342 e.printStackTrace();
343 }
344 }
345 }
346
347 public void stopGnuplot() {
348 if (this.gnuplotProcess != null) {
349 this.gnuplotProcess.destroy();
350 this.logger.log("Gnuplot should be deactivated...");
351 }
352 this.gnuplotProcess = null;
353 }
354
355 public void setnVar(int n) {
356 this.nVar = n;
357 }
358
359 }