1 /*
2 
3     This file is part of the Maude 2 interpreter.
4 
5     Copyright 1997-2003 SRI International, Menlo Park, CA 94025, USA.
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20 
21 */
22 
23 ImportModule*
makeRenamedCopy(int name,Renaming * canonical,ModuleCache * moduleCache)24 ImportModule::makeRenamedCopy(int name, Renaming* canonical, ModuleCache* moduleCache)
25 {
26   ImportModule* copy = new ImportModule(name, getModuleType(), RENAMING, moduleCache);
27   DebugAdvisory("makeRenamedCopy() made " << copy << " at address " << static_cast<void*>(copy));
28   LineNumber lineNumber(FileTable::AUTOMATIC);
29 
30   int nrParameters = parameterNames.size();
31   for (int i = 0; i < nrParameters; ++i)
32     {
33       Token t;
34       t.tokenize(parameterNames[i], FileTable::AUTOMATIC);
35       copy->addParameter(t, importedModules[i]);
36     }
37   //Assert(!parametersBound(), "renamed module has bound parameters");
38 
39   int nrImports = importedModules.size();
40   for (int i = nrParameters; i < nrImports; ++i)
41     {
42       if (ImportModule* importCopy = moduleCache->makeRenamedCopy(importedModules[i], canonical))
43 	copy->addImport(importCopy, INCLUDING, lineNumber);  // HACK should this be INCLUDING?
44       else
45 	{
46 	  //
47 	  //	One of our imports failed its renaming. Abort construction of the
48 	  //	renamed copy and mark it as bad. Let the module cache handle the
49 	  //	clean up.
50 	  //
51 	  copy->markAsBad();
52 	  return copy;
53 	}
54     }
55   finishCopy(copy, canonical);
56   return copy;
57 }
58 
59 void
finishCopy(ImportModule * copy,Renaming * canonical)60 ImportModule::finishCopy(ImportModule* copy, Renaming* canonical)
61 {
62   Assert(!isBad(), "original module bad " << this);
63   copy->canonicalRenaming = canonical;
64   copy->baseModule = this;
65   addUser(copy);
66   //
67   //	Copy our local contents, renaming it as we go, and flattening
68   //	in our imports (but not statements).
69   //
70   copy->importSorts();
71   donateSorts2(copy, canonical);
72   copy->closeSortSet();
73 
74   DebugAdvisory("finishCopy() done with sorts - from " << this << " to " << copy <<
75 		" copy->isBad() = " << copy->isBad());
76   if (!(copy->isBad()))
77     {
78       copy->importOps();
79       donateOps2(copy, canonical);
80       DebugAdvisory("finishCopy() done with ops - from " << this << " to " << copy <<
81 		    " copy->isBad() = " << copy->isBad());
82       if (!(copy->isBad()))
83 	{
84 	  copy->closeSignature();
85 	  copy->fixUpImportedOps();
86 	  fixUpDonatedOps2(copy, canonical);
87 	  DebugAdvisory("finishCopy() done with fixups - from " << this << " to " << copy <<
88 			" copy->isBad() = " << copy->isBad());
89 	  if (!(copy->isBad()))
90 	    {
91 	      copy->closeFixUps();
92 	      //
93 	      //	Statements are not copied so we have no local statements.
94 	      //
95 	      copy->localStatementsComplete();
96 	    }
97 	}
98     }
99   //
100   //	Reset phase counter in each imported module and return copy.
101   //
102   copy->resetImports();
103 }
104 
105 Sort*
localSort(ImportModule * copy,Renaming * renaming,const Sort * sort)106 ImportModule::localSort(ImportModule* copy, Renaming* renaming, const Sort* sort)
107 {
108   return (sort->index() == Sort::KIND) ?
109     localSort2(copy, renaming, sort->component()->sort(1))->component()->sort(Sort::KIND) :
110     localSort2(copy, renaming, sort);
111 }
112 
113 Sort*
localSort2(ImportModule * copy,Renaming * renaming,const Sort * sort)114 ImportModule::localSort2(ImportModule* copy, Renaming* renaming, const Sort* sort)
115 {
116   int id = sort->id();
117   if (renaming != 0)
118     id = renaming->renameSort(id);
119   Sort* ts = copy->findSort(id);
120   Assert(ts != 0, "couldn't find sort " << QUOTE(Token::sortName(id)) <<
121 	 " renamed from " << QUOTE(sort) << " in module " << copy);
122   return ts;
123 }
124 
125 void
donateSorts2(ImportModule * copy,Renaming * renaming)126 ImportModule::donateSorts2(ImportModule* copy, Renaming* renaming)
127 {
128   Assert(!isBad(), "original module bad " << this);
129   //
130   //	Donate our sorts, after a possible renaming.
131   //
132   bool moduleDonatingToTheory = copy->isTheory() && !isTheory();
133   const Vector<Sort*>& sorts = getSorts();
134   for (int i = nrImportedSorts; i < nrUserSorts; i++)
135     {
136       Sort* original = sorts[i];
137       int id = original->id();
138       if (renaming != 0)
139 	id = renaming->renameSort(id);
140       Sort* sort = copy->findSort(id);
141       if (sort == 0)
142 	{
143 	  sort = copy->addSort(id);
144 	  sort->setLineNumber(original->getLineNumber());
145 	}
146       else
147 	{
148 	  if (copy->isTheory() &&
149 	      (moduleDonatingToTheory != copy->sortDeclaredInModule.contains(sort->getIndexWithinModule())))
150 	    {
151 	      //
152 	      //	A theory is getting the same sort from a module and a theory.
153 	      //	This is a nasty situation that can cause various inconsistancies
154 	      //	down the road since sorts from modules are handled differently
155 	      //	to sorts from thoeries; so we handle it harshly.
156 	      //
157 	      IssueWarning(*copy << ": sort " << QUOTE(original) <<
158 			    " has been imported from both " << *original <<
159 			   " and " << *sort <<
160 			   ". Since it is imported from both a module and a theory, this renders theory " <<
161 			   QUOTE(copy) << " unusable.");
162 	      copy->markAsBad();
163 	    }
164 	  else
165 	    {
166 	      IssueAdvisory(*copy << ": sort " << QUOTE(original) <<
167 			    " has been imported from both " << *original <<
168 			    " and " << *sort << '.');
169 	    }
170 	}
171       if (moduleDonatingToTheory)
172 	copy->sortDeclaredInModule.insert(sort->getIndexWithinModule());
173     }
174   //
175   //	Donate our subsort relations, after a possible renaming.
176   //
177   for (int i = 0; i < nrUserSorts; i++)
178     {
179       int nrImports = getNrImportedSubsorts(i);
180       const Sort* s = sorts[i];
181       const Vector<Sort*>& subsorts = s->getSubsorts();
182       int nrSubsorts = subsorts.length();
183       if (nrSubsorts > nrImports)
184 	{
185 	  Sort* ts = localSort2(copy, renaming, s);
186 	  for (int j = nrImports; j < nrSubsorts; j++)
187 	    ts->insertSubsort(localSort2(copy, renaming, subsorts[j]));
188 	}
189     }
190 }
191 
192 void
donateOps2(ImportModule * copy,Renaming * renaming)193 ImportModule::donateOps2(ImportModule* copy, Renaming* renaming)
194 {
195   DebugAdvisory("donateOps2(), from " << this << " to " << copy);
196   Assert(!isBad(), "original module bad " << this);
197 
198   bool moduleDonatingToTheory = copy->isTheory() && !isTheory();
199 
200   Vector<int> gather;
201   Vector<Sort*> domainAndRange;
202   Vector<int> emptyStrategy;
203   //
204   //	Handle our regular operators.
205   //
206   const Vector<Symbol*>& symbols = getSymbols();
207   for (int i = 0; i < nrUserSymbols; i++)
208     {
209       int nrImportedDeclarations = getNrImportedDeclarations(i);
210       int nrUserDeclarations = nrUserDecls[i];
211       if (nrUserDeclarations > nrImportedDeclarations)
212 	{
213 	  //
214 	  //	Need to donate some declarations for this symbol.
215 	  //
216 	  Symbol* symbol = symbols[i];
217 	  SymbolType symbolType = getSymbolType(symbol);
218 	  Assert(!(symbolType.isCreatedOnTheFly()),
219 		 "unexpected variable/sort test/polymorph instance " << symbol);
220 
221 	  Token name;
222 	  int prec = DEFAULT;
223 	  const Vector<int>* format;
224 
225 	  int index = (renaming == 0) ? NONE : renaming->renameOp(symbol);  // index of renaming that applies to symbol
226 	  if (index == NONE)
227 	    {
228 	      name.tokenize(symbol->id(), symbol->getLineNumber());
229 	      prec = symbolType.hasFlag(SymbolType::PREC) ? getPrec(symbol) : DEFAULT;
230 	      if (symbolType.hasFlag(SymbolType::GATHER))
231 		getGather(symbol, gather);
232 	      else
233 		gather.clear();
234 	      format = &(getFormat(symbol));
235 	    }
236 	  else
237 	    {
238 	      int newName = renaming->getOpTo(index);
239 	      DebugAdvisory("Old symbol = " << symbol << " newName = " << Token::name(newName));
240 	      name.tokenize(newName, symbol->getLineNumber());
241 	      prec = renaming->getPrec(index);
242 	      symbolType.assignFlags(SymbolType::PREC, prec != DEFAULT);
243 	      gather = renaming->getGather(index);  // deep copy
244 	      symbolType.assignFlags(SymbolType::GATHER, !gather.empty());
245 	      format = &(renaming->getFormat(index));
246 	      symbolType.assignFlags(SymbolType::FORMAT, !format->empty());
247 	    }
248 
249 	  const Vector<OpDeclaration>& opDecls = symbol->getOpDeclarations();
250 	  int domainAndRangeLength = opDecls[0].getDomainAndRange().length();
251 	  domainAndRange.resize(domainAndRangeLength);
252 	  const Vector<int>& strategy = symbolType.hasFlag(SymbolType::STRAT) ?
253 	    symbol->getStrategy() : emptyStrategy;
254 	  const NatSet& frozen = symbol->getFrozen();
255 
256 	  bool originator;
257 	  for (int j = nrImportedDeclarations; j < nrUserDeclarations; j++)
258 	    {
259 	      const Vector<Sort*>& oldDomainAndRange = opDecls[j].getDomainAndRange();
260 	      for (int k = 0; k < domainAndRangeLength; k++)
261 		domainAndRange[k] = localSort(copy, renaming, oldDomainAndRange[k]);
262 	      symbolType.assignFlags(SymbolType::CTOR, opDecls[j].isConstructor());
263 	      Symbol* newSymbol = copy->addOpDeclaration(name,  // BUG: name has codeNr = -1
264 							 domainAndRange,
265 							 symbolType,
266 							 strategy,
267 							 frozen,
268 							 prec,
269 							 gather,
270 							 *format,
271 							 getMetadata(symbol, j),
272 							 originator);
273 	      if (j == 0)
274 		{
275 		  if (originator)
276 		    {
277 		      if (symbolType.getBasicType() == SymbolType::BUBBLE)
278 		        copy->copyBubbleSpec(symbol, newSymbol);
279 		    }
280 		  else
281 		    {
282 		      IssueAdvisory(*copy << ": operator " << QUOTE(newSymbol) <<
283 				   " has been imported from both " << *newSymbol <<
284 				   " and " << *symbol << " with no common ancestor.");
285 		    }
286 		}
287 	      else  // we must have already imported some declarations
288 	        Assert(!originator, "bad origination of " << symbol);
289 	      if (moduleDonatingToTheory)
290 		copy->opDeclaredInModule.insert(newSymbol->getIndexWithinModule());
291 	    }
292 	}
293     }
294   //
295   //	Now handle our polymorphic operators.
296   //
297   int nrPolymorphs = getNrPolymorphs();
298   for (int i = nrImportedPolymorphs; i < nrPolymorphs; i++)
299     {
300       Token name = getPolymorphName(i);
301       SymbolType symbolType = getPolymorphType(i);
302       int prec = DEFAULT;
303       const Vector<int>* format;
304 
305       int index = (renaming == 0) ? NONE : renaming->renamePolymorph(name.code());
306       if (index == NONE)
307 	{
308 	  prec = symbolType.hasFlag(SymbolType::PREC) ? getPolymorphPrec(i) : DEFAULT;
309 	  if (symbolType.hasFlag(SymbolType::GATHER))
310 	    getPolymorphGather(i, gather);
311 	  else
312 	    gather.clear();
313 	  format = &(getPolymorphFormat(i));
314 	}
315       else
316 	{
317 	  name.tokenize(renaming->getOpTo(index), name.lineNumber());
318 	  prec = renaming->getPrec(index);
319 	  symbolType.assignFlags(SymbolType::PREC, prec != DEFAULT);
320 	  gather = renaming->getGather(index);  // deep copy
321 	  symbolType.assignFlags(SymbolType::GATHER, !gather.empty());
322 	  format = &(renaming->getFormat(index));
323 	  symbolType.assignFlags(SymbolType::FORMAT, !format->empty());
324 	}
325 
326       const Vector<Sort*>& oldDomainAndRange = getPolymorphDomainAndRange(i);
327       int domainAndRangeLength = oldDomainAndRange.length();
328       domainAndRange.resize(domainAndRangeLength);
329       for (int j = 0; j < domainAndRangeLength; j++)
330 	{
331 	  Sort* s = oldDomainAndRange[j];
332 	  domainAndRange[j] = (s == 0) ? 0 : localSort(copy, renaming, s);
333 	}
334 
335       const Vector<int>& strategy = symbolType.hasFlag(SymbolType::STRAT) ?
336 	getPolymorphStrategy(i) : emptyStrategy;
337 
338       int copyIndex = copy->addPolymorph(name,
339 					 domainAndRange,
340 					 symbolType,
341 					 strategy,
342 					 getPolymorphFrozen(i),
343 					 prec,
344 					 gather,
345 					 *format,
346 					 getPolymorphMetadata(i));
347       if (moduleDonatingToTheory)
348 	copy->polymorphDeclaredInModule.insert(copyIndex);
349     }
350 }
351 
352 void
fixUpDonatedOps2(ImportModule * copy,Renaming * renaming)353 ImportModule::fixUpDonatedOps2(ImportModule* copy, Renaming* renaming)
354 {
355   //
356   //	The map from imported module's symbols to importing module's symbols
357   //	is built dynamically.
358   //
359   ImportTranslation importTranslation(copy, renaming);
360   //
361   //	Handle our regular operators.
362   //
363   const Vector<Symbol*>& symbols = getSymbols();
364   for (int i = 0; i < nrUserSymbols; i++)
365     {
366       int nrImportedDeclarations = getNrImportedDeclarations(i);
367       if (nrUserDecls[i] > nrImportedDeclarations)
368 	{
369 	  //
370 	  //	We donated some declarations for this symbol so do
371 	  //	an incremental fixup if needed.
372 	  //
373 	  Symbol* symbol = symbols[i];
374 	  SymbolType st = getSymbolType(symbol);
375 	  if (st.hasFlag(SymbolType::LEFT_ID | SymbolType::RIGHT_ID))
376 	    {
377 	      BinarySymbol* ns = safeCast(BinarySymbol*, importTranslation.translate(symbol));
378 	      if (ns->getIdentity() == 0)
379 		{
380 		  Term* id = safeCast(BinarySymbol*, symbol)->getIdentity();
381 		  Assert(id != 0, "missing identity");
382 		  ns->setIdentity(id->deepCopy(&importTranslation));
383 		}
384 	    }
385 
386 	  if (st.hasAttachments())
387 	    importTranslation.translate(symbol)->copyAttachments(symbol, &importTranslation);
388 	  else if (st.getBasicType() == SymbolType::BUBBLE)
389 	    copy->copyFixUpBubbleSpec(symbol, &importTranslation);
390 	}
391     }
392   //
393   //	Now handle our polymorphic operators.
394   //
395   {
396     Vector<Sort*> domainAndRange;
397 
398     int nrPolymorphs = getNrPolymorphs();
399     for (int i = nrImportedPolymorphs; i < nrPolymorphs; i++)
400       {
401 	//
402 	//	Get polymorph name.
403 	//
404 	int id = getPolymorphName(i).code();
405 	if (renaming != 0)
406 	  {
407 	    int index = renaming->renamePolymorph(id);
408 	    if (index != NONE)
409 	      id = renaming->getOpTo(index);
410 	  }
411 	//
412 	//	Get polymorph domain and range.
413 	//
414 	const Vector<Sort*>& oldDomainAndRange = getPolymorphDomainAndRange(i);
415 	int domainAndRangeLength = oldDomainAndRange.length();
416 	domainAndRange.resize(domainAndRangeLength);
417 	for (int j = 0; j < domainAndRangeLength; j++)
418 	  {
419 	    Sort* s = oldDomainAndRange[j];
420 	    domainAndRange[j] = (s == 0) ? 0 : localSort(copy, renaming, s);
421 	  }
422 
423 	int donatedCopyIndex = copy->findPolymorphIndex(id, domainAndRange);
424 	Assert(donatedCopyIndex != NONE, "missing polymorph");
425 	copy->copyFixUpPolymorph(donatedCopyIndex, this, i, &importTranslation);
426       }
427   }
428 }
429 
430 void
localStatementsComplete()431 ImportModule::localStatementsComplete()
432 {
433   nrOriginalMembershipAxioms = getSortConstraints().length();
434   nrOriginalEquations = getEquations().length();
435   nrOriginalRules = getRules().length();
436 
437   FOR_EACH_CONST(i, Vector<ImportModule*>, importedModules)
438     labels.insert((*i)->labels.begin(), (*i)->labels.end());
439   if (canonicalRenaming == 0)
440     {
441       {
442 	FOR_EACH_CONST(i, Vector<SortConstraint*>, getSortConstraints())
443 	  {
444 	    int id = (*i)->getLabel().id();
445 	    if (id != NONE)
446 	      labels.insert(id);
447 	  }
448       }
449       {
450 	FOR_EACH_CONST(i, Vector<Equation*>, getEquations())
451 	  {
452 	    int id = (*i)->getLabel().id();
453 	    if (id != NONE)
454 	      labels.insert(id);
455 	  }
456       }
457       {
458 	FOR_EACH_CONST(i, Vector<Rule*>, getRules())
459 	  {
460 	    int id = (*i)->getLabel().id();
461 	    if (id != NONE)
462 	      labels.insert(id);
463 	  }
464       }
465     }
466   else
467     {
468       FOR_EACH_CONST(i, set<int>, baseModule->labels)
469 	labels.insert(canonicalRenaming->renameLabel(*i));
470     }
471 }
472