コード例 #1
0
        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);
        }
コード例 #2
0
        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));
        }
コード例 #3
0
 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());
 }
コード例 #4
0
 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());
     }
 }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: ConstraintSolverUtil.cs プロジェクト: noprompt/cat
        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);
        }
コード例 #7
0
        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);
        }