root/ggpa/Sentence.cpp

Revision 1, 19.7 kB (checked in by pantley2, 4 years ago)

GGPA code from the good old days of SIGART

Line 
1 /*
2  * Sentence.cpp
3  * Implementation of Sentence class
4  */
5
6 #include "Sentence.h"
7 #include "SentenceStructure.h"
8 #include <vector>
9 #include <iostream>
10 #include <string>
11 using namespace std;
12
13
14 /*
15  * Constructor for Sentence
16  * Parameters:  theValues - a vector of values for the Sentence
17  *              theStructure - a pointer to a SentenceStructure
18  * Return type: none
19  * Sets the values of the sentence equal to a copy of theValues,
20  * checking that the values are all in the SentenceStructure.
21  */
22 Sentence::Sentence(vector<string> theValues, SentenceStructure* theStructure) {
23     //cout << "Constructor" << endl;
24     if (theStructure == NULL) {
25         cerr << "Structure is NULL" << endl;
26         exit(1);
27     }
28     this->structure = theStructure;
29
30     // verify the values
31     if (theValues.size() != structure->getNumParameters()) {
32         cerr << "Incorrect size for theValues vector: should be "
33              << structure->getNumParameters() << endl;
34     }
35     for (unsigned int i = 0; i < theValues.size(); i++) {
36         if (!isVariable(theValues[i]) &&
37             structure->getValueIndex(i, theValues[i]) < 0) {
38             cerr << "Invalid value \"" << theValues[i] << "\" at index "
39                  << i << endl;
40             exit(1);
41         }
42     }
43     this->values = theValues;
44 }
45
46 /*
47  * Destructor for Sentence class
48  */
49 Sentence::~Sentence() {
50     clearDependencies(true);
51 }
52
53 /*
54  * operator[]
55  * Parameters: index - an int representing the value that we wish to
56  *                      retrieve
57  * Return type: A const reference to a string
58  * Returns the value at the index. This should be used to access the
59  * values in a Sentence.
60  */
61 const string& Sentence::operator[](int index) const {
62     return values[index];
63 }
64
65 /*
66  * getNumValues
67  * No parameters
68  * Return type: int
69  * Returns the number of values for this sentence.
70  */
71 unsigned int Sentence::getNumValues() const {
72     return values.size();
73 }
74
75 /*
76  * getName
77  * No parameters
78  * Return type: string
79  * Returns the name of this sentence (from its SentenceStructure)
80  */
81 string Sentence::getName() const {
82     return structure->getName();
83 }
84
85
86 /*
87  * addAndDependency
88  * Parameters:  dependency: a Sentence
89  *              negated:  a bool, true if the dependency is negative
90  * Return value: none
91  * Adds the dependency to the dependency list
92  */
93 void Sentence::addAndDependency(Sentence* dependency, bool negated) {
94     vector<Sentence*> temp(1);
95     temp[0] = dependency;
96     dependencies.push_back(temp);
97     dependencyFlags.push_back(negated);
98 }
99
100 /*
101  * addOrDependency
102  * Parameters: theSentences: a vector of Sentences to be ORed
103  *             negated: a bool, true if the dependencyis negative
104  * Adds the OR dependency to the dependency list
105  */
106 void Sentence::addOrDependency(const vector<Sentence*>& dependency,
107                                bool negated) {
108     dependencies.push_back(dependency);
109     dependencyFlags.push_back(negated);
110
111 }
112
113 /*
114  * getDependencies
115  * No parameters
116  * Return type: a const reference to a vector of vectors of sentences
117  * Returns the dependency list for this sentence.
118  */
119 const vector<vector<Sentence*> >& Sentence::getDependencies() const {
120     return this->dependencies;
121 }
122
123 /*
124  * isDependencyNegated
125  * Parameters: index - the index of the dependency in the dependency list
126  * Return type: bool
127  * Returns true if the dependency is negated, and false otherwise
128  */
129 bool Sentence::isDependencyNegated(int index) const {
130     if (index >=0 && (unsigned int)index < dependencyFlags.size()) {
131         return dependencyFlags[index];
132     } else {
133         cerr << "Index out of bounds" << endl;
134         exit(1);
135     }
136 }
137
138 /*
139  * getIndex
140  * No parameters
141  * Return type: int
142  * Returns the index of this Sentence in the State object.  If this sentence
143  * has variables, then the function will return -1.  In this case, you
144  * should call getAtomicSentences and then do getIndex on each of those.
145  */
146 int Sentence::getIndex() const {
147     //cout << "Get Index" << endl;
148     int base = structure->getOffset();
149
150     // calculate the offset using the values vector as a variable length
151     // integer
152     int offset = 0;
153     int start = values.size()-1, stop = -1, step = -1;
154     if (ENDIAN == BIG_ENDIAN) {
155         stop = values.size();
156         start = 0;
157         step = 1;
158     }
159     for (int i = start; i != stop; i += step) {
160         // if it is a variable, return -1
161         if (isVariable(values[i])) {
162             //cout << "Value is a variable: " << values[i] << endl;
163             return -1;
164         }
165        
166         int numValues = structure->getValues(i).size();
167         int index = structure->getValueIndex(i, values[i]);
168
169         if (index < 0) {
170             cerr << "Value " << i << " = '" << values[i] << "' not found" << endl;
171             //int num = 1/0;
172             exit(1);
173         }
174        
175         // update the number:
176         offset *= numValues;
177         offset += index;
178     }
179     //cout << "End. Base = " << base << ", Offset = " << offset << endl;
180     return base + offset;
181 }
182
183 /*
184  * getAtomicSentences
185  * Parameters: none
186  * Return type: a vector of sentences
187  * Returns all possible atomic sentences that can be derived from this
188  * Sentence.  These sentences will be returned in increasing order of
189  * index within State.
190  */
191 vector<Sentence*> Sentence::getAtomicSentences() const {
192     vector<Sentence*>* sentences = new vector<Sentence*>();
193     int numParameters = structure->getNumParameters();
194     vector<vector<string> > possibilities;
195     vector<string> start(numParameters, "");
196     possibilities.push_back(start);
197
198     int startPos = numParameters - 1, stopPos = 0, step = -1;
199     for (int i = startPos; i >= stopPos; i += step) {
200
201         if (isVariable(values[i])) {
202             vector<vector<string> > newPossibilities;
203             vector<string> posValues = structure->getValues(i);
204            
205             if (ENDIAN == LITTLE_ENDIAN) {
206                 for (unsigned int j = 0; j < possibilities.size(); j++) {
207                     for (unsigned int k = 0; k < posValues.size(); k++) {
208                         vector<string> cur;
209                         cur = possibilities[j];
210                         cur[i] = posValues[k];
211                         newPossibilities.push_back(cur);
212                     }
213                 }
214             }
215             else {  // BIG_ENDIAN
216                 for (unsigned int k = 0; k < posValues.size(); k++) {
217                     for (unsigned int j = 0; j < possibilities.size(); j++) {
218                         vector<string> cur;
219                         cur = possibilities[j];
220                         cur[i] = posValues[k];
221                         newPossibilities.push_back(cur);
222                     }
223                 }
224             }
225             possibilities = newPossibilities;
226
227         } else {
228             for (unsigned int j = 0; j < possibilities.size(); j++) {
229                 possibilities[j][i] = values[i];
230             }
231         }
232     }
233
234     for (unsigned int i = 0; i < possibilities.size(); i++) {
235         //cout << "Creating sentence " << i+1 << " of " << possibilities.size()
236         //     << endl;
237         sentences->push_back(new Sentence(possibilities[i], structure));
238     }
239     return *sentences;
240 }
241
242 /*
243  * getStructure
244  * Parameters: none
245  * Return type: a pointer to a SentenceStructure
246  * Returns the SentenceStructure for this Sentence
247  */
248 SentenceStructure* Sentence::getStructure() const {
249     return this->structure;
250 }
251
252 /*
253  * operator==
254  * Parameters: s2 - another Sentence for comparison
255  * Return type: bool
256  * Returns true if the two sentences are equal, and false otherwise
257  */
258 bool Sentence::operator==(const Sentence& s2) const {
259     if (!(*(this->structure) == *(s2.structure))) {
260         return false;
261     }
262
263     if (this->values.size() != s2.values.size()) {
264         return false;
265     }
266
267     for (unsigned int i = 0; i < this->values.size(); i++) {
268         if (this->values[i] != s2.values[i]) {
269             return false;
270         }
271     }
272     return true;
273 }
274
275
276 /**
277  * enumerateWithBinding
278  * Parameters: none
279  * Return type: a vector of sentence*
280  * This works similarly to getAtomicSentences, except that it also does
281  * binding within the dependencies.
282  */
283 vector<Sentence*> Sentence::enumerateWithBinding() const {
284     map<string,string> valueMap;
285     return enumerateWithBinding(valueMap);
286
287 /*
288     vector<Sentence*> sentences = getAtomicSentences();
289
290     for (unsigned int index = 0; index < sentences.size(); index++) {
291         Sentence* sentence = sentences[index];
292         sentence->dependencies = this->dependencies;
293
294         // get the variable mappings at the base
295         map<string, string> valueMap* = new map<string,string>();
296         for (unsigned int attribute = 0; attribute < values.size();
297              attribute++) {
298             if (isVariable(values[attribute])) {
299                 (*valueMap)[values[attribute]] = (*sentence)[attribute];
300             }
301         }
302
303         for (unsigned int dependency = 0; dependency <= dependencies;
304              dependency++) {
305             for (unsigned int num = 0; num < dependencies[dependency].size();
306                  num++) {
307                 Sentence* component = dependencies[dependency][num];
308                 for (unsigned int variable = 0;
309                      variable < component->values.size(); variable++) {
310                     value = component->values[variable];
311                     if (isVariable(value)) {
312                         if (valueMap.find(value) != valueMap.end()) {
313                             component->values[variable] = valueMap[value];
314                         } else {
315                             // break apart the variable into multiple sentences
316                         }
317                     }
318                 }
319             }
320         }
321
322         delete valueMap;
323     }
324 */
325 }
326
327
328
329 /*
330  * enumerateWithBinding
331  * Parameters: valueMap - a map of variables to values
332  * Return type: vector of sentence pointers
333  * Returns the set of sentences that can be generated from this sentence.
334  * The supplied variable values will be used, but if no values exist,
335  * we will branch on this value.
336  */
337 vector<Sentence*> Sentence::enumerateWithBinding(map<string,string>& valueMap) const {
338     vector<Sentence*> sentences;
339     Sentence* thisSentence = new Sentence(*this);
340     // assign all the variables that we can.
341     for (unsigned int valueIndex = 0; valueIndex < values.size();
342          valueIndex++) {
343         string value = values[valueIndex];
344         if (isVariable(value)) {
345             if (valueMap.find(value) != valueMap.end()) {
346                 // the variable is defined, just assign the value
347                 (*thisSentence).values[valueIndex] = valueMap[value];
348             }
349         }
350     }
351
352     sentences = thisSentence->getAtomicSentences();
353     map<string,string> valueMapCopy(valueMap);
354     for (unsigned int sentenceIndex = 0; sentenceIndex < sentences.size();
355          sentenceIndex++) {
356         Sentence* sentence = sentences[sentenceIndex];
357        
358         // extend the valueMap
359         valueMap = valueMapCopy;
360         for (unsigned int valueIndex = 0; valueIndex < values.size();
361              valueIndex++) {
362             if (isVariable((*thisSentence)[valueIndex])) {
363                 valueMap[(*thisSentence)[valueIndex]]
364                     = (*sentence)[valueIndex];
365             }
366         }
367
368         // process each sentence in the dependencies.
369         
370     }
371     return sentences;
372    
373 }
374
375
376 /**
377  * getVariables
378  * No parameters.
379  * Return type: a map from variables to vectors of of their possible values
380  * Searches through the sentence and its dependencies, and returns all
381  * of the variables, along with their posible values
382  */
383 map<string, vector<string> > Sentence::getVariables() const {
384     map<string, vector<string> > variableMap;
385     getVariables(variableMap);
386
387     return variableMap;
388 }
389
390
391 /*
392  * getVariables
393  * Parameters: variableMap: a map where we should add the new variables
394  * Return type: none
395  * Adds the variables and their set of possible values to the variableMap
396  */
397 void Sentence::getVariables(map<string, vector<string> >& variableMap) const {
398     for (unsigned int valueIndex = 0; valueIndex < values.size();
399          valueIndex++) {
400         string value = values[valueIndex];
401         if (isVariable(value)) {
402             variableMap[value] = structure->getValues(valueIndex);
403         }
404     }
405    
406     for (unsigned int index = 0; index < dependencies.size(); index++) {
407         vector<Sentence*> dependency = dependencies[index];
408         for (unsigned int subIndex = 0; subIndex < dependency.size();
409              subIndex++) {
410             Sentence* component = dependency[subIndex];
411             component->getVariables(variableMap);
412         }
413     }
414    
415     return;
416 }
417
418
419 /**
420  * getAtomicSentence
421  * Parameters: variableMap - a mapping of the variables
422  * Return type: a new Sentence
423  * Creates a new sentence with any variables mapped by the parameter map
424  */
425 Sentence* Sentence::getAtomicSentence(map<string, string> variableMap) const {
426     Sentence* atomicSentence = new Sentence(*this);
427
428     for (unsigned int valueIndex = 0;
429          valueIndex < atomicSentence->values.size();
430          valueIndex++) {
431         string value = atomicSentence->values[valueIndex];
432         if (isVariable(value)) {
433             atomicSentence->values[valueIndex] = variableMap[value];
434         }
435     }
436
437     for (unsigned int dependencyIndex = 0;
438          dependencyIndex < dependencies.size();
439          dependencyIndex++) {
440         vector<Sentence*> dependency = dependencies[dependencyIndex];
441         for (unsigned int sentenceIndex = 0;
442              sentenceIndex < dependency.size();
443              sentenceIndex++) {
444             Sentence* sentence;
445             sentence = dependency[sentenceIndex]->getAtomicSentence(variableMap);
446             atomicSentence->dependencies[dependencyIndex][sentenceIndex] = sentence;
447             // NOTE:  Do we need to delete the old sentence?
448         }
449     }
450
451     return atomicSentence;
452 }
453
454
455 /*
456  * clearDependencies
457  * No parameters or return type.
458  * Removes all of the dependencies
459  */
460 void Sentence::clearDependencies(bool recursiveDelete) {
461     if (recursiveDelete) {
462         for (unsigned int dependencyIndex = 0;
463              dependencyIndex < dependencies.size();
464              dependencyIndex++) {
465             vector<Sentence*> dependency = dependencies[dependencyIndex];
466             for (unsigned int subIndex = 0; subIndex < dependency.size();
467                  subIndex++) {
468                 delete dependency[subIndex];
469                 dependency[subIndex] = NULL;
470             }
471         }
472     }
473     dependencies.clear();
474 }
475
476 /*
477  * print
478  * Parameters: output: a stream to output to.
479  * No return type.
480  * Prints the sentence to the given stream
481  */
482 void Sentence::print(ostream& output, string indent) const {
483     if (dependencies.size() == 0) {
484         output << indent << "(" << structure->getName();
485         for (unsigned int index = 0; index < values.size(); index++) {
486             output << " " << values[index];
487         }
488         output << ")" << endl;
489     } else {
490         output << "(<= ";
491         output << "(" << structure->getName();
492         for (unsigned int index = 0; index < values.size(); index++) {
493             output << " " << values[index];
494         }
495         output << endl;
496        
497         for (unsigned int index = 0; index < dependencies.size(); index++) {
498             string curIndent = indent+"\t";
499             vector<Sentence*> dependency = dependencies[index];
500             if (isDependencyNegated(index)) {
501                 output << curIndent << "(not" << endl;
502                 curIndent = curIndent + "\t";
503             }
504             if (dependency.size() == 1) {
505                 dependency[0]->print(output, curIndent);
506             } else {
507                 output << curIndent << "(or ";
508                 for (unsigned int subIndex = 0; subIndex < dependency.size();
509                      subIndex++) {
510                     output << endl;
511                     dependency[subIndex]->print(output, curIndent +"\t");
512                 }
513                 output << ")" << endl;
514             }
515             if (isDependencyNegated(index)) {
516                 output << indent << "\t)" << endl;
517             }
518         }
519         output << indent << "))";
520
521     }
522 }
523
524
525 /*
526  * mergeValues
527  * No parameters or return type.
528  * Merges possible values for variables in this sentence.
529  */
530 void Sentence::mergeValues() {
531     multimap<string, PossibleValues*> variableMap;
532     mergeValues(variableMap);
533    
534 }
535
536
537 /*
538  * mergeValues
539  * Parameters: variableMap:  a multimap from variables to their set of
540  *                           possible values
541  * Return type: none
542  * Merges the sets of values for the variables
543  */
544 void Sentence::mergeValues(multimap<string, PossibleValues*>& variableMap) {
545     // first merge the current variables and add them to the map
546     for (unsigned int index = 0; index < values.size(); index++) {
547         string value = values[index];
548         vector<string>* valueSet = structure->getValuesPointer(index);
549         mergeValue(value, valueSet, variableMap);
550     }
551
552     // then perform the merge for all of the dependencies
553     for (unsigned int index = 0; index < dependencies.size(); index++) {
554         vector<Sentence*> dependency = dependencies[index];
555         for (unsigned int subIndex = 0; subIndex < dependency.size();
556              subIndex++) {
557             dependency[subIndex]->mergeValues(variableMap);
558         }
559     }
560        
561 }
562
563 /*
564  * mergeValue
565  * Parameters: value - the value to merge in
566  *             valueSet - the set of values for that variable
567  *             variableMap - the mapping from variable name to value set
568  * Return type: none
569  * Merges the value with the valueMap.
570  */
571 void Sentence::mergeValue(string value, vector<string>* valueSet,
572                           multimap<string, PossibleValues*>& variableMap) {
573     pair<multimap<string, PossibleValues*>::iterator, multimap<string, PossibleValues*>::iterator> range;
574     multimap<string, PossibleValues*>::iterator equalItr;
575     PossibleValues* possibleValues;
576     if (isVariable(value)) {
577         if (structure->getName() == DISTINCT_NAME) {
578             possibleValues = new DistinctPossibleValues(valueSet);
579         } else {
580             possibleValues = new PossibleValues(valueSet);
581            
582         }
583         range = variableMap.equal_range(value);
584         for (equalItr = range.first; equalItr != range.second;
585              equalItr++) {
586             possibleValues->merge(equalItr->second);
587             equalItr->second->merge(possibleValues);
588         }
589         variableMap.insert(pair<string, PossibleValues*>(value, possibleValues));
590     }
591 }
592
593
594 // functions for PossibleValues subclasses
595
596 Sentence::PossibleValues::PossibleValues(vector<string>* possibleValues) {
597     values = possibleValues;
598 }
599
600        
601 /*
602  * merge
603  * Parameters: otherValues: the values to add to the current
604  * No return type
605  * Adds the otherValues to these values, avoiding duplication.
606  */
607 void Sentence::PossibleValues::merge(PossibleValues* otherValues) {
608     vector<string>* addValues = otherValues->getValues();
609     if (addValues == NULL) {
610         return;
611     }
612    
613     unsigned int thisSize = values->size();
614     for (unsigned int index = 0; index < addValues->size(); index++) {
615         string value = (*addValues)[index];
616         bool found = false;
617         for (unsigned int thisIndex = 0; thisIndex < thisSize;
618              thisIndex++) {
619             if ((*values)[thisIndex] == value) {
620                 found = true;
621                 break;
622             }
623         }
624         if (!found) {
625             values->push_back(value);
626         }
627     }
628 }
629
630 /*
631  * getValues
632  * no parameters
633  * return type: vector<string>*
634  * gets the values for this object.
635  */
636 vector<string>* Sentence::PossibleValues::getValues() {
637     return values;
638 }
639
640
641 Sentence::DistinctPossibleValues::DistinctPossibleValues(vector<string>* possibleValues) {
642     values = possibleValues;
643 }
644
645 /*
646  * getValues
647  * no parameters
648  * return type: vector<string>*
649  * gets the values for this object.
650  */
651 vector<string>* Sentence::DistinctPossibleValues::getValues() {
652     return NULL;
653 }
Note: See TracBrowser for help on using the browser.