1)Making naiveencoder and encoding graph use tuner 2)Adding timeout to the sat solver...
[satune.git] / src / ASTAnalyses / Encoding / subgraph.cc
index 69fb36743a872e66eec1932604988fa79a10263d..de76e4d0e6890d149fd703795f3713dc455ad3be 100644 (file)
@@ -1,10 +1,17 @@
 #include "subgraph.h"
 #include "encodinggraph.h"
 #include "set.h"
+#include "qsort.h"
 
 EncodingSubGraph::EncodingSubGraph() :
        encodingSize(0),
-       numElements(0) {
+       numElements(0),
+       maxEncodingVal(0) {
+}
+
+EncodingSubGraph::~EncodingSubGraph() {
+       map.resetAndDeleteKeys();
+       values.resetAndDelete();
 }
 
 uint hashNodeValuePair(NodeValuePair *nvp) {
@@ -15,12 +22,98 @@ bool equalsNodeValuePair(NodeValuePair *nvp1, NodeValuePair *nvp2) {
        return nvp1->value == nvp2->value && nvp1->node == nvp2->node;
 }
 
+int sortEncodingValue(const void *p1, const void *p2) {
+       const EncodingValue *e1 = *(const EncodingValue **) p1;
+       const EncodingValue *e2 = *(const EncodingValue **) p2;
+       uint se1 = e1->notequals.getSize();
+       uint se2 = e2->notequals.getSize();
+       if (se1 > se2)
+               return -1;
+       else if (se2 == se1)
+               return 0;
+       else
+               return 1;
+}
+
+uint EncodingSubGraph::getEncoding(EncodingNode *n, uint64_t val) {
+       NodeValuePair nvp(n, val);
+       EncodingValue *ev = map.get(&nvp);
+       return ev->encoding;
+}
+
+void EncodingSubGraph::solveEquals() {
+       Vector<EncodingValue *> toEncode;
+       Vector<bool> encodingArray;
+       SetIteratorEncodingValue *valIt = values.iterator();
+       while (valIt->hasNext()) {
+               EncodingValue *ev = valIt->next();
+               if (!ev->inComparison)
+                       toEncode.push(ev);
+               else
+                       ev->assigned = true;
+       }
+       delete valIt;
+       bsdqsort(toEncode.expose(), toEncode.getSize(), sizeof(EncodingValue *), sortEncodingValue);
+       uint toEncodeSize = toEncode.getSize();
+       for (uint i = 0; i < toEncodeSize; i++) {
+               EncodingValue *ev = toEncode.get(i);
+               encodingArray.clear();
+               SetIteratorEncodingValue *conflictIt = ev->notequals.iterator();
+               while (conflictIt->hasNext()) {
+                       EncodingValue *conflict = conflictIt->next();
+                       if (conflict->assigned) {
+                               encodingArray.setExpand(conflict->encoding, true);
+                       }
+               }
+               delete conflictIt;
+               uint encoding = 0;
+               for (; encoding < encodingArray.getSize(); encoding++) {
+                       //See if this is unassigned
+                       if (!encodingArray.get(encoding))
+                               break;
+               }
+               if (encoding > maxEncodingVal)
+                       maxEncodingVal = encoding;
+               ev->encoding = encoding;
+               ev->assigned = true;
+       }
+}
+
+void EncodingSubGraph::solveComparisons() {
+       HashsetEncodingValue discovered;
+       Vector<EncodingValue *> tovisit;
+       SetIteratorEncodingValue *valIt = values.iterator();
+       while (valIt->hasNext()) {
+               EncodingValue *ev = valIt->next();
+               if (discovered.add(ev)) {
+                       tovisit.push(ev);
+                       while (tovisit.getSize() != 0) {
+                               EncodingValue *val = tovisit.last(); tovisit.pop();
+                               SetIteratorEncodingValue *nextIt = val->larger.iterator();
+                               uint minVal = val->encoding + 1;
+                               while (nextIt->hasNext()) {
+                                       EncodingValue *nextVal = nextIt->next();
+                                       if (nextVal->encoding < minVal) {
+                                               if (minVal > maxEncodingVal)
+                                                       maxEncodingVal = minVal;
+                                               nextVal->encoding = minVal;
+                                               discovered.add(nextVal);
+                                               tovisit.push(nextVal);
+                                       }
+                               }
+                               delete nextIt;
+                       }
+               }
+       }
+       delete valIt;
+}
+
 uint EncodingSubGraph::estimateNewSize(EncodingSubGraph *sg) {
-       uint newSize=0;
-       SetIteratorEncodingNode * nit = sg->nodes.iterator();
-       while(nit->hasNext()) {
+       uint newSize = 0;
+       SetIteratorEncodingNode *nit = sg->nodes.iterator();
+       while (nit->hasNext()) {
                EncodingNode *en = nit->next();
-               uint size=estimateNewSize(en);
+               uint size = estimateNewSize(en);
                if (size > newSize)
                        newSize = size;
        }
@@ -28,11 +121,63 @@ uint EncodingSubGraph::estimateNewSize(EncodingSubGraph *sg) {
        return newSize;
 }
 
+double EncodingSubGraph::measureSimilarity(EncodingNode *node) {
+       uint common = 0;
+       Hashset64Int intSet;
+       SetIteratorEncodingNode *nit = nodes.iterator();
+       while (nit->hasNext()) {
+               EncodingNode *en = nit->next();
+               for(uint i=0; i < en->getSize(); i++){
+                       intSet.add(en->getIndex(i));
+               }
+       }
+       for(uint i=0; i < node->getSize(); i++){
+               if(intSet.contains( node->getIndex(i) )){
+                       common++;
+               }
+       }
+//     model_print("measureSimilarity:139: common=%u\t GraphSize=%u\tnodeSize=%u\tGraphSim=%f\tnodeSim=%f\n", common, intSet.getSize(), node->getSize(), 1.0*common/intSet.getSize(), 1.0*common/node->getSize());
+       delete nit;
+       return common*1.0/intSet.getSize() + common*1.0/node->getSize();
+}
+
+double EncodingSubGraph::measureSimilarity(EncodingSubGraph *sg) {
+       uint common = 0;
+       Hashset64Int set1;
+       Hashset64Int set2;
+       SetIteratorEncodingNode *nit = nodes.iterator();
+       while (nit->hasNext()) {
+               EncodingNode *en = nit->next();
+               for(uint i=0; i < en->getSize(); i++){
+                       set1.add(en->getIndex(i));
+               }
+       }
+       delete nit;
+       nit = sg->nodes.iterator();
+       while (nit->hasNext()) {
+               EncodingNode *en = nit->next();
+               for(uint i=0; i < en->getSize(); i++){
+                       set2.add(en->getIndex(i));
+               }
+       }
+       delete nit;
+       SetIterator64Int *setIter1 = set1.iterator();
+       while(setIter1->hasNext()){
+               uint64_t item1 = setIter1->next();
+               if( set2.contains(item1)){
+                       common++;
+               }
+       }
+       delete setIter1;
+//     model_print("measureSimilarity:139: common=%u\tGraphSize1=%u\tGraphSize2=%u\tGraphSize1=%f\tGraphSize2=%f\n", common, set1.getSize(), set2.getSize(), 1.0*common/set1.getSize(), 1.0*common/set2.getSize());
+       return common*1.0/set1.getSize() + common*1.0/set2.getSize();
+}
+
 uint EncodingSubGraph::estimateNewSize(EncodingNode *n) {
-       SetIteratorEncodingEdge * eeit = n->edges.iterator();
-       uint newsize=n->getSize();
-       while(eeit->hasNext()) {
-               EncodingEdge * ee = eeit->next();
+       SetIteratorEncodingEdge *eeit = n->edges.iterator();
+       uint newsize = n->getSize();
+       while (eeit->hasNext()) {
+               EncodingEdge *ee = eeit->next();
                if (ee->left != NULL && ee->left != n && nodes.contains(ee->left)) {
                        uint intersectSize = n->s->getUnionSize(ee->left->s);
                        if (intersectSize > newsize)
@@ -55,28 +200,63 @@ uint EncodingSubGraph::estimateNewSize(EncodingNode *n) {
 
 void EncodingSubGraph::addNode(EncodingNode *n) {
        nodes.add(n);
-       uint newSize=estimateNewSize(n);
+       uint newSize = estimateNewSize(n);
        numElements += n->elements.getSize();
        if (newSize > encodingSize)
-               encodingSize=newSize;
+               encodingSize = newSize;
 }
 
-SetIteratorEncodingNode * EncodingSubGraph::nodeIterator() {
+SetIteratorEncodingNode *EncodingSubGraph::nodeIterator() {
        return nodes.iterator();
 }
 
 void EncodingSubGraph::encode() {
        computeEncodingValue();
-       computeInequalities();
+       computeComparisons();
+       computeEqualities();
+       solveComparisons();
+       solveEquals();
 }
 
-void EncodingSubGraph::computeInequalities() {
-       SetIteratorEncodingNode *nodeit=nodes.iterator();
-       while(nodeit->hasNext()) {
-               EncodingNode *node=nodeit->next();
-               SetIteratorEncodingEdge *edgeit=node->edges.iterator();
-               while(edgeit->hasNext()) {
-                       EncodingEdge *edge=edgeit->next();
+void EncodingSubGraph::computeEqualities() {
+       SetIteratorEncodingNode *nodeit = nodes.iterator();
+       while (nodeit->hasNext()) {
+               EncodingNode *node = nodeit->next();
+               generateEquals(node, node);
+
+               SetIteratorEncodingEdge *edgeit = node->edges.iterator();
+               while (edgeit->hasNext()) {
+                       EncodingEdge *edge = edgeit->next();
+                       //skip over comparisons as we have already handled them
+                       if (edge->numComparisons != 0)
+                               continue;
+                       if (edge->numEquals == 0)
+                               continue;
+                       if (edge->left == NULL || !nodes.contains(edge->left))
+                               continue;
+                       if (edge->right == NULL || !nodes.contains(edge->right))
+                               continue;
+                       //examine only once
+                       if (edge->left != node)
+                               continue;
+                       //We have a comparison edge between two nodes in the subgraph
+                       //For now we don't support multiple encoding values with the same encoding....
+                       //So we enforce != constraints for every Set...
+                       if (edge->left != edge->right)
+                               generateEquals(edge->left, edge->right);
+               }
+               delete edgeit;
+       }
+       delete nodeit;
+}
+
+void EncodingSubGraph::computeComparisons() {
+       SetIteratorEncodingNode *nodeit = nodes.iterator();
+       while (nodeit->hasNext()) {
+               EncodingNode *node = nodeit->next();
+               SetIteratorEncodingEdge *edgeit = node->edges.iterator();
+               while (edgeit->hasNext()) {
+                       EncodingEdge *edge = edgeit->next();
                        if (edge->numComparisons == 0)
                                continue;
                        if (edge->left == NULL || !nodes.contains(edge->left))
@@ -94,35 +274,70 @@ void EncodingSubGraph::computeInequalities() {
        delete nodeit;
 }
 
+void EncodingSubGraph::orderEV(EncodingValue *earlier, EncodingValue *later) {
+       earlier->larger.add(later);
+}
+
+void EncodingSubGraph::generateEquals(EncodingNode *left, EncodingNode *right) {
+       Set *lset = left->s;
+       Set *rset = right->s;
+       uint lSize = lset->getSize(), rSize = rset->getSize();
+       for (uint lindex = 0; lindex < lSize; lindex++) {
+               for (uint rindex = 0; rindex < rSize; rindex++) {
+                       uint64_t lVal = lset->getElement(lindex);
+                       NodeValuePair nvp1(left, lVal);
+                       EncodingValue *lev = map.get(&nvp1);
+                       uint64_t rVal = rset->getElement(rindex);
+                       NodeValuePair nvp2(right, rVal);
+                       EncodingValue *rev = map.get(&nvp2);
+                       if (lev != rev) {
+                               if (lev->inComparison && rev->inComparison) {
+                                       //Need to assign during comparison stage...
+                                       //Thus promote to comparison
+                                       if (lVal < rVal) {
+                                               orderEV(lev, rev);
+                                       } else {
+                                               orderEV(rev, lev);
+                                       }
+                               } else {
+                                       lev->notequals.add(rev);
+                                       rev->notequals.add(lev);
+                               }
+                       }
+               }
+       }
+}
+
 void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *right) {
-       Set *lset=left->s;
-       Set *rset=right->s;
-       uint lindex=0, rindex=0;
-       uint lSize=lset->getSize(), rSize=rset->getSize();
-       uint64_t lVal=lset->getElement(lindex);
+       Set *lset = left->s;
+       Set *rset = right->s;
+       uint lindex = 0, rindex = 0;
+       uint lSize = lset->getSize(), rSize = rset->getSize();
+       uint64_t lVal = lset->getElement(lindex);
        NodeValuePair nvp1(left, lVal);
        EncodingValue *lev = map.get(&nvp1);
        lev->inComparison = true;
-       uint64_t rVal=rset->getElement(rindex);
+       uint64_t rVal = rset->getElement(rindex);
        NodeValuePair nvp2(right, rVal);
        EncodingValue *rev = map.get(&nvp2);
        rev->inComparison = true;
        EncodingValue *last = NULL;
 
-       while(lindex < lSize || rindex < rSize) {
+       while (lindex < lSize || rindex < rSize) {
                if (last != NULL) {
                        if (lev != NULL)
-                               last->larger.push(lev);
+                               orderEV(last, lev);
                        if (rev != NULL && lev != rev)
-                               last->larger.push(rev);
+                               orderEV(last, rev);
                }
                if (lev != rev) {
-                       if (rev == NULL || lVal < rVal) {
+                       if (rev == NULL ||
+                                       (lev != NULL && lVal < rVal)) {
                                if (rev != NULL)
-                                       lev->larger.push(rev);
+                                       orderEV(lev, rev);
                                last = lev;
                                if (++lindex < lSize) {
-                                       lVal=lset->getElement(lindex);
+                                       lVal = lset->getElement(lindex);
                                        NodeValuePair nvpl(left, lVal);
                                        lev = map.get(&nvpl);
                                        lev->inComparison = true;
@@ -130,10 +345,10 @@ void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *righ
                                        lev = NULL;
                        } else {
                                if (lev != NULL)
-                                       rev->larger.push(lev);
+                                       orderEV(rev, lev);
                                last = rev;
                                if (++rindex < rSize) {
-                                       rVal=rset->getElement(rindex);
+                                       rVal = rset->getElement(rindex);
                                        NodeValuePair nvpr(right, rVal);
                                        rev = map.get(&nvpr);
                                        rev->inComparison = true;
@@ -143,7 +358,7 @@ void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *righ
                } else {
                        last = lev;
                        if (++lindex < lSize) {
-                               lVal=lset->getElement(lindex);
+                               lVal = lset->getElement(lindex);
                                NodeValuePair nvpl(left, lVal);
                                lev = map.get(&nvpl);
                                lev->inComparison = true;
@@ -151,7 +366,7 @@ void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *righ
                                lev = NULL;
 
                        if (++rindex < rSize) {
-                               rVal=rset->getElement(rindex);
+                               rVal = rset->getElement(rindex);
                                NodeValuePair nvpr(right, rVal);
                                rev = map.get(&nvpr);
                                rev->inComparison = true;
@@ -162,12 +377,12 @@ void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *righ
 }
 
 void EncodingSubGraph::computeEncodingValue() {
-       SetIteratorEncodingNode *nodeit=nodes.iterator();
-       while(nodeit->hasNext()) {
-               EncodingNode *node=nodeit->next();
-               Set * set = node->s;
+       SetIteratorEncodingNode *nodeit = nodes.iterator();
+       while (nodeit->hasNext()) {
+               EncodingNode *node = nodeit->next();
+               Set *set = node->s;
                uint setSize = set->getSize();
-               for(uint i=0; i<setSize; i++) {
+               for (uint i = 0; i < setSize; i++) {
                        uint64_t val = set->getElement(i);
                        NodeValuePair nvp(node, val);
                        if (!map.contains(&nvp)) {
@@ -179,20 +394,21 @@ void EncodingSubGraph::computeEncodingValue() {
 }
 
 void EncodingSubGraph::traverseValue(EncodingNode *node, uint64_t value) {
-       EncodingValue *ecv=new EncodingValue(value);
+       EncodingValue *ecv = new EncodingValue(value);
+       values.add(ecv);
        HashsetEncodingNode discovered;
        Vector<EncodingNode *> tovisit;
        tovisit.push(node);
        discovered.add(node);
-       while(tovisit.getSize()!=0) {
-               EncodingNode *n=tovisit.last();tovisit.pop();
+       while (tovisit.getSize() != 0) {
+               EncodingNode *n = tovisit.last();tovisit.pop();
                //Add encoding node to structures
                ecv->nodes.add(n);
-               NodeValuePair *nvp=new NodeValuePair(n, value);
+               NodeValuePair *nvp = new NodeValuePair(n, value);
                map.put(nvp, ecv);
-               SetIteratorEncodingEdge *edgeit=node->edges.iterator();
-               while(edgeit->hasNext()) {
-                       EncodingEdge *ee=edgeit->next();
+               SetIteratorEncodingEdge *edgeit = n->edges.iterator();
+               while (edgeit->hasNext()) {
+                       EncodingEdge *ee = edgeit->next();
                        if (!discovered.contains(ee->left) && nodes.contains(ee->left) && ee->left->s->exists(value)) {
                                tovisit.push(ee->left);
                                discovered.add(ee->left);