Beispiel #1
0
        public static void SetDownwardsLimits(SolvingNode[] toposortedNodes)
        {
            void Downwards(SolvingNode descendant)
            {
                if (descendant.State is ICompositeType composite)
                {
                    foreach (var member in composite.Members)
                    {
                        Downwards(member);
                    }
                }

                foreach (var ancestor in descendant.Ancestors)
                {
                    descendant.State = SetDownwardsLimits(descendant, ancestor);
                }
            }

            for (int i = toposortedNodes.Length - 1; i >= 0; i--)
            {
                var descendant = toposortedNodes[i];
                if (descendant.MemberOf.Any())
                {
                    continue;
                }

                Downwards(descendant);
            }
        }
Beispiel #2
0
        public static void Destruction(SolvingNode[] toposorteNodes)
        {
            void Destruction(SolvingNode node)
            {
                if (node.State is ICompositeType composite)
                {
                    if (composite.Members.Any(m => m.State is RefTo))
                    {
                        node.State = composite.GetNonReferenced();
                    }

                    foreach (var member in composite.Members)
                    {
                        Destruction(member);
                    }
                }

                foreach (var ancestor in node.Ancestors.ToArray())
                {
                    TryMergeDestructive(node, ancestor);
                }
            }

            for (int i = toposorteNodes.Length - 1; i >= 0; i--)
            {
                var descendant = toposorteNodes[i];
                if (descendant.MemberOf.Any())
                {
                    continue;
                }
                Destruction(descendant);
            }
        }
Beispiel #3
0
        public void SetCall(IState[] argThenReturnTypes, int[] argThenReturnIds)
        {
            if (argThenReturnTypes.Length != argThenReturnIds.Length)
            {
                throw new ArgumentException("Sizes of type and id array have to be equal");
            }

            for (int i = 0; i < argThenReturnIds.Length - 1; i++)
            {
                var type  = argThenReturnTypes[i];
                var argId = argThenReturnIds[i];
                switch (type)
                {
                case Primitive primitive:
                {
                    var node = GetOrCreateNode(argId);
                    if (!node.TrySetAncestor(primitive))
                    {
                        throw new InvalidOperationException();
                    }
                    break;
                }

                case Array array:
                {
                    //var node = GetOrCreateNode(argId);
                    //var ancestor = CreateVarType(array);
                    //ancestor.BecomeAncestorFor(node);

                    //todo Upcast support
                    GetOrCreateArrayNode(argId, array.ElementNode);
                    break;
                }

                case Fun fun:
                {
                    var node     = GetOrCreateNode(argId);
                    var ancestor = CreateVarType(fun);
                    ancestor.BecomeAncestorFor(node);
                    break;
                }

                case RefTo refTo:
                {
                    var node = GetOrCreateNode(argId);
                    refTo.Node.BecomeAncestorFor(node);
                    break;
                }

                default: throw new InvalidOperationException();
                }
            }

            var returnId   = argThenReturnIds[argThenReturnIds.Length - 1];
            var returnType = argThenReturnTypes[argThenReturnIds.Length - 1];
            var returnNode = GetOrCreateNode(returnId);

            returnNode.State = SolvingFunctions.GetMergedState(returnNode.State, returnType);
        }
Beispiel #4
0
        public void GetLastCommonAncestorOrNull_ConcreteFunTypeAndConstrainsArray_ReturnsAny()
        {
            var fun   = Fun.Of(Primitive.I32, Primitive.I64);
            var array = Array.Of(CreateConstrainsNode());

            Assert.AreEqual(Primitive.Any, fun.GetLastCommonAncestorOrNull(array));
            Assert.AreEqual(Primitive.Any, array.GetLastCommonAncestorOrNull(fun));
        }
Beispiel #5
0
        static void ConcreteConcatEx()
        {
            //              2     0 1
            //a:int[]; y = concat(a,b)
            var graph = new GraphBuilder();

            graph.SetVarType("a", Array.Of(Primitive.I32));
            graph.SetVar("a", 0);
            graph.SetVar("b", 1);
            graph.SetConcatCall(0, 1, 2);
            graph.SetDef("y", 2);
            var result = graph.Solve();
        }
Beispiel #6
0
        public void SetIfElse(int[] conditions, int[] expressions, int resultId)
        {
            var result = GetOrCreateNode(resultId);

            foreach (var exprId in expressions)
            {
                var expr = GetOrCreateNode(exprId);
                result.BecomeReferenceFor(expr);
            }

            foreach (var condId in conditions)
            {
                SetOrCreatePrimitive(condId, Primitive.Bool);
            }
        }
Beispiel #7
0
        public void Array_referencesItself()
        {
            //    1       0
            //x = reverse(x)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetReverse(0, 1);
            graph.SetDef("x", 1);

            var result = graph.Solve();
            var res    = result.AssertAndGetSingleGeneric(null, null);

            result.AssertNamed(Array.Of(res), "x");
        }
Beispiel #8
0
        public void ConcreteFunAndUpcast()
        {
            //                2  0   1
            //a:int[]; y = First(a, isNan)
            var graph = new GraphBuilder();

            graph.SetVarType("a", Array.Of(Primitive.I32));
            graph.SetVar("a", 0);
            graph.SetVarType("isNan", Fun.Of(Primitive.Real, Primitive.Bool));
            graph.SetVar("isNan", 1);
            graph.SetGetFirst(0, 1, 2);
            graph.SetDef("y", 2);
            var result = graph.Solve();

            result.AssertNoGenerics();
        }
Beispiel #9
0
        public void Anything_WithConcreteFun()
        {
            //     2  0   1
            //y = Any(a, isNan)
            var graph = new GraphBuilder();

            graph.SetVar("a", 0);
            graph.SetVarType("isNan", Fun.Of(Primitive.Real, Primitive.Bool));
            graph.SetVar("isNan", 1);
            graph.SetIsAny(0, 1, 2);
            graph.SetDef("y", 2);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Primitive.Real), "a");
        }
Beispiel #10
0
        public void ConcreteArg()
        {
            //               2 0
            //x:int[]; y = sum(x)
            var graph = new GraphBuilder();

            graph.SetVarType("x", Array.Of(Primitive.I32));
            graph.SetVar("x", 0);
            graph.SetSumCall(0, 1);
            graph.SetDef("y", 1);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamedEqualToArrayOf(Primitive.I32, "x");
            result.AssertNamed(Primitive.I32, "y");
        }
Beispiel #11
0
        public void ConcreteCall()
        {
            //        1  0
            //y = NoNans(x)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetCall(new  IState[] { Array.Of(Primitive.Real), Primitive.Bool }, new [] { 0, 1 });
            graph.SetDef("y", 1);

            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Primitive.Real), "x");
            result.AssertNamed(Primitive.Bool, "y");
        }
Beispiel #12
0
        public void ConcreteArg()
        {
            //          2  0,1
            //x:int[]; y = get(x,0)
            var graph = new GraphBuilder();

            graph.SetVarType("x", Array.Of(Primitive.I32));
            graph.SetVar("x", 0);
            graph.SetConst(1, Primitive.I32);
            graph.SetArrGetCall(0, 1, 2);
            graph.SetDef("y", 2);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamedEqualToArrayOf(Primitive.I32, "x");
            result.AssertNamed(Primitive.I32, "y");
        }
Beispiel #13
0
        public void ConcreteFun()
        {
            //     2  0   1
            //y = Map(a, SQRT)
            var graph = new GraphBuilder();

            graph.SetVar("a", 0);
            graph.SetVarType("SQRT", Fun.Of(Primitive.Real, Primitive.Real));
            graph.SetVar("SQRT", 1);
            graph.SetMap(0, 1, 2);
            graph.SetDef("y", 2);

            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Primitive.Real), "a", "y");
        }
Beispiel #14
0
        public void Array_referencesItselfManyTimes()
        {
            //    4      0    3   1 2
            //x = concat(x,concat(x,x)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetVar("x", 1);
            graph.SetVar("x", 2);
            graph.SetConcatCall(1, 2, 3);
            graph.SetConcatCall(0, 3, 4);
            graph.SetDef("x", 4);
            var result = graph.Solve();
            var res    = result.AssertAndGetSingleGeneric(null, null);

            result.AssertNamed(Array.Of(res), "x");
        }
Beispiel #15
0
        public void Anything_WithBoolArray()
        {
            //     3  0  2  1
            //y = Any(a, x->x)
            var graph = new GraphBuilder();

            graph.SetVar("a", 0);
            graph.SetVar("2lx", 1);
            graph.CreateLambda(1, 2, "2lx");
            graph.SetIsAny(0, 2, 3);
            graph.SetDef("y", 3);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Primitive.Bool), "a");
            result.AssertNamed(Primitive.Bool, "2lx");
            result.AssertNode(Fun.Of(Primitive.Bool, Primitive.Bool), 2);
        }
Beispiel #16
0
        public void Array_referencesItselfWithMap()
        {
            //    0  5  4    132
            //x = x.map(f(a)=a+1)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetVar("la", 1);
            graph.SetIntConst(2, Primitive.U8);
            graph.SetArith(1, 2, 3);
            graph.CreateLambda(3, 4, "la");
            graph.SetMap(0, 4, 5);
            graph.SetDef("x", 5);
            var result = graph.Solve();
            var res    = result.AssertAndGetSingleArithGeneric();

            result.AssertNamed(Array.Of(res), "x");
        }
Beispiel #17
0
        public void TwoDimentions_Generic()
        {
            //    4    2  0,1  3
            //y = get(get(x,0),0)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetConst(1, Primitive.I32);
            graph.SetArrGetCall(0, 1, 2);
            graph.SetConst(3, Primitive.I32);
            graph.SetArrGetCall(2, 3, 4);
            graph.SetDef("y", 4);
            var result  = graph.Solve();
            var generic = result.AssertAndGetSingleGeneric(null, null);

            result.AssertNamed(Array.Of(new Array(generic)), "x");
            result.AssertAreGenerics(generic, "y");
        }
Beispiel #18
0
        public void Array_referencesItselfWithMap_RetTypeIsConcrete()
        {
            //    0  5  4    132
            //x = x.map(f(a):i64=a+1)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetVar("la", 1);
            graph.SetIntConst(2, Primitive.U8);
            graph.SetArith(1, 2, 3);
            graph.CreateLambda(3, 4, Primitive.I64, "la");
            graph.SetMap(0, 4, 5);
            graph.SetDef("x", 5);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Primitive.I64), "x");
        }
Beispiel #19
0
        public void ArrayCycle_Solved()
        {
            //    4  2  0 1    3
            //x = [ get(x,0) , 1]
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetIntConst(1, Primitive.U8);
            graph.SetArrGetCall(0, 1, 2);
            graph.SetIntConst(3, Primitive.U8);
            graph.SetArrayInit(4, 2, 3);
            graph.SetDef("x", 4);
            var res = graph.Solve();

            var t = res.AssertAndGetSingleGeneric(Primitive.U8, Primitive.Real);

            res.AssertNamed(Array.Of(t), "x");
        }
Beispiel #20
0
        public void ThreeDimentions_ConcreteDefArrayOf()
        {
            //           4    2  0,1  3
            //y:real[] = get(get(x,0),0)
            var graph = new GraphBuilder();

            graph.SetVar("x", 0);
            graph.SetConst(1, Primitive.I32);
            graph.SetArrGetCall(0, 1, 2);
            graph.SetConst(3, Primitive.I32);
            graph.SetArrGetCall(2, 3, 4);
            graph.SetVarType("y", Array.Of(Primitive.Real));
            graph.SetDef("y", 4);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Array.Of(Array.Of(Primitive.Real))), "x");
            result.AssertNamed(Array.Of(Primitive.Real), "y");
        }
Beispiel #21
0
        public void TwoDimentions_ConcreteArg()
        {
            //    4    2  0,1  3
            //x:int[][]; y = get(get(x,0),0)
            var graph = new GraphBuilder();

            graph.SetVarType("x", Array.Of(Array.Of(Primitive.I32)));
            graph.SetVar("x", 0);
            graph.SetConst(1, Primitive.I32);
            graph.SetArrGetCall(0, 1, 2);
            graph.SetConst(3, Primitive.I32);
            graph.SetArrGetCall(2, 3, 4);
            graph.SetDef("y", 4);
            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNamed(Array.Of(Array.Of(Primitive.I32)), "x");
            result.AssertNamed(Primitive.I32, "y");
        }
Beispiel #22
0
        public static void MergeGroup(SolvingNode[] cycleRoute)
        {
            var main = cycleRoute.First();

            foreach (var current in cycleRoute)
            {
                if (current == main)
                {
                    continue;
                }

                if (current.State is RefTo refState)
                {
                    if (!cycleRoute.Contains(refState.Node))
                    {
                        throw new InvalidOperationException();
                    }
                }
                else
                {
                    //merge main and current
                    main.State = GetMergedState(main.State, current.State);
                }

                main.Ancestors.AddRange(current.Ancestors);
                current.Ancestors.Clear();

                if (!current.IsSolved)
                {
                    current.State = new RefTo(main);
                }
            }

            var newAncestors = main.Ancestors.Distinct()
                               .SelectMany(r => r.Ancestors)
                               .Where(r => !cycleRoute.Contains(r))
                               .Distinct()
                               .ToList();

            main.Ancestors.Clear();
            main.Ancestors.AddRange(newAncestors);
        }
Beispiel #23
0
 public void Impossible_ConcreteArgAndDef_throws()
 {
     try
     {
         //                   1  0
         //x:real[]; y:int = sum(x)
         var graph = new GraphBuilder();
         graph.SetVarType("x", Array.Of(Primitive.Real));
         graph.SetVar("x", 0);
         graph.SetSumCall(0, 1);
         graph.SetVarType("y", Primitive.I32);
         graph.SetDef("y", 1);
         var result = graph.Solve();
         Assert.Fail("Impossible equation solved");
     }
     catch (Exception e)
     {
         Console.WriteLine(e);
     }
 }
Beispiel #24
0
        public void Generic()
        {
            //     3  0  2 1
            //y = Map(a, x->x)
            var graph = new GraphBuilder();

            graph.SetVar("a", 0);

            graph.SetVar("2lx", 1);
            graph.CreateLambda(1, 2, "2lx");
            graph.SetMap(0, 2, 3);
            graph.SetDef("y", 3);

            var result = graph.Solve();

            var t = result.AssertAndGetSingleGeneric(null, null);

            result.AssertNamed(Array.Of(t), "a", "y");
            result.AssertNode(Fun.Of(t, t));
        }
Beispiel #25
0
        //[Ignore("Upcast for complex types")]
        public void ConcreteCall_WithGenericArray()
        {
            //        3   2 0  1
            //y = NoNans( [ 1, -1])
            var graph = new GraphBuilder();

            graph.SetIntConst(0, Primitive.U8);
            graph.SetIntConst(1, Primitive.I16);
            graph.SetArrayInit(2, 0, 1);

            graph.SetCall(new IState[] { Array.Of(Primitive.Real), Primitive.Bool }, new[] { 2, 3 });
            graph.SetDef("y", 3);

            var result = graph.Solve();

            result.AssertNoGenerics();
            result.AssertNode(Array.Of(Primitive.Real), 2);
            result.AssertNode(Primitive.Real, 0, 1);
            result.AssertNamed(Primitive.Bool, "y");
        }
Beispiel #26
0
        public void ImpossibleArgType_Throws()
        {
            //                 1  0
            //x:Any[]; y = NoNans(x)
            var graph = new GraphBuilder();

            graph.SetVarType("x", Array.Of(Primitive.Any));
            graph.SetVar("x", 0);

            try
            {
                graph.SetCall(new IState[] { Array.Of(Primitive.Real), Primitive.Bool }, new[] { 0, 1 });
                graph.SetDef("y", 1);
                graph.Solve();
                Assert.Fail();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
Beispiel #27
0
        private void SetOrCreateLambda(int lambdaId, SolvingNode[] args, SolvingNode ret)
        {
            var fun = Fun.Of(args, ret);

            while (_syntaxNodes.Count <= lambdaId)
            {
                _syntaxNodes.Add(null);
            }

            var alreadyExists = _syntaxNodes[lambdaId];

            if (alreadyExists != null)
            {
                alreadyExists.State = SolvingFunctions.GetMergedState(fun, alreadyExists.State);
            }
            else
            {
                var res = new SolvingNode(lambdaId.ToString(), fun, SolvingNodeType.SyntaxNode);
                _syntaxNodes[lambdaId] = res;
            }
        }
Beispiel #28
0
 public void ConcreteArgAndDef_Impossible()
 {
     try
     {
         //          2  0,1
         //x:real[]; y:int = get(x,0)
         var graph = new GraphBuilder();
         graph.SetVarType("x", Array.Of(Primitive.Real));
         graph.SetVar("x", 0);
         graph.SetConst(1, Primitive.I32);
         graph.SetArrGetCall(0, 1, 2);
         graph.SetVarType("y", Primitive.I32);
         graph.SetDef("y", 2);
         var result = graph.Solve();
         Assert.Fail("Impossible equation solved");
     }
     catch (Exception e)
     {
         Console.WriteLine(e);
     }
 }
Beispiel #29
0
        public void ConcreteOutput()
        {
            //     3  0  2 1
            //y:u16[] = Map(a, x->x)
            var graph = new GraphBuilder();

            graph.SetVar("a", 0);

            graph.SetVar("2lx", 1);
            graph.CreateLambda(1, 2, "2lx");
            graph.SetMap(0, 2, 3);
            graph.SetVarType("y", Array.Of(Primitive.U16));
            graph.SetDef("y", 3);

            var result = graph.Solve();

            result.AssertNoGenerics();

            result.AssertNamed(Array.Of(Primitive.U16), "a", "y");
            result.AssertNode(Fun.Of(Primitive.U16, Primitive.U16));
        }
Beispiel #30
0
        /// <summary>
        /// Превращает неопределенное ограничение в ограничение с массивом
        /// </summary>
        /// <param name="descNodeName"></param>
        /// <param name="descendant"></param>
        /// <param name="ancestor"></param>
        /// <returns></returns>
        private static Array TransformToArrayOrNull(string descNodeName, Constrains descendant,
                                                    Array ancestor)
        {
            if (descendant.NoConstrains)
            {
                var    constrains = new Constrains();
                string eName;

                if (descNodeName.StartsWith("T") && descNodeName.Length > 1)
                {
                    eName = "e" + descNodeName.Substring(1).ToLower() + "'";
                }
                else
                {
                    eName = "e" + descNodeName.ToLower() + "'";
                }

                var node = new SolvingNode(eName, constrains, SolvingNodeType.TypeVariable);
                node.Ancestors.Add(ancestor.ElementNode);
                return(new Array(node));
            }

            if (descendant.HasDescendant && descendant.Descedant is Array arrayEDesc)
            {
                if (arrayEDesc.Element is RefTo)
                {
                    var origin = arrayEDesc.ElementNode.GetNonReference();
                    if (origin.IsSolved)
                    {
                        return(new Array(origin));
                    }
                }
                else if (arrayEDesc.ElementNode.IsSolved)
                {
                    return(arrayEDesc);
                }
            }

            return(null);
        }