public Relation ResolveRelation(Relation r, Stack <Constraint> visited, Relation parent) { /// NOTES: It may become neccessary to resolve in stages, first resolve variables, then /// resolve relations. This would make it easier to catch variables which are just /// aliases for each other. I am not sure at this point, whether such a condition /// could arise. I may alternatively choose to simply rename all generics, but that /// would have a significant computational cost. r.SetParent(parent); r.GetNonGenericsForChildren().AddRange(r.GetAllVarNames()); Vector vLeft = new Vector(); Vector vRight = new Vector(); VarNameList allVars = new VarNameList(); VarNameList topVars = new VarNameList(); foreach (Constraint c in r.GetLeft()) { vLeft.Add(ResolveRelationConstraint(c, visited, r, topVars, allVars)); } foreach (Constraint c in r.GetRight()) { vRight.Add(ResolveRelationConstraint(c, visited, r, topVars, allVars)); } Relation ret = new Relation(vLeft, vRight); // Make sure we set the parent for the newly created relation as well ret.SetParent(parent); Log("Resolved relation " + r.ToString()); Log("to " + ret.ToString()); Log("non-generics = " + r.GetNonGenericsForChildren()); return(ret); }
public void RenameGenericVars(Relation rel) { Dictionary <string, string> newNames = new Dictionary <string, string>(); VarNameList generics = rel.GetGenericVars(); Log("Generics of " + rel.ToString() + " are " + generics.ToString()); // TODO: temp if (rel.GetParent() == null) { Log(rel.ToString() + " has no parent"); } else { Log("Parent of " + rel.ToString() + " is " + rel.GetParent().ToString()); } foreach (string s in generics) { newNames.Add(s, GetUniqueVarName(s)); } RenameVars(rel, newNames); }
public Constraint ResolveRelationConstraint(Constraint c, Stack <Constraint> visited, Relation parent, VarNameList topVars, VarNameList allVars) { VarNameList nonGenerics = parent.GetNonGenericsForChildren(); if (c is Var) { Var v = c as Var; Constraint u = Resolve(v, visited, parent); if (u is Relation) { Relation r = u as Relation; // Make sure we don't add variables to the non-generics // list which occured in a duplicate. if (!topVars.Contains(v)) { VarNameList subVars = r.GetAllVarNames(); foreach (string s in subVars) { if (allVars.Contains(s)) { nonGenerics.Add(s); } } allVars.AddRange(subVars); } else { Log("duplicate of variable " + v.ToString() + ", with unifier " + r.ToString()); QueueForRenamingOfGenerics(r); } } else if (u is Var) { nonGenerics.Add(u as Var); } topVars.Add(v); return(u); } else { Constraint u = Resolve(c, visited, parent); // non-vars should not resolve to vars Trace.Assert(!(u is Var)); if (u is Relation) { Relation r = u as Relation; VarNameList subVars = r.GetAllVarNames(); foreach (string s in subVars) { if (allVars.Contains(s)) { nonGenerics.Add(s); } } allVars.AddRange(subVars); } return(u); } }