View Javadoc

1   /*******************************************************************************
2    * SAT4J: a SATisfiability library for Java Copyright (C) 2004-2008 Daniel Le Berre
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the Eclipse Public License v1.0
6    * which accompanies this distribution, and is available at
7    * http://www.eclipse.org/legal/epl-v10.html
8    *
9    * Alternatively, the contents of this file may be used under the terms of
10   * either the GNU Lesser General Public License Version 2.1 or later (the
11   * "LGPL"), in which case the provisions of the LGPL are applicable instead
12   * of those above. If you wish to allow use of your version of this file only
13   * under the terms of the LGPL, and not to allow others to use your version of
14   * this file under the terms of the EPL, indicate your decision by deleting
15   * the provisions above and replace them with the notice and other provisions
16   * required by the LGPL. If you do not delete the provisions above, a recipient
17   * may use your version of this file under the terms of the EPL or the LGPL.
18   * 
19   * Based on the original MiniSat specification from:
20   * 
21   * An extensible SAT solver. Niklas Een and Niklas Sorensson. Proceedings of the
22   * Sixth International Conference on Theory and Applications of Satisfiability
23   * Testing, LNCS 2919, pp 502-518, 2003.
24   *
25   * See www.minisat.se for the original solver in C++.
26   * 
27   *******************************************************************************/
28  package org.sat4j.tools;
29  
30  import java.io.FileWriter;
31  import java.io.IOException;
32  import java.io.ObjectInputStream;
33  import java.io.PrintWriter;
34  import java.io.Writer;
35  import java.util.Map;
36  
37  import org.sat4j.core.Vec;
38  import org.sat4j.specs.IConstr;
39  import org.sat4j.specs.Lbool;
40  import org.sat4j.specs.SearchListener;
41  
42  /**
43   * Class allowing to express the search as a tree in the dot language. The
44   * resulting file can be viewed in a tool like <a
45   * href="http://www.graphviz.org/">Graphviz</a>
46   * 
47   * To use only on small benchmarks.
48   * 
49   * Note that also does not make sense to use such a listener on a distributed or
50   * remote solver.
51   * 
52   * @author daniel
53   * @since 2.2
54   */
55  public class DotSearchTracing<T> implements SearchListener {
56  
57  	/**
58       * 
59       */
60  	private static final long serialVersionUID = 1L;
61  
62  	private final Vec<String> pile;
63  
64  	private String currentNodeName = null;
65  
66  	private transient Writer out;
67  
68  	private boolean estOrange = false;
69  
70  	private final Map<Integer, T> mapping;
71  
72  	/**
73  	 * @since 2.1
74  	 */
75  	public DotSearchTracing(final String fileNameToSave, Map<Integer, T> mapping) {
76  		pile = new Vec<String>();
77  		this.mapping = mapping;
78  		try {
79  			out = new FileWriter(fileNameToSave);
80  		} catch (IOException e) {
81  			System.err.println("Problem when created file.");
82  		}
83  	}
84  
85  	private String node(int dimacs) {
86  		if (mapping != null) {
87  			int var = Math.abs(dimacs);
88  			T t = mapping.get(var);
89  			if (t != null) {
90  				if (dimacs > 0)
91  					return t.toString();
92  				return "-" + t.toString();
93  			}
94  		}
95  		return Integer.toString(dimacs);
96  	}
97  
98  	public final void assuming(final int p) {
99  		final int absP = Math.abs(p);
100 		String newName;
101 
102 		if (currentNodeName == null) {
103 			newName = "" + absP;
104 			pile.push(newName);
105 			saveLine(lineTab("\"" + newName + "\"" + "[label=\"" + node(p)
106 					+ "\", shape=circle, color=blue, style=filled]"));
107 		} else {
108 			newName = currentNodeName;
109 			pile.push(newName);
110 			saveLine(lineTab("\"" + newName + "\"" + "[label=\"" + node(p)
111 					+ "\", shape=circle, color=blue, style=filled]"));
112 		}
113 		currentNodeName = newName;
114 	}
115 
116 	/**
117 	 * @since 2.1
118 	 */
119 	public final void propagating(final int p, IConstr reason) {
120 		String newName = currentNodeName + "." + p;
121 
122 		if (currentNodeName == null) {
123 			saveLine(lineTab("\"null\" [label=\"\", shape=point]"));
124 		}
125 		final String couleur = estOrange ? "orange" : "green";
126 
127 		saveLine(lineTab("\"" + newName + "\"" + "[label=\"" + node(p)
128 				+ "\",shape=point, color=black]"));
129 		saveLine(lineTab("\"" + currentNodeName + "\"" + " -- " + "\""
130 				+ newName + "\"" + "[label=" + "\" " + node(p)
131 				+ "\", fontcolor =" + couleur + ", color = " + couleur
132 				+ ", style = bold]"));
133 		currentNodeName = newName;
134 		estOrange = false;
135 	}
136 
137 	public final void backtracking(final int p) {
138 		final String temp = pile.last();
139 		pile.pop();
140 		saveLine("\"" + temp + "\"" + "--" + "\"" + currentNodeName + "\""
141 				+ "[label=\"\", color=red, style=dotted]");
142 		currentNodeName = temp;
143 	}
144 
145 	public final void adding(final int p) {
146 		estOrange = true;
147 	}
148 
149 	/**
150 	 * @since 2.1
151 	 */
152 	public final void learn(final IConstr clause) {
153 	}
154 
155 	public final void delete(final int[] clause) {
156 	}
157 
158 	/**
159 	 * @since 2.1
160 	 */
161 	public final void conflictFound(IConstr confl, int dlevel, int trailLevel) {
162 		saveLine(lineTab("\"" + currentNodeName
163 				+ "\" [label=\"\", shape=box, color=\"red\", style=filled]"));
164 	}
165 
166 	/**
167 	 * @since 2.1
168 	 */
169 	public final void conflictFound(int p) {
170 		saveLine(lineTab("\"" + currentNodeName
171 				+ "\" [label=\"\", shape=box, color=\"red\", style=filled]"));
172 	}
173 
174 	public final void solutionFound() {
175 		saveLine(lineTab("\"" + currentNodeName
176 				+ "\" [label=\"\", shape=box, color=\"green\", style=filled]"));
177 	}
178 
179 	public final void beginLoop() {
180 	}
181 
182 	public final void start() {
183 		saveLine("graph G {");
184 	}
185 
186 	/**
187 	 * @since 2.1
188 	 */
189 	public final void end(Lbool result) {
190 		saveLine("}");
191 	}
192 
193 	private final String lineTab(final String line) {
194 		return "\t" + line;
195 	}
196 
197 	private final void saveLine(final String line) {
198 		try {
199 			out.write(line + '\n');
200 			if ("}".equals(line)) {
201 				out.close();
202 			}
203 		} catch (IOException e) {
204 			e.printStackTrace();
205 		}
206 	}
207 
208 	private void readObject(ObjectInputStream stream) throws IOException,
209 			ClassNotFoundException {
210 		// if the solver is serialized, out is linked to stdout
211 		stream.defaultReadObject();
212 		out = new PrintWriter(System.out);
213 	}
214 
215 	public void restarting() {
216 		// DLB add support for restarts on the graphs.
217 	}
218 
219 	public void backjump(int backjumpLevel) {
220 	}
221 }