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 CatFxnType CatFxnTypeFromRelation(Relation rel) { CatTypeVector cons = CatTypeVectorFromVec(rel.GetLeft()); CatTypeVector prod = CatTypeVectorFromVec(rel.GetRight()); // TODO: add the boolean as a third value in the vector. // it becomes a variable when unknown, and is resolved otherwise. return(new CatFxnType(cons, prod, false)); }
public void AddRelConstraint(Relation r1, Relation r2) { if (IsRelationConstrained(r1, r2)) { return; } MarkRelationConstrained(r1, r2); AddVecConstraint(r1.GetLeft(), r2.GetLeft()); AddVecConstraint(r1.GetRight(), r2.GetRight()); }
public void AddSubConstraints(Constraint c1, Constraint c2) { if (c1 == c2) { return; } if ((c1 is Vector) && (c2 is Vector)) { AddToConstraintQueue(c1 as Vector, c2 as Vector); } else if ((c1 is Relation) && (c2 is Relation)) { Relation r1 = c1 as Relation; Relation r2 = c2 as Relation; AddToConstraintQueue(r1.GetLeft(), r2.GetLeft()); AddToConstraintQueue(r1.GetRight(), r2.GetRight()); } }
public bool IsRecursiveRelation(string s, Constraint c) { Relation rel = c as Relation; if (rel == null) { return(false); } foreach (Constraint tmp in rel.GetLeft()) { if (tmp.EqualsVar(s)) { return(true); } } foreach (Constraint tmp in rel.GetRight()) { if (tmp.EqualsVar(s)) { return(true); } } return(false); }
private bool CanRollupRelation(Constraint child) { VarNameMap map = new VarNameMap(); if (!(child is Relation)) { return(false); } Relation childRel = child as Relation; int n = GetLeft().GetCount(); if (n != childRel.GetLeft().GetCount()) { return(false); } for (int i = 0; i < n; ++i) { Constraint tmp = GetLeft(i); Constraint childTmp = childRel.GetLeft(i); if (tmp != child) { if (!tmp.Equals(childTmp, map)) { return(false); } } else { if (!(childTmp is RecursiveRelation)) { return(false); } } } n = GetRight().GetCount(); if (n != childRel.GetRight().GetCount()) { return(false); } for (int i = 0; i < n; ++i) { Constraint tmp = GetRight(i); Constraint childTmp = childRel.GetRight(i); if (tmp != child) { if (!tmp.Equals(childTmp, map)) { return(false); } } else { if (!(childTmp is RecursiveRelation)) { return(false); } } } return(true); }
public CatFxnType LocalComposeTypes(CatFxnType left, CatFxnType right) { // Make sure that the variables on the left function and the variables // on the right function are different CatVarRenamer renamer = new CatVarRenamer(); left = renamer.Rename(left.AddImplicitRhoVariables()); renamer.ResetNames(); right = renamer.Rename(right.AddImplicitRhoVariables()); Log("=="); Log("Composing : " + left.ToString()); Log("with : " + right.ToString()); Log("Adding constraints"); Relation rLeft = FxnTypeToRelation(left); Relation rRight = FxnTypeToRelation(right); //TODO: remove //rLeft.UnrollRecursiveRelations(); //rRight.UnrollRecursiveRelations(); Relation result = new Relation(rLeft.GetLeft(), rRight.GetRight()); AddTopLevelConstraints(rLeft.GetRight(), rRight.GetLeft()); AddConstraint(CreateVar("result$"), result); Log("Constraints"); ComputeConstraintLists(); LogConstraints(); Log("Unifiers"); ComputeUnifiers(); foreach (string sVar in GetConstrainedVars()) { Constraint u = GetUnifierFor(sVar); Log("var: " + sVar + " = " + u); } Log("Composed Type"); Constraint c = GetResolvedUnifierFor("result$"); if (!(c is Relation)) { throw new Exception("Resolved type is not a relation"); } // TODO: remove // Relation r = c as Relation; // r.RollupRecursiveRelations(); CatKind k = ConstraintToCatKind(c); CatFxnType ft = k as CatFxnType; Log("raw type : " + ft.ToString()); Log("pretty type : " + ft.ToPrettyString()); Log("=="); CheckConstraintQueueEmpty(); // Check if the relation was valid, and thus the function type if (!ft.IsValid()) { throw new Exception("invalid function type: " + ft.ToString()); } return(ft); }