00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #ifndef BOOLEANABSTRACTOR_H_
00009 #define BOOLEANABSTRACTOR_H_
00010 
00011 #include <map>
00012 using namespace std;
00013 
00014 
00015 class CNode;
00016 class Leaf;
00017 class BooleanVar;
00018 
00019 
00020 #include "CNF.h"
00021 #include "SatSolver.h"
00022 #include "Term.h"
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 class BooleanAbstractor {
00031 
00032 private:
00033 
00034         CNode* original;
00035 
00036         enum edge_op
00037         {
00038                 EDGEOP_NOOP = 0,
00039                 EDGEOP_EQ = 1,
00040                 EDGEOP_NEQ = 2,
00041                 EDGEOP_LT = 4,
00042                 EDGEOP_LEQ = 8
00043         };
00044 
00045         struct edge;
00046         struct node;
00047 
00048         struct node
00049         {
00050                 Term* t;
00051                 set<edge*> outgoing_edges;
00052                 set<edge*> incoming_edges;
00053 
00054                 node(Term* t)
00055                 {
00056                         this->t = t;
00057                 }
00058 
00059                 string to_string()
00060                 {
00061                         return t->to_string();
00062                 }
00063         };
00064 
00065         struct edge
00066         {
00067                 node* source;
00068                 node* target;
00069                 edge_op op;
00070 
00071                 edge(node* source, node* target, edge_op op)
00072                 {
00073                         this->source = source;
00074                         this->target = target;
00075                         this->op = op;
00076                         source->outgoing_edges.insert(this);
00077                         target->incoming_edges.insert(this);
00078                 }
00079 
00080                 string to_string()
00081                 {
00082                         return source->t->to_string() + " -> " + target->t->to_string();
00083 
00084                 }
00085 
00086                 string to_string(edge_op op)
00087                 {
00088                         string op_string = "";
00089                         if(op == EDGEOP_LT) op_string = "<";
00090                         else if(op == EDGEOP_LEQ) op_string = "<=";
00091                         else if(op == EDGEOP_EQ) op_string = "=";
00092                         else op_string = "!=";
00093                         return source->t->to_string() + op_string + target->t->to_string();
00094 
00095                 }
00096 
00097                 ~edge()
00098                 {
00099                         source->outgoing_edges.erase(this);
00100                         target->incoming_edges.erase(this);
00101                 }
00102 
00103         };
00104 
00105         map<Term*, node*> term_to_node_map;
00106 
00107         
00108 
00109 
00110 
00111 
00112         set<node*> frontier_nodes;
00113 
00114         
00115 
00116 
00117 
00118         set<edge*> relation_graph;
00119 
00120         
00121 
00122 
00123 
00124         set<Term*> used_constants;
00125         map<pair<node*, node*>, edge*> edge_matrix;
00126 
00127         
00128 
00129 
00130         set<CNode*> literals;
00131 
00132         
00133 
00134 
00135         set<CNode*> valid_implications;
00136 
00137         
00138 
00139 
00140         CNode* learned;
00141 
00142 
00143         int max_implications;
00144 
00145 
00146 public:
00147         BooleanAbstractor(CNode* node);
00148         CNode* get_learned_implications();
00149         ~BooleanAbstractor();
00150 
00151 private:
00152         node* get_node_from_term(Term* t);
00153         void build_relation_graph();
00154         void add_edge(Term* source, Term* target, edge_op op,
00155                         bool add_used_constant = true);
00156         void add_edge(node* source, node* target, edge_op op,
00157                         set<edge*>* added_edges = NULL);
00158         string relation_graph_to_dotty();
00159 
00160         bool is_frontier_node(node* n);
00161         bool is_frontier_node(node* n, set<edge*> & processed_edges);
00162 
00163         void add_initial_frontier_nodes();
00164 
00165         
00166 
00167 
00168 
00169 
00170 
00171         void add_basic_implications();
00172 
00173         
00174 
00175 
00176 
00177 
00178 
00179         void add_constant_relations();
00180 
00181         
00182 
00183 
00184 
00185 
00186         void add_implication(CNode* prec, CNode* concl);
00187 
00188 
00189 
00190         
00191 
00192 
00193 
00194         void make_chordal();
00195 
00196         
00197 
00198 
00199 
00200         void wire_edge(edge* in, edge* out, set<edge*>& processed_edges);
00201 
00202         
00203 
00204 
00205 
00206         void add_implications();
00207 
00208         
00209 
00210 
00211         inline bool edge_between(node* n1, node* n2);
00212 
00213 
00214         
00215 
00216 
00217         bool deduce_lt(edge_op op1, edge_op op2);
00218 
00219         
00220 
00221 
00222         bool deduce_leq(edge_op op1, edge_op op2);
00223 
00224         
00225 
00226 
00227         bool deduce_eq(edge_op op1, edge_op op2);
00228 
00229         
00230 
00231 
00232 
00233         bool deduce_op(edge_op op1, edge_op op2, edge_op ded_op);
00234 
00235         
00236 
00237 
00238         bool is_relevant_deduction(node* source, node* target, edge_op op);
00239 
00240         
00241 
00242 
00243         void add_implication(edge* e1, edge* e2, CNode* deduction, edge_op op);
00244 
00245         
00246 
00247 
00248         CNode* edge_to_literal(edge* e, edge_op op);
00249 
00250 };
00251 
00252 #endif