3 #include "signatureenc.h"
17 const char * AlloyEnc::alloyFileName = "satune.als";
18 const char * AlloyEnc::solutionFile = "solution.sol";
20 AlloyEnc::AlloyEnc(CSolver *_solver):
24 output.open(alloyFileName);
25 if(!output.is_open()){
26 model_print("AlloyEnc:Error in opening the dump file satune.als\n");
31 AlloyEnc::~AlloyEnc(){
37 void AlloyEnc::encode(){
39 SetIteratorBooleanEdge *iterator = csolver->getConstraints();
41 while(iterator->hasNext()){
42 BooleanEdge constraint = iterator->next();
43 string constr = encodeConstraint(constraint);
44 //model_print("constr=%s\n", constr.c_str());
45 char *cstr = new char [constr.length()+1];
46 strcpy (cstr, constr.c_str());
49 output << "fact {" << endl;
50 for(uint i=0; i< facts.getSize(); i++){
51 char *cstr = facts.get(i);
55 output << "}" << endl;
59 int AlloyEnc::getResult(){
60 ifstream input(solutionFile, ios::in);
62 while(getline(input, line)){
63 if(regex_match(line, regex("Unsatisfiable."))){
66 if(regex_match(line, regex(".*Element\\d+.*value=.*Element\\d+.*->\\d+.*"))){
67 int tmp=0, index=0, value=0;
68 const char* s = line.c_str();
71 if (4 == sscanf(s,"%*[^0123456789]%u%*[^0123456789]%d%*[^0123456789]%d%*[^0123456789]%" PRId64 "", &i1, &i2, &i3, &i4)){
72 model_print("Element%d = %" PRId64 "\n", i1, i4);
73 sigEnc.setValue(i1, i4);
80 void AlloyEnc::dumpAlloyFooter(){
81 output << "pred show {}" << endl;
82 output << "run show for " << sigEnc.getAlloyIntScope() << " int" << endl;
85 void AlloyEnc::dumpAlloyHeader(){
86 output << "open util/integer" << endl;
89 int AlloyEnc::solve(){
91 int result = IS_INDETER;
93 if( output.is_open()){
96 snprintf(buffer, sizeof(buffer), "./run.sh java -Xmx10000m edu.mit.csail.sdg.alloy4whole.ExampleAlloyCompilerNoViz %s > %s", alloyFileName, solutionFile);
97 int status = system(buffer);
99 //Read data in from results file
100 result = getResult();
105 string AlloyEnc::encodeConstraint(BooleanEdge c){
106 Boolean *constraint = c.getBoolean();
108 switch(constraint->type){
110 res = encodeBooleanLogic((BooleanLogic *) constraint);
114 res = encodePredicate((BooleanPredicate *) constraint);
118 res = encodeBooleanVar( (BooleanVar *) constraint);
125 return "not ( " + res + " )";
130 string AlloyEnc::encodeBooleanLogic( BooleanLogic *bl){
131 uint size = bl->inputs.getSize();
133 for (uint i = 0; i < size; i++)
134 array[i] = encodeConstraint(bl->inputs.get(i));
140 for( uint i=1; i< size; i++){
141 res += " and " + array[i];
146 return "not " + array[0];
149 return array[0] + " iff " + array[1];
159 string AlloyEnc::encodePredicate( BooleanPredicate *bp){
160 switch (bp->predicate->type) {
164 return encodeOperatorPredicate(bp);
170 string AlloyEnc::encodeBooleanVar( BooleanVar *bv){
171 BooleanSig * boolSig = sigEnc.getBooleanSignature(bv);
172 return *boolSig + " = 1";
175 string AlloyEnc::processElementFunction(ElementFunction* elemFunc, ElementSig *signature){
176 FunctionOperator *function = (FunctionOperator *) elemFunc->getFunction();
177 uint numDomains = elemFunc->inputs.getSize();
178 ASSERT(numDomains > 1);
179 ElementSig *inputs[numDomains];
181 for (uint i = 0; i < numDomains; i++) {
182 Element *elem = elemFunc->inputs.get(i);
183 inputs[i] = sigEnc.getElementSignature(elem);
184 if(elem->type == ELEMFUNCRETURN){
185 result += processElementFunction((ElementFunction *) elem, inputs[i]);
189 switch(function->op){
199 result += *signature + " = " + *inputs[0];
200 for (uint i = 1; i < numDomains; i++) {
201 result += op + "["+ *inputs[i] +"]";
207 string AlloyEnc::encodeOperatorPredicate(BooleanPredicate *constraint){
209 PredicateOperator *predicate = (PredicateOperator *) constraint->predicate;
210 ASSERT(constraint->inputs.getSize() == 2);
212 Element *elem0 = constraint->inputs.get(0);
213 ASSERT(elem0->type == ELEMSET || elem0->type == ELEMFUNCRETURN || elem0->type == ELEMCONST);
214 ElementSig *elemSig1 = sigEnc.getElementSignature(elem0);
215 if(elem0->type == ELEMFUNCRETURN){
216 str += processElementFunction((ElementFunction *) elem0, elemSig1);
218 Element *elem1 = constraint->inputs.get(1);
219 ASSERT(elem1->type == ELEMSET || elem1->type == ELEMFUNCRETURN || elem1->type == ELEMCONST);
220 ElementSig *elemSig2 = sigEnc.getElementSignature(elem1);
221 if(elem1->type == ELEMFUNCRETURN){
222 str += processElementFunction((ElementFunction *) elem1, elemSig2);
224 switch (predicate->getOp()) {
226 str += *elemSig1 + " = " + *elemSig2;
229 str += *elemSig1 + " < " + *elemSig2;
232 str += *elemSig1 + " > " + *elemSig2;
240 void AlloyEnc::writeToFile(string str){
241 output << str << endl;
244 bool AlloyEnc::getBooleanValue(Boolean *b){
245 if (b->boolVal == BV_MUSTBETRUE)
247 else if (b->boolVal == BV_MUSTBEFALSE)
249 return sigEnc.getBooleanSignature(b);
252 uint64_t AlloyEnc::getValue(Element * element){
253 ElementEncoding *elemEnc = element->getElementEncoding();
254 if (elemEnc->numVars == 0)//case when the set has only one item
255 return element->getRange()->getElement(0);
256 return sigEnc.getValue(element);