1 #include "satencoder.h"
9 #include "orderencoder.h"
10 #include "ordergraph.h"
11 #include "orderedge.h"
13 #include "predicate.h"
14 #include "orderelement.h"
16 Edge encodeOrderSATEncoder(SATEncoder *This, BooleanOrder *constraint) {
17 switch ( constraint->order->type) {
19 return encodePartialOrderSATEncoder(This, constraint);
21 return encodeTotalOrderSATEncoder(This, constraint);
30 Edge inferOrderConstraintFromGraph(Order* order, uint64_t _first, uint64_t _second){
31 if (order->graph != NULL) {
32 OrderGraph *graph=order->graph;
33 OrderNode *first=lookupOrderNodeFromOrderGraph(graph, _first);
34 OrderNode *second=lookupOrderNodeFromOrderGraph(graph, _second);
35 if ((first != NULL) && (second != NULL)) {
36 OrderEdge *edge=lookupOrderEdgeFromOrderGraph(graph, first, second);
40 else if (edge->mustNeg)
43 OrderEdge *invedge=getOrderEdgeFromOrderGraph(graph, second, first);
44 if (invedge != NULL) {
47 else if (invedge->mustNeg)
55 Edge getPairConstraint(SATEncoder *This, Order *order, OrderPair *pair) {
56 Edge gvalue = inferOrderConstraintFromGraph(order, pair->first, pair->second);
57 if(!edgeIsNull(gvalue))
60 HashTableOrderPair *table = order->orderPairTable;
63 if (pair->first < pair->second) {
65 flipped.first = pair->second;
66 flipped.second = pair->first;
70 if (!(table->contains(pair))) {
71 constraint = getNewVarSATEncoder(This);
72 OrderPair *paircopy = new OrderPair(pair->first, pair->second, constraint);
73 table->put(paircopy, paircopy);
75 constraint = table->get(pair)->constraint;
77 return negate ? constraintNegate(constraint) : constraint;
80 Edge encodeTotalOrderSATEncoder(SATEncoder *This, BooleanOrder *boolOrder) {
81 ASSERT(boolOrder->order->type == TOTAL);
82 if (boolOrder->order->orderPairTable == NULL) {
83 boolOrder->order->initializeOrderHashTable();
84 bool doOptOrderStructure=GETVARTUNABLE(This->solver->tuner, boolOrder->order->type, OPTIMIZEORDERSTRUCTURE, &onoff);
85 if (doOptOrderStructure) {
86 boolOrder->order->graph = buildMustOrderGraph(boolOrder->order);
87 reachMustAnalysis(This->solver, boolOrder->order->graph, true);
89 createAllTotalOrderConstraintsSATEncoder(This, boolOrder->order);
91 OrderPair pair(boolOrder->first, boolOrder->second, E_NULL);
92 Edge constraint = getPairConstraint(This, boolOrder->order, &pair);
97 void createAllTotalOrderConstraintsSATEncoder(SATEncoder *This, Order *order) {
99 model_print("in total order ...\n");
101 ASSERT(order->type == TOTAL);
102 Vector<uint64_t> *mems = order->set->members;
103 uint size = mems->getSize();
104 for (uint i = 0; i < size; i++) {
105 uint64_t valueI = mems->get(i);
106 for (uint j = i + 1; j < size; j++) {
107 uint64_t valueJ = mems->get(j);
108 OrderPair pairIJ(valueI, valueJ, E_NULL);
109 Edge constIJ = getPairConstraint(This, order, &pairIJ);
110 for (uint k = j + 1; k < size; k++) {
111 uint64_t valueK = mems->get(k);
112 OrderPair pairJK(valueJ, valueK, E_NULL);
113 OrderPair pairIK(valueI, valueK, E_NULL);
114 Edge constIK = getPairConstraint(This, order, &pairIK);
115 Edge constJK = getPairConstraint(This, order, &pairJK);
116 addConstraintCNF(This->cnf, generateTransOrderConstraintSATEncoder(This, constIJ, constJK, constIK));
122 Edge getOrderConstraint(HashTableOrderPair *table, OrderPair *pair) {
123 ASSERT(pair->first != pair->second);
126 if (pair->first < pair->second) {
128 flipped.first = pair->second;
129 flipped.second = pair->first;
132 if (!table->contains(pair)) {
135 Edge constraint = table->get(pair)->constraint;
136 ASSERT(!edgeIsNull(constraint));
137 return negate ? constraintNegate(constraint) : constraint;
140 Edge generateTransOrderConstraintSATEncoder(SATEncoder *This, Edge constIJ,Edge constJK,Edge constIK) {
141 Edge carray[] = {constIJ, constJK, constraintNegate(constIK)};
142 Edge loop1 = constraintOR(This->cnf, 3, carray);
143 Edge carray2[] = {constraintNegate(constIJ), constraintNegate(constJK), constIK};
144 Edge loop2 = constraintOR(This->cnf, 3, carray2 );
145 return constraintAND2(This->cnf, loop1, loop2);
148 Edge encodePartialOrderSATEncoder(SATEncoder *This, BooleanOrder *constraint) {
149 ASSERT(constraint->order->type == PARTIAL);