}
case ELEMFUNCRETURN: {
ElementFunction *ef = (ElementFunction *) e;
- return ((uint)(uintptr_t) ef->function) ^
+ return ((uint)(uintptr_t) ef->getFunction()) ^
((uint)(uintptr_t) ef->overflowstatus) ^
hashArray(&ef->inputs);
}
case ELEMFUNCRETURN: {
ElementFunction *ef1 = (ElementFunction *) e1;
ElementFunction *ef2 = (ElementFunction *) e2;
- return (ef1->function == ef2->function) &&
+ return (ef1->getFunction() == ef2->getFunction()) &&
(ef1->overflowstatus == ef2->overflowstatus) &&
compareArray(&ef1->inputs, &ef2->inputs);
}
ElementFunction::ElementFunction(Function *_function, Element **array, uint numArrays, BooleanEdge _overflowstatus) :
Element(ELEMFUNCRETURN),
- function(_function),
inputs(array, numArrays),
overflowstatus(_overflowstatus),
- functionencoding(this) {
+ functionencoding(this),
+ function(_function) {
}
ElementConst::ElementConst(uint64_t _value, Set *_set) :
class ElementFunction : public Element {
public:
ElementFunction(Function *function, Element **array, uint numArrays, BooleanEdge overflowstatus);
- Function *function;
Array<Element *> inputs;
BooleanEdge overflowstatus;
FunctionEncoding functionencoding;
Element *clone(CSolver *solver, CloneMap *map);
Set * getRange();
void updateParents();
+ Function * getFunction() {return function;}
CMEMALLOC;
+ private:
+ Function *function;
};
static inline ElementEncoding *getElementEncoding(Element *e) {
#include "encodinggraph.h"
#include "iterator.h"
#include "element.h"
+#include "function.h"
EncodingGraph::EncodingGraph(CSolver * _solver) :
solver(_solver) {
}
-EncodingNode * EncodingGraph::getNode(Element * element) {
- return NULL;
-}
-
void EncodingGraph::buildGraph() {
ElementIterator it(solver);
while(it.hasNext()) {
Element * e = it.next();
- processElement(e);
+ switch(e->type) {
+ case ELEMSET:
+ case ELEMFUNCRETURN:
+ processElement(e);
+ break;
+ case ELEMCONST:
+ break;
+ default:
+ ASSERT(0);
+ }
}
}
void EncodingGraph::processElement(Element *e) {
- switch(e->type) {
- case ELEMSET: {
- break;
- }
- case ELEMFUNCRETURN: {
- break;
+ uint size=e->parents.getSize();
+ for(uint i=0;i<size;i++) {
+ ASTNode * n = e->parents.get(i);
+ switch(n->type) {
+ case PREDICATEOP:
+ processPredicate((BooleanPredicate *)n);
+ break;
+ case ELEMFUNCRETURN:
+ processFunction((ElementFunction *)n);
+ break;
+ default:
+ ASSERT(0);
+ }
}
- case ELEMCONST: {
- break;
+}
+
+void EncodingGraph::processFunction(ElementFunction *ef) {
+ Function *f=ef->getFunction();
+ if (f->type==OPERATORFUNC) {
+ FunctionOperator *fo=(FunctionOperator*)f;
+ ArithOp op=fo->op;
}
- default:
- ASSERT(0);
+}
+
+void EncodingGraph::processPredicate(BooleanPredicate *b) {
+
+}
+
+EncodingNode * EncodingGraph::createNode(Element *e) {
+ Set *s = e->getRange();
+ EncodingNode *n = encodingMap.get(s);
+ if (n == NULL) {
+ n = new EncodingNode(s);
+ encodingMap.put(s, n);
}
+ n->addElement(e);
+ return n;
+}
+
+void EncodingNode::addElement(Element *e) {
+ elements.add(e);
+}
+
+EncodingEdge::EncodingEdge(EncodingNode *_l, EncodingNode *_r) :
+ left(_l),
+ right(_r),
+ dst(NULL)
+{
+}
+
+EncodingEdge::EncodingEdge(EncodingNode *_left, EncodingNode *_right, EncodingNode *_dst) :
+ left(_left),
+ right(_right),
+ dst(_dst)
+{
+}
+
+uint hashEncodingEdge(EncodingEdge *edge) {
+ uintptr_t hash=(((uintptr_t) edge->left) >> 2) ^ (((uintptr_t)edge->right) >> 4) ^ (((uintptr_t)edge->dst) >> 6);
+ return (uint) hash;
+}
+
+bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2) {
+ return e1->left == e2->left && e1->right == e2->right && e1->dst == e2->dst;
}
#include "classlist.h"
#include "structs.h"
+uint hashEncodingEdge(EncodingEdge *edge);
+bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
+
+typedef Hashtable<EncodingEdge *, EncodingEdge *, uintptr_t, PTRSHIFT, hashEncodingEdge, equalsEncodingEdge> HashtableEdge;
+
class EncodingGraph {
public:
EncodingGraph(CSolver * solver);
- EncodingNode * getNode(Element * element);
void buildGraph();
CMEMALLOC;
private:
CSolver * solver;
- HashTableEncoding encodingMap;
+ HashtableEncoding encodingMap;
+ HashtableEdge edgeMap;
void processElement(Element *e);
+ void processFunction(ElementFunction *f);
+ void processPredicate(BooleanPredicate *b);
+ EncodingNode * createNode(Element *e);
};
class EncodingNode {
public:
-
+ EncodingNode(Set *_s);
+ void addElement(Element *e);
CMEMALLOC;
private:
-
+ Set *s;
+ HashsetElement elements;
};
class EncodingEdge {
public:
-
+ EncodingEdge(EncodingNode *_l, EncodingNode *_r);
+ EncodingEdge(EncodingNode *_l, EncodingNode *_r, EncodingNode *_d);
CMEMALLOC;
private:
+ EncodingNode *left;
+ EncodingNode *right;
+ EncodingNode *dst;
+ friend uint hashEncodingEdge(EncodingEdge *edge);
+ friend bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
+
};
+
#endif
}
void SATEncoder::encodeElementFunctionSATEncoder(ElementFunction *function) {
- switch (function->function->type) {
+ switch (function->getFunction()->type) {
case TABLEFUNC:
encodeTableElementFunctionSATEncoder(function);
break;
#ifdef TRACE_DEBUG
model_print("Operator Function ...\n");
#endif
- FunctionOperator *function = (FunctionOperator *) func->function;
+ FunctionOperator *function = (FunctionOperator *) func->getFunction();
uint numDomains = func->inputs.getSize();
/* Call base encoders for children */
Edge carray[numDomains + 1];
uint64_t result = function->applyFunctionOperator(numDomains, vals);
- bool isInRange = ((FunctionOperator *)func->function)->isInRangeFunction(result);
+ bool isInRange = ((FunctionOperator *)func->getFunction())->isInRangeFunction(result);
bool needClause = isInRange;
if (function->overflowbehavior == SATC_OVERFLOWSETSFLAG || function->overflowbehavior == SATC_FLAGIFFOVERFLOW) {
needClause = true;
}
void SATEncoder::encodeEnumEntriesTableElemFuncSATEncoder(ElementFunction *func) {
- UndefinedBehavior undefStatus = ((FunctionTable *) func->function)->undefBehavior;
+ UndefinedBehavior undefStatus = ((FunctionTable *) func->getFunction())->undefBehavior;
ASSERT(undefStatus == SATC_IGNOREBEHAVIOR || undefStatus == SATC_FLAGFORCEUNDEFINED);
Array<Element *> *elements = &func->inputs;
- Table *table = ((FunctionTable *) (func->function))->table;
+ Table *table = ((FunctionTable *) (func->getFunction()))->table;
uint size = table->getSize();
Edge constraints[size];
SetIteratorTableEntry *iterator = table->getEntries();
#ifdef TRACE_DEBUG
model_print("Enumeration Table functions ...\n");
#endif
- ASSERT(elemFunc->function->type == TABLEFUNC);
+ ASSERT(elemFunc->getFunction()->type == TABLEFUNC);
//First encode children
Array<Element *> *elements = &elemFunc->inputs;
for (uint i = 0; i < elements->getSize(); i++) {
encodeElementSATEncoder(elem);
}
- FunctionTable *function = (FunctionTable *)elemFunc->function;
+ FunctionTable *function = (FunctionTable *)elemFunc->getFunction();
switch (function->undefBehavior) {
case SATC_IGNOREBEHAVIOR:
case SATC_FLAGFORCEUNDEFINED:
typedef Hashtable<void *, void *, uintptr_t, PTRSHIFT> CloneMap;
-typedef Hashtable<Set *, EncodingNode *, uintptr_t, PTRSHIFT> HashTableEncoding;
+typedef Hashtable<Set *, EncodingNode *, uintptr_t, PTRSHIFT> HashtableEncoding;
typedef SetIterator<TableEntry *, uintptr_t, PTRSHIFT, table_entry_hash_function, table_entry_equals> SetIteratorTableEntry;
typedef SetIterator<OrderEdge *, uintptr_t, PTRSHIFT, order_edge_hash_function, order_edge_equals> SetIteratorOrderEdge;