1 /********************************************************************
2  * AUTHORS: Trevor Hansen
3  *
4  * BEGIN DATE: Feb, 2010
5  *
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 ********************************************************************/
24 
25 #include "stp/ToSat/AIG/ToCNFAIG.h"
26 
27 namespace stp
28 {
29 
30 // Can it only add in the new variables somehow??
addVariables(BBNodeManagerAIG & mgr,Cnf_Dat_t * & cnfData,ToSATBase::ASTNodeToSATVar & nodeToVars)31 void addVariables(BBNodeManagerAIG& mgr, Cnf_Dat_t*& cnfData,
32                   ToSATBase::ASTNodeToSATVar& nodeToVars)
33 {
34   BBNodeManagerAIG::SymbolToBBNode::const_iterator it;
35   // Each symbol maps to a vector of CNF variables.
36   for (it = mgr.symbolToBBNode.begin(); it != mgr.symbolToBBNode.end(); it++)
37   {
38     const ASTNode& n = it->first;
39     const vector<BBNodeAIG>& b = it->second;
40 
41     const int width = (n.GetType() == BOOLEAN_TYPE) ? 1 : n.GetValueWidth();
42 
43     // INT_MAX for parts of symbols that didn't get encoded.
44     vector<unsigned> v(width, ~((unsigned)0));
45 
46     for (unsigned i = 0; i < b.size(); i++)
47     {
48       if (!b[i].IsNull())
49       {
50         Aig_Obj_t* pObj;
51         pObj = (Aig_Obj_t*)Vec_PtrEntry(mgr.aigMgr->vPis, b[i].symbol_index);
52         v[i] = cnfData->pVarNums[pObj->Id];
53       }
54     }
55     nodeToVars.insert(make_pair(n, v));
56   }
57 }
58 
dag_aware_aig_rewrite(const bool needAbsRef,BBNodeManagerAIG & mgr)59 void ToCNFAIG::dag_aware_aig_rewrite(const bool needAbsRef,
60                                      BBNodeManagerAIG& mgr)
61 {
62   const int nodeCount = mgr.aigMgr->nObjs[AIG_OBJ_AND];
63 
64   if (!needAbsRef && uf.enable_AIG_rewrites_flag)
65   {
66     Dar_LibStart();
67     Dar_RwrPar_t Pars, *pPars = &Pars;
68     Dar_ManDefaultRwrParams(pPars);
69 
70     // Assertion errors occur with this enabled.
71     // pPars->fUseZeros = 1;
72 
73     // For mul63bit.smt2 with iterations =3 & nCutsMax = 8
74     // CNF generation was taking 139 seconds, solving 10 seconds.
75 
76     // With nCutsMax =2, CNF generation takes 16 seconds, solving 10 seconds.
77     // The rewriting doesn't remove as many nodes of course..
78     const int iterations = 3;
79 
80     for (int i = 0; i < iterations; i++)
81     {
82       Aig_Man_t* pTemp;
83       mgr.aigMgr = Aig_ManDup(pTemp = mgr.aigMgr, 0);
84       Aig_ManStop(pTemp);
85       Dar_ManRewrite(mgr.aigMgr, pPars);
86 
87       mgr.aigMgr = Aig_ManDup(pTemp = mgr.aigMgr, 0);
88       Aig_ManStop(pTemp);
89 
90       if (uf.stats_flag)
91         cerr << "After rewrite [" << i
92              << "]  nodes:" << mgr.aigMgr->nObjs[AIG_OBJ_AND] << endl;
93 
94       //Fixedpoint reached?
95       if (nodeCount == mgr.aigMgr->nObjs[AIG_OBJ_AND])
96         break;
97     }
98   }
99 }
100 
toCNF(const BBNodeAIG & top,Cnf_Dat_t * & cnfData,ToSATBase::ASTNodeToSATVar & nodeToVars,bool needAbsRef,BBNodeManagerAIG & mgr)101 void ToCNFAIG::toCNF(const BBNodeAIG& top, Cnf_Dat_t*& cnfData,
102                      ToSATBase::ASTNodeToSATVar& nodeToVars, bool needAbsRef,
103                      BBNodeManagerAIG& mgr)
104 {
105   assert(cnfData == NULL);
106 
107   Aig_ObjCreatePo(mgr.aigMgr, top.n);
108   if (!needAbsRef)
109   {
110     Aig_ManCleanup(mgr.aigMgr); // remove nodes not connected to the PO.
111   }
112   assert(Aig_ManCheck(mgr.aigMgr)); // check that AIG looks ok.
113 
114   assert(Aig_ManPoNum(mgr.aigMgr) == 1);
115 
116   // UseZeroes gives assertion errors.
117   // Rewriting is sometimes very slow. Can it be configured to be faster?
118   // What about refactoring???
119 
120   if (uf.stats_flag)
121   {
122     cerr << "Nodes before AIG rewrite:" << mgr.aigMgr->nObjs[AIG_OBJ_AND]
123          << endl;
124   }
125 
126   dag_aware_aig_rewrite(needAbsRef, mgr);
127 
128   if (!uf.simple_cnf)
129   {
130     cnfData = Cnf_Derive(mgr.aigMgr, 0);
131     if (uf.stats_flag)
132       cerr << "advanced CNF" << endl;
133   }
134   else
135   {
136     cnfData = Cnf_DeriveSimple(mgr.aigMgr, 0);
137     if (uf.stats_flag)
138       cerr << "simple CNF" << endl;
139   }
140   assert(cnfData != NULL);
141 
142   fill_node_to_var(cnfData, nodeToVars, mgr);
143 }
144 
fill_node_to_var(Cnf_Dat_t * cnfData,ToSATBase::ASTNodeToSATVar & nodeToVars,BBNodeManagerAIG & mgr)145 void ToCNFAIG::fill_node_to_var(Cnf_Dat_t* cnfData,
146                                 ToSATBase::ASTNodeToSATVar& nodeToVars,
147                                 BBNodeManagerAIG& mgr)
148 {
149   BBNodeManagerAIG::SymbolToBBNode::const_iterator it;
150   assert(nodeToVars.size() == 0);
151 
152   // todo. cf. with addvariables above...
153   // Each symbol maps to a vector of CNF variables.
154   for (it = mgr.symbolToBBNode.begin(); it != mgr.symbolToBBNode.end(); it++)
155   {
156     const ASTNode& n = it->first;
157     const vector<BBNodeAIG>& b = it->second;
158     assert(nodeToVars.find(n) == nodeToVars.end());
159 
160     const int width = (n.GetType() == BOOLEAN_TYPE) ? 1 : n.GetValueWidth();
161 
162     // INT_MAX for parts of symbols that didn't get encoded.
163     vector<unsigned> v(width, ~((unsigned)0));
164 
165     for (unsigned i = 0; i < b.size(); i++)
166     {
167       if (!b[i].IsNull())
168       {
169         Aig_Obj_t* pObj;
170         pObj = (Aig_Obj_t*)Vec_PtrEntry(mgr.aigMgr->vPis, b[i].symbol_index);
171         v[i] = cnfData->pVarNums[pObj->Id];
172       }
173     }
174 
175     nodeToVars.insert(make_pair(n, v));
176   }
177 }
178 }
179