The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
EquivalenceClass.cs
Go to the documentation of this file.
1 // -------------------------------------------------------------------------- //
3 // Project rROTOR //
4 // -------------------------------------------------------------------------- //
5 // File: EquivalenceClass.cs //
6 // Author: Francisco Ortin- francisco.ortin@gmail.com //
7 // Description: //
8 // Represents a equivalence class of type varariables [Aho]. //
9 // -------------------------------------------------------------------------- //
10 // Create date: 03-04-2007 //
12 //visto
13 using System;
14 using System.Collections.Generic;
15 using System.Text;
16 using Tools;
17 using TypeSystem.Operations;
18 
19 namespace TypeSystem {
20  public class EquivalenceClass {
21  #region Fields
22  private IDictionary<int, TypeVariable> typeVariables = new Dictionary<int, TypeVariable>();
26 
30  private TypeExpression substitution;
31  #endregion
32 
33  #region Properties
34  public IDictionary<int, TypeVariable> TypeVariables {
38  get { return typeVariables; }
39  }
40 
45  get { return substitution; }
46  }
47  #endregion
48 
49 
50  #region Constructors
51  public EquivalenceClass() { }
52 
54  if (!(te is TypeVariable))
55  throw new ArgumentException("I need a type variable, not a " + te);
56  add(te, SortOfUnification.Equivalent, new List<Pair<TypeExpression, TypeExpression>>());
57  }
58  #endregion
59 
60  private static int numero = 0;
61  #region Add
62  public bool add(TypeExpression te, SortOfUnification unification, IList<Pair<TypeExpression, TypeExpression>> previouslyUnified) {
70  TypeVariable tv = te as TypeVariable;
71  if (tv != null) { // * Another type variable
72  // * Tries to add its substitution
73  if (tv.Substitution != null) // * If it has a substitution
74  if (!this.add(tv.EquivalenceClass.Substitution, unification, previouslyUnified)) // * We try to add it to ourselves
75  return false; // * Both susbstitutions are not the same
76  // * If no error, we add it to the equivalence class
77  this.typeVariables[tv.Variable] = tv;
78  if (tv.EquivalenceClass != null) { // * The parameter already has a equivalence class
79  IList<int> keys = new List<int>(tv.EquivalenceClass.TypeVariables.Keys);
80  foreach (int pairKey in keys) {
81  if (!this.typeVariables.ContainsKey(pairKey)) {
82  // * We recursively add all the element of the equivalence class
83  this.typeVariables[pairKey] = tv.EquivalenceClass.TypeVariables[pairKey];
84  this.add(tv.EquivalenceClass.TypeVariables[pairKey], unification, previouslyUnified);
85  }
86  }
87  }
88  // * Finally, we update the equivalence class of tv
89  tv.EquivalenceClass = this;
90  return true;
91  }
92  // * te is not a type variable
93  if (this.substitution != null) {
94  // * A substitution already exists
95  if (unification == SortOfUnification.Equivalent) {
96  // * They must be equivalent
97  if ( !(bool)this.substitution.AcceptOperation(new EquivalentOperation(te), null) )
98  return false;
99  if (te.HasTypeVariables())
100  // var1=Array(int) must be unified to Array(var1)
101  return te.Unify(this.substitution, unification, previouslyUnified);
102  return true;
103  }
104  if (unification == SortOfUnification.Incremental) {
105  // * The incremental behaviour implies a union of all the types
106  this.substitution = UnionType.collect(this.substitution, te);
107  return true;
108  }
109  // * Override unification (the susbstitution is overridden)
110  this.substitution = te;
111  return true;
112  }
113  // * We set the type as a susbstitution
114  substitution = te;
115  return true;
116  }
117  #endregion
118 
119  private string cachedToString = "";
120  #region ToString()
121  public override string ToString() {
127  StringBuilder sb = new StringBuilder("{");
128  ICollection<int> keys = typeVariables.Keys;
129  int i = 0;
130  foreach (int key in keys)
131  {
132  sb.Append(key);
133  if (i < keys.Count - 1)
134  sb.Append(",");
135  i++;
136  }
137  sb.Append("}");
138  return sb.ToString();
139  }
140  #endregion
141 
142 
143 
144  #region UpdateEquivalenceClass()
145  public void UpdateEquivalenceClass(IDictionary<TypeVariable, TypeVariable> typeVariableMappings) {
154  // * Creates a new equivalence class
155  EquivalenceClass newEquivalenceClass = new EquivalenceClass();
156  // * We take the existing substitution...
157  newEquivalenceClass.substitution = this.substitution;
158  // ... changing old type variables for new ones
159  if (newEquivalenceClass.substitution != null)
160  newEquivalenceClass.substitution.ReplaceTypeVariables(typeVariableMappings);
161  // * We update all the appropiate type variables
162  newEquivalenceClass.typeVariables = new Dictionary<int, TypeVariable>();
163  foreach (KeyValuePair<int, TypeVariable> oldPair in this.typeVariables) {
164  // * Is there a new type variable for the existing one?
165  if (typeVariableMappings.ContainsKey(oldPair.Value)) {
166  // * We create a new entry with the new one...
167  TypeVariable newTypeVariable = typeVariableMappings[oldPair.Value];
168  newEquivalenceClass.typeVariables[newTypeVariable.Variable] = newTypeVariable;
169  // * ... and updates the class equivalence of the new type variable
170  newTypeVariable.EquivalenceClass = newEquivalenceClass;
171  newTypeVariable.ValidTypeExpression = false;
172  }
173  else // * Otherwise, the old one is kept
174  newEquivalenceClass.typeVariables[oldPair.Key] = oldPair.Value;
175  }
176  // * Finally, we update all the equivalence classes of the substitution if its exists
177  if (newEquivalenceClass.substitution != null)
178  newEquivalenceClass.substitution.UpdateEquivalenceClass(typeVariableMappings, new List<TypeExpression>());
179  }
180  #endregion
181 
182  // SSA
183 
184  #region CloneTypeVariables()
185  internal void CloneTypeVariables(IDictionary<int, TypeVariable> clonedTypeVariables, IList<EquivalenceClass> equivalenceClasses, MethodType methodAnalyzed) {
196  // * Checks if the equivalence class has been already cloned
197  if (equivalenceClasses.Contains(this))
198  return;
199  // * Adds class equivalence
200  equivalenceClasses.Add(this);
201  // * Clones, but not updates, the substitution
202  if (this.substitution!=null)
203  this.substitution.Clone(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
204  // * Clones all the type variables in the equivalence class
205  foreach (KeyValuePair<int, TypeVariable> pair in this.typeVariables)
206  pair.Value.Clone(clonedTypeVariables, equivalenceClasses, methodAnalyzed);
207  }
208  #endregion
209 
210  // Loop Detection
211 
218  public bool Remove(TypeVariable toRemove) {
219  return this.typeVariables.Remove(toRemove.Variable);
220  }
221  }
222 }
TypeExpression Substitution
A equivalence class could be bounded to a unique no variable type
EquivalenceClass(TypeExpression te)
bool Remove(TypeVariable toRemove)
When loops are detected, it is necesary to suppress a new extra variable returned in the return type ...
IDictionary< int, TypeVariable > TypeVariables
All the type variables that must be substituted with the same value
Abstract class that represents all different types.
Represents a generic type expression
Definition: TypeVariable.cs:36
System.Text.StringBuilder StringBuilder
Definition: CSharpParser.cs:4
No location information is provided within this class, because the exec methods invoked by the proper...
virtual bool HasTypeVariables()
To know if the type expression has some type variables and requieres unification The default implemen...
void UpdateEquivalenceClass(IDictionary< TypeVariable, TypeVariable > typeVariableMappings)
Replaces the equivalence class substituting the old type variables for the new ones. The substitution is not altered. Since equivalence classes and type variables have a bidirectional association, the new equivalence classes will make type variables update their new equivalence classes.
override string ToString()
The ToString of its substitution
bool add(TypeExpression te, SortOfUnification unification, IList< Pair< TypeExpression, TypeExpression >> previouslyUnified)
To add a new type to the class equivalence.
TypeExpression Substitution
Gets the substitution; null if it does not exist
abstract bool Unify(TypeExpression te, SortOfUnification unification, IList< Pair< TypeExpression, TypeExpression >> previouslyUnified)
Requires the implicit object to be a subtype of the type parameter
EquivalenceClass EquivalenceClass
The equivalence class of the type variable (see the dragon book)
Definition: TypeVariable.cs:88