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 DagNode*
upQid(int id,PointerMap & qidMap)24 MetaLevel::upQid(int id, PointerMap& qidMap)
25 {
26   void* p = const_cast<void*>(static_cast<const void*>(Token::name(id)));
27   DagNode *d = static_cast<DagNode*>(qidMap.getMap(p));
28   if (d == 0)
29     {
30       d = new QuotedIdentifierDagNode(qidSymbol, Token::backQuoteSpecials(id));
31       (void) qidMap.setMap(p, d);
32     }
33   return d;
34 }
35 
36 DagNode*
upType(Sort * sort,PointerMap & qidMap)37 MetaLevel::upType(Sort* sort, PointerMap& qidMap)
38 {
39   int id = sort->id();
40   if (sort->index() == Sort::KIND)
41     {
42       string fullName("`[");
43       ConnectedComponent* component = sort->component();
44       int nrMaxSorts = component->nrMaximalSorts();
45       for (int i = 1; i <= nrMaxSorts; i++)
46 	{
47 	  fullName += Token::name(component->sort(i)->id());
48 	  fullName += (i == nrMaxSorts) ? "`]" : "`,";
49 	}
50       id = Token::encode(fullName.c_str());
51     }
52   return upQid(id, qidMap);
53 }
54 
55 DagNode*
upJoin(int id,Sort * sort,char sep,PointerMap & qidMap)56 MetaLevel::upJoin(int id, Sort* sort, char sep, PointerMap& qidMap)
57 {
58   Assert(sort != 0, "null sort");
59   string fullName(Token::name(id));
60   fullName += sep;
61   if (sort->index() == Sort::KIND)
62     {
63       fullName += "`[";
64       ConnectedComponent* component = sort->component();
65       int nrMaxSorts = component->nrMaximalSorts();
66       for (int i = 1; i <= nrMaxSorts; i++)
67 	{
68 	  fullName += Token::name(component->sort(i)->id());
69 	  fullName += (i == nrMaxSorts) ? "`]" : "`,";
70 	}
71     }
72   else
73     fullName += Token::name(sort->id());
74   return upQid(Token::encode(fullName.c_str()), qidMap);
75 }
76 
77 local_inline DagNode*
upConstant(int id,Sort * sort,PointerMap & qidMap)78 MetaLevel::upConstant(int id, Sort* sort, PointerMap& qidMap)
79 {
80   return upJoin(id, sort, '.', qidMap);
81 }
82 
83 DagNode*
upConstant(int id,DagNode * d,PointerMap & qidMap)84 MetaLevel::upConstant(int id, DagNode* d, PointerMap& qidMap)
85 {
86   Sort* sort = d->getSort();
87   if (sort == 0)
88     {
89       //
90       //	Can happen since sorts are not calculated in unifiers.
91       //	Fortunately there shouldn't be any membership axioms involved
92       //	in a unification problem and the precise sorts of constants is
93       //	non-critical for disambiguation.
94       //	So we temporarily compute a base sort.
95       //
96       Symbol* s = d->symbol();
97       s->computeBaseSort(d);
98       sort = s->rangeComponent()->sort(d->getSortIndex());
99       d->setSortIndex(Sort::SORT_UNKNOWN);
100     }
101   return upJoin(id, sort, '.', qidMap);
102 }
103 
104 inline DagNode*
upVariable(int id,Sort * sort,PointerMap & qidMap)105 MetaLevel::upVariable(int id, Sort* sort, PointerMap& qidMap)
106 {
107   //
108   //	id might be flagged (in the disjoint unification case) so we always unflag it.
109   //
110   return upJoin(Token::unflaggedCode(id), sort, ':', qidMap);
111 }
112 
113 DagNode*
upDagNode(DagNode * dagNode,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)114 MetaLevel::upDagNode(DagNode* dagNode,
115 		     MixfixModule* m,
116 		     PointerMap& qidMap,
117 		     PointerMap& dagNodeMap)
118 {
119   Assert(dagNode != 0, "null dagNode");
120   Vector<DagNode*> args(2);  // can't be static!
121   //
122   //	See if we have already up'd this dag node via a different path.
123   //
124   DagNode *d = static_cast<DagNode*>(dagNodeMap.getMap(dagNode));
125   if (d != 0)
126     return d;
127   //
128   //	Examine symbol to see if we have a special representation with its own
129   //	conversion scheme.
130   //
131   Symbol* s = dagNode->symbol();
132   switch (m->getSymbolType(s).getBasicType())
133     {
134     case SymbolType::QUOTED_IDENTIFIER:
135       {
136 	int id = static_cast<QuotedIdentifierDagNode*>(dagNode)->getIdIndex();
137 	d = upConstant(Token::quoteNameCode(id), dagNode, qidMap);
138 	break;
139       }
140     case SymbolType::STRING:
141       {
142 	string result;
143 	Token::ropeToString(static_cast<StringDagNode*>(dagNode)->getValue(), result);
144 	d = upConstant(Token::encode(result.c_str()), dagNode, qidMap);
145 	break;
146       }
147     case SymbolType::FLOAT:
148       {
149 	double mf = static_cast<FloatDagNode*>(dagNode)->getValue();
150 	d = upConstant(Token::doubleToCode(mf), dagNode, qidMap);
151 	break;
152       }
153     case SymbolType::SMT_NUMBER_SYMBOL:
154       {
155 	const mpq_class& value = safeCast(SMT_NumberDagNode*, dagNode)->getValue();
156 	d = upSMT_Number(value, s, m, qidMap);
157 	break;
158       }
159     case SymbolType::VARIABLE:
160       {
161 	VariableDagNode* v = safeCast(VariableDagNode*, dagNode);
162 	int id = (variableGenerator == 0) ? v->id() :
163 	  variableGenerator->getFreshVariableName(variableBase + v->getIndex());
164 	Sort* sort = safeCast(VariableSymbol*, dagNode->symbol())->getSort();
165 	d = upVariable(id, sort, qidMap);
166 	break;
167       }
168     default:
169       {
170 	int nrArgs = s->arity();
171 	if (nrArgs == 0)
172 	  d = upConstant(s->id(), dagNode, qidMap);
173 	else
174 	  {
175 	    args[0] = upQid(m->getSymbolType(s).hasFlag(SymbolType::ITER) ?
176 			    iterToken(dagNode) : s->id(),
177 			    qidMap);
178 	    DagArgumentIterator a(*dagNode);
179 	    if (nrArgs == 1)
180 	      args[1] = upDagNode(a.argument(), m, qidMap, dagNodeMap);
181 	    else
182 	      {
183 		//
184 		//	nrArgs is only a suggestion - flattened assoc operators may have more args.
185 		//
186 		Vector<DagNode*> args2(0, nrArgs);  // can't be static!
187 		for (; a.valid(); a.next())
188 		  args2.append(upDagNode(a.argument(), m, qidMap, dagNodeMap));
189 		args[1] = metaArgSymbol->makeDagNode(args2);
190 	      }
191 	    d = metaTermSymbol->makeDagNode(args);
192 	  }
193 	break;
194       }
195     }
196   (void) dagNodeMap.setMap(dagNode, d);
197   return d;
198 }
199 
200 DagNode*
upTerm(const Term * term,MixfixModule * m,PointerMap & qidMap)201 MetaLevel::upTerm(const Term* term, MixfixModule* m, PointerMap& qidMap)
202 {
203   Assert(term != 0, "null term");
204   Vector<DagNode*> args(2);  // can't be static!
205   //
206   //	Examine symbol to see if we have a special representation with its own
207   //	conversion scheme.
208   //
209 
210   Symbol* s = term->symbol();
211   switch (m->getSymbolType(s).getBasicType())
212     {
213     case SymbolType::QUOTED_IDENTIFIER:
214       {
215 	int id = static_cast<const QuotedIdentifierTerm*>(term)->getIdIndex();
216 	return upConstant(Token::quoteNameCode(id), MixfixModule::disambiguatorSort(term), qidMap);
217       }
218     case SymbolType::STRING:
219       {
220 	string result;
221 	Token::ropeToString(static_cast<const StringTerm*>(term)->getValue(), result);
222 	return upConstant(Token::encode(result.c_str()), MixfixModule::disambiguatorSort(term), qidMap);
223       }
224     case SymbolType::FLOAT:
225       {
226 	double mf = static_cast<const FloatTerm*>(term)->getValue();
227 	return upConstant(Token::doubleToCode(mf), MixfixModule::disambiguatorSort(term), qidMap);
228       }
229     case SymbolType::SMT_NUMBER_SYMBOL:
230       {
231 	const mpq_class& value = safeCast(const SMT_NumberTerm*, term)->getValue();
232 	return upSMT_Number(value, s, m, qidMap);
233       }
234     case SymbolType::VARIABLE:
235       {
236 	const VariableTerm* vt = safeCast(const VariableTerm*, term);
237 	return upVariable(vt->id(), vt->getSort(), qidMap);
238       }
239     default:
240       {
241 	int nrArgs = s->arity();
242 	if (nrArgs == 0)
243 	  return upConstant(s->id(), MixfixModule::disambiguatorSort(term), qidMap);
244 	else
245 	  {
246 	    int id = s->id();
247 	    if (m->getSymbolType(s).hasFlag(SymbolType::ITER))
248 	      {
249 		const mpz_class& number = safeCast(const S_Term*, term)->getNumber();
250 		if (number > 1)
251 		  {
252 		    string tmp(Token::name(id));
253 		    tmp += '^';
254 		    char* str = mpz_get_str(0, 10, number.get_mpz_t());
255 		    tmp += str;
256 		    free(str);
257 		    id = Token::encode(tmp.c_str());
258 		  }
259 	      }
260 	    args[0] = upQid(id, qidMap);
261 	    ArgumentIterator a(*(const_cast<Term*>(term)));
262 	    if (nrArgs == 1)
263 	      args[1] = upTerm(a.argument(), m, qidMap);
264 	    else
265 	      {
266 		//
267 		//	nrArgs is only a suggestion - flattened assoc operators may have more args.
268 		//
269 		Vector<DagNode*> args2(0, nrArgs);  // can't be static!
270 		for (; a.valid(); a.next())
271 		  args2.append(upTerm(a.argument(), m, qidMap));
272 		args[1] = metaArgSymbol->makeDagNode(args2);
273 	      }
274 	    return metaTermSymbol->makeDagNode(args);
275 	  }
276       }
277     }
278 }
279 
280 int
iterToken(DagNode * dagNode)281 MetaLevel::iterToken(DagNode* dagNode)
282 {
283   int id = dagNode->symbol()->id();
284   const mpz_class& number = safeCast(S_DagNode*, dagNode)->getNumber();
285   if (number == 1)
286     return id;
287   string tmp(Token::name(id));
288   tmp += '^';
289   char* str = mpz_get_str(0, 10, number.get_mpz_t());
290   tmp += str;
291   free(str);
292   return Token::encode(tmp.c_str());
293 }
294 
295 DagNode*
upContext(DagNode * dagNode,MixfixModule * m,DagNode * hole,PointerMap & qidMap,PointerMap & dagNodeMap)296 MetaLevel::upContext(DagNode* dagNode,
297 		     MixfixModule* m,
298 		     DagNode* hole,
299 		     PointerMap& qidMap,
300 		     PointerMap& dagNodeMap)
301 {
302   Assert(dagNode != 0, "null dagNode");
303   //
304   //	See if we have already up'd this dag node via a different path.
305   //
306   if (DagNode *d = static_cast<DagNode*>(dagNodeMap.getMap(dagNode)))
307     return d;
308   //
309   //	See if our node is the hole.
310   //
311   if (dagNode == hole)
312     return holeSymbol->makeDagNode();
313   //
314   //	Constants cannot contain the hole.
315   //
316   Symbol* s = dagNode->symbol();
317   int nrArgs = s->arity();
318   if (nrArgs == 0)
319     return upDagNode(dagNode, m, qidMap, dagNodeMap);
320   //
321   //	Usual case.
322   //
323   Vector<DagNode*> args(2);  // can't be static!
324   args[0] = upQid(m->getSymbolType(s).hasFlag(SymbolType::ITER) ?
325 		  iterToken(dagNode) : s->id(),
326 		  qidMap);
327   DagArgumentIterator a(*dagNode);
328   if (nrArgs == 1)
329     args[1] = upContext(a.argument(), m, hole, qidMap, dagNodeMap);
330   else
331     {
332       Vector<DagNode*> args2(0, nrArgs);  // can't be static!
333       for (; a.valid(); a.next())
334 	args2.append(upContext(a.argument(), m, hole, qidMap, dagNodeMap));
335       args[1] = metaArgSymbol->makeDagNode(args2);
336     }
337   DagNode* d = metaTermSymbol->makeDagNode(args);
338   (void) dagNodeMap.setMap(dagNode, d);
339   return d;
340 }
341 
342 DagNode*
upResultPair(DagNode * dagNode,MixfixModule * m)343 MetaLevel::upResultPair(DagNode* dagNode, MixfixModule* m)
344 {
345   Assert(dagNode != 0, "null dagNode");
346   static Vector<DagNode*> args(2);
347   PointerMap qidMap;
348   PointerMap dagNodeMap;
349   args[0] = upDagNode(dagNode, m, qidMap, dagNodeMap);
350   args[1] = upType(dagNode->getSort(), qidMap);
351   return resultPairSymbol->makeDagNode(args);
352 }
353 
354 DagNode*
upResultPair(Term * term,MixfixModule * m)355 MetaLevel::upResultPair(Term* term, MixfixModule* m)
356 {
357   Assert(term != 0, "null term");
358   static Vector<DagNode*> args(2);
359   PointerMap qidMap;
360   args[0] = upTerm(term, m, qidMap);
361   args[1] = upType(term->getSort(), qidMap);
362   return resultPairSymbol->makeDagNode(args);
363 }
364 
365 DagNode*
upResultTriple(DagNode * dagNode,const Substitution & substitution,const VariableInfo & variableInfo,MixfixModule * m)366 MetaLevel::upResultTriple(DagNode* dagNode,
367 			  const Substitution& substitution,
368 			  const VariableInfo& variableInfo,
369 			  MixfixModule* m)
370 {
371   Assert(dagNode != 0, "null dagNode");
372   static Vector<DagNode*> args(3);
373   PointerMap qidMap;
374   PointerMap dagNodeMap;
375   args[0] = upDagNode(dagNode, m, qidMap, dagNodeMap);
376   args[1] = upType(dagNode->getSort(), qidMap);
377   args[2] = upSubstitution(substitution, variableInfo, m, qidMap, dagNodeMap);
378   return resultTripleSymbol->makeDagNode(args);
379 }
380 
381 DagNode*
upResult4Tuple(DagNode * dagNode,const Substitution & substitution,const VariableInfo & variableInfo,DagNode * metaContext,MixfixModule * m)382 MetaLevel::upResult4Tuple(DagNode* dagNode,
383 			  const Substitution& substitution,
384 			  const VariableInfo& variableInfo,
385 			  DagNode* metaContext,
386 			  MixfixModule* m)
387 {
388   Assert(dagNode != 0, "null dagNode");
389   static Vector<DagNode*> args(4);
390   PointerMap qidMap;
391   PointerMap dagNodeMap;
392   args[0] = upDagNode(dagNode, m, qidMap, dagNodeMap);
393   args[1] = upType(dagNode->getSort(), qidMap);
394   args[2] = upSubstitution(substitution, variableInfo, m, qidMap, dagNodeMap);
395   args[3] = metaContext;
396   return result4TupleSymbol->makeDagNode(args);
397 }
398 
399 DagNode*
upUnificationPair(const Substitution & substitution,const VariableInfo & variableInfo,const mpz_class & variableIndex,MixfixModule * m)400 MetaLevel::upUnificationPair(const Substitution& substitution,
401 			     const VariableInfo& variableInfo,
402 			     const mpz_class& variableIndex,
403 			     MixfixModule* m)
404 {
405   PointerMap qidMap;
406   PointerMap dagNodeMap;
407   Vector<DagNode*> args(2);
408   args[0] = upSubstitution(substitution, variableInfo, m, qidMap, dagNodeMap);
409   args[1] = succSymbol->makeNatDag(variableIndex);
410   return unificationPairSymbol->makeDagNode(args);
411 }
412 
413 DagNode*
upUnificationTriple(const Substitution & substitution,const VariableInfo & variableInfo,const mpz_class & variableIndex,MixfixModule * m)414 MetaLevel::upUnificationTriple(const Substitution& substitution,
415 			       const VariableInfo& variableInfo,
416 			       const mpz_class& variableIndex,
417 			       MixfixModule* m)
418 {
419   PointerMap qidMap;
420   PointerMap dagNodeMap;
421   Vector<DagNode*> args(3);
422   upDisjointSubstitutions(substitution,
423 			  variableInfo,
424 			  m,
425 			  qidMap,
426 			  dagNodeMap,
427 			  args[0],
428 			  args[1]);
429   args[2] = succSymbol->makeNatDag(variableIndex);
430   return unificationTripleSymbol->makeDagNode(args);
431 }
432 
433 
434 void
upDisjointSubstitutions(const Substitution & substitution,const VariableInfo & variableInfo,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap,DagNode * & left,DagNode * & right)435 MetaLevel::upDisjointSubstitutions(const Substitution& substitution,
436 				   const VariableInfo& variableInfo,
437 				   MixfixModule* m,
438 				   PointerMap& qidMap,
439 				   PointerMap& dagNodeMap,
440 				   DagNode*& left,
441 				   DagNode*& right)
442 {
443   int nrVariables = variableInfo.getNrRealVariables();
444   Vector<DagNode*> leftArgs(0, nrVariables);
445   Vector<DagNode*> rightArgs(0, nrVariables);
446   for (int i = 0; i < nrVariables; i++)
447     {
448       VariableTerm* variable = safeCast(VariableTerm*, variableInfo.index2Variable(i));
449       DagNode* d = upAssignment(variable,
450 				substitution.value(i),
451 				m,
452 				qidMap,
453 				dagNodeMap);
454       if (Token::isFlagged(variable->id()))
455 	rightArgs.append(d);
456       else
457 	leftArgs.append(d);
458     }
459   int nrLeftArgs = leftArgs.size();
460   if (nrLeftArgs == 0)
461     left = emptySubstitutionSymbol->makeDagNode();
462   else if (nrLeftArgs == 1)
463     left = leftArgs[0];
464   else
465     left = substitutionSymbol->makeDagNode(leftArgs);
466   int nrRightArgs = rightArgs.size();
467   if (nrRightArgs == 0)
468     right = emptySubstitutionSymbol->makeDagNode();
469   else if (nrRightArgs == 1)
470     right = rightArgs[0];
471   else
472     right = substitutionSymbol->makeDagNode(rightArgs);
473 }
474 
475 DagNode*
upSubstitution(const Substitution & substitution,const VariableInfo & variableInfo,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)476 MetaLevel::upSubstitution(const Substitution& substitution,
477 			  const VariableInfo& variableInfo,
478 			  MixfixModule* m,
479 			  PointerMap& qidMap,
480 			  PointerMap& dagNodeMap)
481 {
482   int nrVariables = variableInfo.getNrRealVariables();
483   if (nrVariables == 0)
484     return emptySubstitutionSymbol->makeDagNode();
485   if (nrVariables == 1)
486     {
487       return upAssignment(variableInfo.index2Variable(0),
488 			  substitution.value(0),
489 			  m,
490 			  qidMap,
491 			  dagNodeMap);
492     }
493   Vector<DagNode*> args(nrVariables);
494   for (int i = 0; i < nrVariables; i++)
495     {
496       args[i] = upAssignment(variableInfo.index2Variable(i),
497 			     substitution.value(i),
498 			     m,
499 			     qidMap,
500 			     dagNodeMap);
501     }
502   return substitutionSymbol->makeDagNode(args);
503 }
504 
505 DagNode*
upAssignment(const Term * variable,DagNode * value,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)506 MetaLevel::upAssignment(const Term* variable,
507 			DagNode* value,
508 			MixfixModule* m,
509 			PointerMap& qidMap,
510 			PointerMap& dagNodeMap)
511 {
512   static Vector<DagNode*> args(2);
513   args[0] = upTerm(variable, m, qidMap);
514   args[1] = upDagNode(value, m, qidMap, dagNodeMap);
515   return assignmentSymbol->makeDagNode(args);
516 }
517 
518 DagNode*
upAssignment(DagNode * variable,DagNode * value,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)519 MetaLevel::upAssignment(DagNode* variable,
520 			DagNode* value,
521 			MixfixModule* m,
522 			PointerMap& qidMap,
523 			PointerMap& dagNodeMap)
524 {
525   static Vector<DagNode*> args(2);
526   args[0] = upDagNode(variable, m, qidMap, dagNodeMap);
527   args[1] = upDagNode(value, m, qidMap, dagNodeMap);
528   return assignmentSymbol->makeDagNode(args);
529 }
530 
531 DagNode*
upSmtSubstitution(const Substitution & substitution,const VariableInfo & variableInfo,const NatSet & smtVariables,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)532 MetaLevel::upSmtSubstitution(const Substitution& substitution,
533 			     const VariableInfo& variableInfo,
534 			     const NatSet& smtVariables,
535 			     MixfixModule* m,
536 			     PointerMap& qidMap,
537 			     PointerMap& dagNodeMap)
538 {
539   int nrVariables = variableInfo.getNrRealVariables();
540   Vector<DagNode*> args;
541 
542   for (int i = 0; i < nrVariables; i++)
543     {
544       //
545       //	SMT variables are constrained rather than bound.
546       //
547       if (!smtVariables.contains(i))
548 	{
549 	  args.append(upAssignment(variableInfo.index2Variable(0),
550 				   substitution.value(0),
551 				   m,
552 				   qidMap,
553 				   dagNodeMap));
554 	}
555     }
556 
557   int nrBindings = args.size();
558   if (nrBindings == 0)
559     return emptySubstitutionSymbol->makeDagNode();
560   if (nrBindings == 1)
561     return args[0];
562   return substitutionSymbol->makeDagNode(args);
563 }
564 
565 DagNode*
upSmtResult(DagNode * state,const Substitution & substitution,const VariableInfo & variableInfo,const NatSet & smtVariables,DagNode * constraint,const mpz_class & variableNumber,MixfixModule * m)566 MetaLevel::upSmtResult(DagNode* state,
567 		       const Substitution& substitution,
568 		       const VariableInfo& variableInfo,
569 		       const NatSet& smtVariables,
570 		       DagNode* constraint,
571 		       const mpz_class& variableNumber,
572 		       MixfixModule* m)
573 {
574   Assert(state != 0, "null state");
575   Assert(constraint != 0, "null constraint");
576   Vector<DagNode*> args(4);
577   PointerMap qidMap;
578   PointerMap dagNodeMap;
579   args[0] = upDagNode(state, m, qidMap, dagNodeMap);
580   args[1] = upSmtSubstitution(substitution,
581 			     variableInfo,
582 			     smtVariables,
583 			     m,
584 			     qidMap,
585 			      dagNodeMap);
586   args[2] = upDagNode(constraint, m, qidMap, dagNodeMap);
587   args[3] = succSymbol->makeNatDag(variableNumber);
588   return smtResultSymbol->makeDagNode(args);
589 }
590 
591 DagNode*
upSmtFailure()592 MetaLevel::upSmtFailure()
593 {
594   return smtFailureSymbol->makeDagNode();
595 }
596 
597 DagNode*
upFailurePair()598 MetaLevel::upFailurePair()
599 {
600   return failure2Symbol->makeDagNode();
601 }
602 
603 DagNode*
upFailureTriple()604 MetaLevel::upFailureTriple()
605 {
606   return failure3Symbol->makeDagNode();
607 }
608 
609 DagNode*
upNoUnifierPair(bool incomplete)610 MetaLevel::upNoUnifierPair(bool incomplete)
611 {
612   return (incomplete ? noUnifierIncompletePairSymbol : noUnifierPairSymbol)->makeDagNode();
613 }
614 
615 DagNode*
upNoUnifierTriple(bool incomplete)616 MetaLevel::upNoUnifierTriple(bool incomplete)
617 {
618   return (incomplete ? noUnifierIncompleteTripleSymbol : noUnifierTripleSymbol)->makeDagNode();
619 }
620 
621 DagNode*
upNoMatchSubst()622 MetaLevel::upNoMatchSubst()
623 {
624   return noMatchSubstSymbol->makeDagNode();
625 }
626 
627 DagNode*
upNoMatchPair()628 MetaLevel::upNoMatchPair()
629 {
630   return noMatchPairSymbol->makeDagNode();
631 }
632 
633 DagNode*
upMatchPair(const Substitution & substitution,const VariableInfo & variableInfo,DagNode * dagNode,DagNode * hole,MixfixModule * m)634 MetaLevel::upMatchPair(const Substitution& substitution,
635 		       const VariableInfo& variableInfo,
636 		       DagNode* dagNode,
637 		       DagNode* hole,
638 		       MixfixModule* m)
639 {
640   PointerMap qidMap;
641   PointerMap dagNodeMap;
642   static Vector<DagNode*> args(2);
643   args[0] = upSubstitution(substitution, variableInfo, m, qidMap, dagNodeMap);
644   args[1] = upContext(dagNode, m, hole, qidMap, dagNodeMap);
645   return matchPairSymbol->makeDagNode(args);
646 }
647 
648 DagNode*
upFailure4Tuple()649 MetaLevel::upFailure4Tuple()
650 {
651   return failure4Symbol->makeDagNode();
652 }
653 
654 DagNode*
upTrace(const RewriteSequenceSearch & state,MixfixModule * m)655 MetaLevel::upTrace(const RewriteSequenceSearch& state, MixfixModule* m)
656 {
657   Vector<int> steps;
658   for (int i = state.getStateNr(); i != 0; i = state.getStateParent(i))
659     steps.append(i);
660 
661   int nrSteps = steps.size();
662   if (nrSteps == 0)
663     return nilTraceSymbol->makeDagNode();
664 
665   Vector<DagNode*> args(nrSteps);
666   PointerMap qidMap;
667   PointerMap dagNodeMap;
668   int j = 0;
669   for (int i = nrSteps - 1; i >= 0; --i, ++j)
670     args[j] = upTraceStep(state, steps[i], m, qidMap, dagNodeMap);
671   return (nrSteps == 1) ? args[0] : traceSymbol->makeDagNode(args);
672 }
673 
674 DagNode*
upTraceStep(const RewriteSequenceSearch & state,int stateNr,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)675 MetaLevel::upTraceStep(const RewriteSequenceSearch& state,
676 		       int stateNr,
677 		       MixfixModule* m,
678 		       PointerMap& qidMap,
679 		       PointerMap& dagNodeMap)
680 {
681   static Vector<DagNode*> args(3);
682   int parentNr = state.getStateParent(stateNr);
683   DagNode* dagNode = state.getStateDag(parentNr);
684   args[0] = upDagNode(dagNode, m, qidMap, dagNodeMap);
685   args[1] = upType(dagNode->getSort(), qidMap);
686   args[2] = upRl(state.getStateRule(stateNr), m, qidMap);
687   return traceStepSymbol->makeDagNode(args);
688 }
689 
690 DagNode*
upFailureTrace()691 MetaLevel::upFailureTrace()
692 {
693   return failureTraceSymbol->makeDagNode();
694 }
695 
696 DagNode*
upNoParse(int badTokenIndex)697 MetaLevel::upNoParse(int badTokenIndex)
698 {
699   static Vector<DagNode*> args(1);
700   args[0] = succSymbol->makeNatDag(badTokenIndex);
701   return noParseSymbol->makeDagNode(args);
702 }
703 
704 DagNode*
upAmbiguity(Term * parse1,Term * parse2,MixfixModule * m)705 MetaLevel::upAmbiguity(Term* parse1, Term* parse2, MixfixModule* m)
706 {
707   Assert(parse1 != 0 && parse2 != 0, "null term");
708   static Vector<DagNode*> args(2);
709   static Vector<DagNode*> args2(2);
710   PointerMap qidMap;
711   args[0] = upTerm(parse1, m, qidMap);
712   args[1] = upType(parse1->getSort(), qidMap);
713   args2[0] = resultPairSymbol->makeDagNode(args);
714   args[0] = upTerm(parse2, m, qidMap);
715   args[1] = upType(parse2->getSort(), qidMap);
716   args2[1] = resultPairSymbol->makeDagNode(args);
717   return ambiguitySymbol->makeDagNode(args2);
718 }
719 
720 DagNode*
upBool(bool value)721 MetaLevel::upBool(bool value)
722 {
723   return value ? trueTerm.getDag() : falseTerm.getDag();
724 }
725 
726 DagNode*
upKindSet(const Vector<ConnectedComponent * > & kinds)727 MetaLevel::upKindSet(const Vector<ConnectedComponent*>& kinds)
728 {
729   int nrKinds = kinds.length();
730   if (nrKinds == 0)
731     return new FreeDagNode(emptySortSetSymbol);
732   PointerMap qidMap;
733   if (nrKinds == 1)
734     return upType(kinds[0]->sort(0), qidMap);
735   Vector<DagNode*> args(nrKinds);
736   for (int i = 0; i < nrKinds; i++)
737     args[i] = upType(kinds[i]->sort(0), qidMap);
738   return sortSetSymbol->makeDagNode(args);
739 }
740 
741 DagNode*
upSortSet(const Vector<Sort * > & sorts)742 MetaLevel::upSortSet(const Vector<Sort*>& sorts)
743 {
744   PointerMap qidMap;
745   return upSortSet(sorts, 0, sorts.length(), qidMap);
746 }
747 
748 DagNode*
upSortSet(const Vector<Sort * > & sorts,int begin,int nrSorts,PointerMap & qidMap)749 MetaLevel::upSortSet(const Vector<Sort*>& sorts,
750 		     int begin,
751 		     int nrSorts,
752 		     PointerMap& qidMap)
753 {
754   if (nrSorts == 0)
755     return new FreeDagNode(emptySortSetSymbol);
756   if (nrSorts == 1)
757     return upType(sorts[begin], qidMap);
758   Vector<DagNode*> args(nrSorts);
759   for (int i = 0; i < nrSorts; i++, begin++)
760     args[i] = upType(sorts[begin], qidMap);
761   return sortSetSymbol->makeDagNode(args);
762 }
763 
764 DagNode*
upQidList(const Vector<int> & ids)765 MetaLevel::upQidList(const Vector<int>& ids)
766 {
767   PointerMap qidMap;
768   return upQidList(ids, qidMap);
769 }
770 
771 DagNode*
upQidList(const Vector<int> & ids,PointerMap & qidMap)772 MetaLevel::upQidList(const Vector<int>& ids, PointerMap& qidMap)
773 {
774   int nrIds = ids.length();
775   if (nrIds == 0)
776     return new FreeDagNode(nilQidListSymbol);
777   if (nrIds == 1)
778     return new QuotedIdentifierDagNode(qidSymbol, Token::backQuoteSpecials(ids[0]));
779   Vector<DagNode*> args(nrIds);
780   for (int i = 0; i < nrIds; i++)
781     args[i] = upQid(ids[i], qidMap);
782   return qidListSymbol->makeDagNode(args);
783 }
784 
785 DagNode*
upTypeListSet(const Vector<OpDeclaration> & opDecls,const NatSet & chosenDecls,PointerMap & qidMap)786 MetaLevel::upTypeListSet(const Vector<OpDeclaration>& opDecls,
787 			 const NatSet& chosenDecls,
788 			 PointerMap& qidMap)
789 {
790   Vector<DagNode*> args;
791   FOR_EACH_CONST(i, NatSet, chosenDecls)
792     args.append(upTypeList(opDecls[*i].getDomainAndRange(), true, qidMap));
793   int nrArgs = args.size();
794   if (nrArgs == 0)
795     return new FreeDagNode(emptySortSetSymbol);
796   if (nrArgs == 1)
797     return args[0];
798   return sortSetSymbol->makeDagNode(args);
799 }
800 
801 DagNode*
upTypeList(const Vector<Sort * > & types,bool omitLast,PointerMap & qidMap)802 MetaLevel::upTypeList(const Vector<Sort*>& types,
803 		      bool omitLast,
804 		      PointerMap& qidMap)
805 {
806   int nrTypes = types.size();
807   if (omitLast)
808     --nrTypes;
809   if (nrTypes == 0)
810     return new FreeDagNode(nilQidListSymbol);
811   if (nrTypes == 1)
812     return upType(types[0], qidMap);
813   Vector<DagNode*> args(nrTypes);
814   for (int i = 0; i < nrTypes; ++i)
815     args[i] = upType(types[i], qidMap);
816   return qidListSymbol->makeDagNode(args);
817 }
818 
819 DagNode*
upSubstitution(const Vector<DagNode * > & substitution,const NarrowingVariableInfo & variableInfo,int nrVariables,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap)820 MetaLevel::upSubstitution(const Vector<DagNode*>& substitution,
821 			  const NarrowingVariableInfo& variableInfo,
822 			  int nrVariables,
823 			  MixfixModule* m,
824 			  PointerMap& qidMap,
825 			  PointerMap& dagNodeMap)
826 {
827   if (nrVariables == 0)
828     return emptySubstitutionSymbol->makeDagNode();
829   else if (nrVariables == 1)
830     {
831       return upAssignment(variableInfo.index2Variable(0),
832 			  substitution[0],
833 			  m,
834 			  qidMap,
835 			  dagNodeMap);
836     }
837 
838   Vector<DagNode*> args(nrVariables);
839   for (int i = 0; i < nrVariables; ++i)
840     {
841       args[i] = upAssignment(variableInfo.index2Variable(i),
842 			     substitution[i],
843 			     m,
844 			     qidMap,
845 			     dagNodeMap);
846     }
847   return substitutionSymbol->makeDagNode(args);
848 }
849 
850 DagNode*
upUnificationPair(const Vector<DagNode * > & unifier,const NarrowingVariableInfo & variableInfo,const mpz_class & variableIndex,MixfixModule * m)851 MetaLevel::upUnificationPair(const Vector<DagNode*>& unifier,
852 			     const NarrowingVariableInfo& variableInfo,
853 			     const mpz_class& variableIndex,
854 			     MixfixModule* m)
855 {
856   PointerMap qidMap;
857   PointerMap dagNodeMap;
858   Vector<DagNode*> args(2);
859 
860   args[0] = upSubstitution(unifier, variableInfo, unifier.size(), m, qidMap, dagNodeMap);
861   args[1] = succSymbol->makeNatDag(variableIndex);
862   return unificationPairSymbol->makeDagNode(args);
863 }
864 
865 void
upDisjointSubstitutions(const Vector<DagNode * > & unifier,const NarrowingVariableInfo & variableInfo,MixfixModule * m,PointerMap & qidMap,PointerMap & dagNodeMap,DagNode * & left,DagNode * & right)866 MetaLevel::upDisjointSubstitutions(const Vector<DagNode*>& unifier,
867 				   const NarrowingVariableInfo& variableInfo,
868 				   MixfixModule* m,
869 				   PointerMap& qidMap,
870 				   PointerMap& dagNodeMap,
871 				   DagNode*& left,
872 				   DagNode*& right)
873 {
874   int nrVariables = unifier.size();
875   Vector<DagNode*> leftArgs(0, nrVariables);
876   Vector<DagNode*> rightArgs(0, nrVariables);
877   for (int i = 0; i < nrVariables; i++)
878     {
879       VariableDagNode* variable = variableInfo.index2Variable(i);
880       DagNode* d = upAssignment(variable,
881 				unifier[i],
882 				m,
883 				qidMap,
884 				dagNodeMap);
885       if (Token::isFlagged(variable->id()))
886 	rightArgs.append(d);
887       else
888 	leftArgs.append(d);
889     }
890   int nrLeftArgs = leftArgs.size();
891   if (nrLeftArgs == 0)
892     left = emptySubstitutionSymbol->makeDagNode();
893   else if (nrLeftArgs == 1)
894     left = leftArgs[0];
895   else
896     left = substitutionSymbol->makeDagNode(leftArgs);
897   int nrRightArgs = rightArgs.size();
898   if (nrRightArgs == 0)
899     right = emptySubstitutionSymbol->makeDagNode();
900   else if (nrRightArgs == 1)
901     right = rightArgs[0];
902   else
903     right = substitutionSymbol->makeDagNode(rightArgs);
904 }
905 
906 DagNode*
upUnificationTriple(const Vector<DagNode * > & unifier,const NarrowingVariableInfo & variableInfo,const mpz_class & variableIndex,MixfixModule * m)907 MetaLevel::upUnificationTriple(const Vector<DagNode*>& unifier,
908 			       const NarrowingVariableInfo& variableInfo,
909 			       const mpz_class& variableIndex,
910 			       MixfixModule* m)
911 {
912   PointerMap qidMap;
913   PointerMap dagNodeMap;
914   Vector<DagNode*> args(3);
915 
916   upDisjointSubstitutions(unifier, variableInfo, m, qidMap, dagNodeMap, args[0], args[1]);
917   args[2] = succSymbol->makeNatDag(variableIndex);
918   return unificationTripleSymbol->makeDagNode(args);
919 }
920 
921 DagNode*
upVariant(const Vector<DagNode * > & variant,const NarrowingVariableInfo & variableInfo,const mpz_class & variableIndex,const mpz_class & parentIndex,bool moreInLayer,MixfixModule * m)922 MetaLevel::upVariant(const Vector<DagNode*>& variant,
923 		     const NarrowingVariableInfo& variableInfo,
924 		     const mpz_class& variableIndex,
925 		     const mpz_class& parentIndex,
926 		     bool moreInLayer,
927 		     MixfixModule* m)
928 {
929   PointerMap qidMap;
930   PointerMap dagNodeMap;
931   Vector<DagNode*> args(5);
932 
933   int nrVariables = variant.size() - 1;
934   args[0] = upDagNode(variant[nrVariables], m, qidMap, dagNodeMap);
935   args[1] = upSubstitution(variant, variableInfo, nrVariables, m, qidMap, dagNodeMap);
936   args[2] = succSymbol->makeNatDag(variableIndex);
937   args[3] = (parentIndex >= 0) ? succSymbol->makeNatDag(parentIndex) :
938     noParentSymbol->makeDagNode();
939   args[4] = upBool(moreInLayer);
940   return variantSymbol->makeDagNode(args);
941 }
942 
943 DagNode*
upNoVariant(bool incomplete)944 MetaLevel::upNoVariant(bool incomplete)
945 {
946   return (incomplete ? noVariantIncompleteSymbol : noVariantSymbol)->makeDagNode();
947 }
948 
949 DagNode*
upSMT_Number(const mpq_class & value,Symbol * symbol,MixfixModule * m,PointerMap & qidMap)950 MetaLevel::upSMT_Number(const mpq_class& value, Symbol* symbol, MixfixModule* m, PointerMap& qidMap)
951 {
952   Sort* sort = symbol->getRangeSort();
953   int id = m->getSMT_NumberToken(value, sort);
954   return upJoin(id, sort, '.', qidMap);
955 }
956