Beispiel #1
0
 private void AddIdentityVectors(Queue <NodeVector> w_queue, IaNode node)
 {
     long[][] id = bg.GetIdentity(bg.var_n);
     for (int i = 0; i < bg.var_n; i++)
     {
         LeadVector vr = new LeadVector(id[i]);
         node.GeneratorSet.AddVector(vr);
         w_queue.Enqueue(new NodeVector {
             Node = node, Vector = vr
         });
     }
 }
        public GeneratorSet(string name, IaNode parent, BaseFunctions b)
        {
            this.name = name;

            this.parent = parent;
            this.b      = b;

            var_w = b.var_w;
            var_n = b.var_n;
            var_m = b.var_m;

            GArr = new LeadVector[var_n];
        }
 private void InsertVector(int ii, LeadVector vector)
 {
     if (GArr[ii] != null)
     {
         if (GArr[ii].Lidx > vector.Lidx)
         {
             int i = var_n - 2;
             while (i >= ii)
             {
                 GArr[i + 1] = GArr[i];
                 i--;
             }
             GArr[ii] = vector;
             return;
         }
         else
         {
             throw new ApplicationException();
         }
     }
     GArr[ii] = vector;
 }
        private void AddEven(LeadVector tvr)
        {
            int  r;
            long d;

            r = b.Reduction(tvr.Lentry, out d);

            long x = 1L << (var_w - r);

            int l = tvr.Vr.Length;

            long[] wr = new long[l];
            for (int i = 0; i < l; i++)
            {
                wr[i] = (x * tvr.Vr[i]) % var_m;
            }

            LeadVector twr = new LeadVector(wr);

            if (twr.Lidx >= 0)
            {
                AddVector(twr);
            }
        }
Beispiel #5
0
        private void CreateGeneratorSets(ProgramAst prg)
        {
            Queue <NodeVector> w_queue = VariableGeneratorSets(prg);

            while (w_queue.Count > 0)
            {
                NodeVector pair = w_queue.Dequeue();

                IaNode from = pair.Node;
                foreach (IaEdge edge in from.Edges)
                {
                    IaNode to = edge.To;

                    if ((edge.Ast != null) && (edge.Ast.AstType == AstNodeTypes.FunctionCall))
                    {
                        IaNode fncBegin = prg.Graph[edge.Ast.TokenText];
                        if (fncBegin.GeneratorSet == null)
                        {
                            fncBegin.GeneratorSet = new GeneratorSet(fncBegin, bg);
                        }

                        if (fncBegin.GeneratorSet.AddVector(pair.Vector))
                        {
                            if (printG)
                            {
                                fncBegin.GeneratorSet.Print();
                            }

                            w_queue.Enqueue(new NodeVector {
                                Node = fncBegin, Vector = pair.Vector
                            });
                        }
                    }

                    foreach (long[][] a_mtx in edge.MatrixSet.TMatrixes)
                    {
                        long[]     xi = bg.MatrixMultiVector(a_mtx, pair.Vector.Vr, bg.var_m);
                        LeadVector x  = new LeadVector(xi);
                        if (x.Lidx >= 0)
                        {
                            if (to.GeneratorSet == null)
                            {
                                to.GeneratorSet = new GeneratorSet(to, bg);
                            }

                            if (to.GeneratorSet.AddVector(x))
                            {
                                if (printG)
                                {
                                    to.GeneratorSet.Print();
                                }

                                w_queue.Enqueue(new NodeVector {
                                    Node = to, Vector = x
                                });
                            }
                        }
                    }
                }
            }
        }
Beispiel #6
0
        private Queue <NodeVector> VariableGeneratorSets(ProgramAst prg)
        {
            Queue <NodeVector> w_queue = new Queue <NodeVector>();
            IaNode             main    = prg.Graph["main"];

            main.GeneratorSet = new GeneratorSet(main, bg);

            Queue <NodeVector> vq = new Queue <NodeVector>();

            prg.VarGraph.GeneratorSet = new GeneratorSet(prg.VarGraph, bg);
            AddIdentityVectors(vq, prg.VarGraph);

            while (vq.Count > 0)
            {
                NodeVector pair = vq.Dequeue();

                IaNode from = pair.Node;
                if (from.Edges.Count() > 0)
                {
                    foreach (IaEdge edge in from.Edges)
                    {
                        IaNode to = edge.To;

                        foreach (long[][] a_mtx in edge.MatrixSet.TMatrixes)
                        {
                            long[]     xi = bg.MatrixMultiVector(a_mtx, pair.Vector.Vr, bg.var_m);
                            LeadVector x  = new LeadVector(xi);
                            if (x.Lidx >= 0)
                            {
                                if (to.GeneratorSet == null)
                                {
                                    to.GeneratorSet = new GeneratorSet(to, bg);
                                }

                                if (to.GeneratorSet.AddVector(x))
                                {
                                    if (printG)
                                    {
                                        to.GeneratorSet.Print();
                                    }

                                    vq.Enqueue(new NodeVector {
                                        Node = to, Vector = x
                                    });
                                }
                            }
                        }
                    }
                }
                else
                {
                    // konec definice promennych
                    main.GeneratorSet.AddVector(pair.Vector);
                    w_queue.Enqueue(new NodeVector {
                        Node = main, Vector = pair.Vector
                    });
                }
            }

            return(w_queue);
        }
Beispiel #7
0
        private void CreateFunctionMatrixes(ProgramAst prg)
        {
            List <IaEdge> fncCallEdges = new List <IaEdge>();

            CreateEmptyFunctionG(prg, fncCallEdges);

            Queue <NodeMatrix> w_queue = new Queue <NodeMatrix>();

            foreach (string name in prg.OrigFncs.Keys)
            {
                w_queue.Enqueue(new NodeMatrix {
                    Node = prg.Graph[name], Matrix = bfm.GetIdentity(bg.var_n)
                });
            }

            while (w_queue.Count > 0)
            {
                NodeMatrix pair = w_queue.Dequeue();

                IaNode from = pair.Node;
                if ((from.Next != null) || (from.IsTrue != null) || (from.IsFalse != null))
                {
                    foreach (IaEdge edge in from.Edges)
                    {
                        if ((edge.Ast == null) || (edge.Ast.AstType != AstNodeTypes.FunctionCall))
                        {
                            IaNode to = edge.To;

                            // pruchod hranou s maticemi
                            foreach (long[][] a_mtx in edge.MatrixSet.TMatrixes)
                            {
                                long[][]   mtx = bg.MatrixMultiMatrix(a_mtx, pair.Matrix, bfm.var_m);
                                long[]     xi  = bg.MatrixToVector(mtx);
                                LeadVector x   = new LeadVector(xi);
                                if (x.Lidx >= 0)
                                {
                                    if (to.FunctionGSet.AddVector(x))
                                    {
                                        if (printG)
                                        {
                                            to.FunctionGSet.Print();
                                        }

                                        w_queue.Enqueue(new NodeMatrix {
                                            Node = to, Matrix = mtx
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // pokud se jedna o konecny uzel funkce
                    foreach (IaEdge edge in fncCallEdges)
                    {
                        if ((edge.Ast == null) || (edge.Ast.AstType != AstNodeTypes.FunctionCall))
                        {
                            throw new ApplicationException();
                        }

                        if (edge.Ast.TokenText == from.FncName)
                        {
                            IaNode to = edge.To;

                            int i = 0;
                            while (edge.From.FunctionGSet.GArr[i] != null)
                            {
                                LeadVector vector = edge.From.FunctionGSet.GArr[i];
                                long[][]   matrix = bfm.VectorToMatrix(vector.Vr, bg.var_n);

                                long[][]   mtx = bg.MatrixMultiMatrix(pair.Matrix, matrix, bfm.var_m);
                                long[]     xi  = bg.MatrixToVector(mtx);
                                LeadVector x   = new LeadVector(xi);
                                if (x.Lidx >= 0)
                                {
                                    if (to.FunctionGSet.AddVector(x))
                                    {
                                        if (printG)
                                        {
                                            to.FunctionGSet.Print();
                                        }

                                        w_queue.Enqueue(new NodeMatrix {
                                            Node = to, Matrix = mtx
                                        });
                                    }
                                }
                                i++;
                            }
                        }
                    }
                }
            }
            // distribuce mnozin zmenovych matic z vystupnich uzlu na hrany volajici funkce
            foreach (string fncName in prg.LastNode.Keys)
            {
                IaNode last = prg.LastNode[fncName];

                List <long[][]> mtxs = new List <long[][]>();
                int             i    = 0;
                while (last.FunctionGSet.GArr[i] != null)
                {
                    mtxs.Add(bfm.VectorToMatrix(last.FunctionGSet.GArr[i].Vr, bg.var_n));
                    i++;
                }
                if (mtxs.Count > 0)
                {
                    foreach (IaEdge edge in fncCallEdges)
                    {
                        if ((edge.Ast == null) || (edge.Ast.AstType != AstNodeTypes.FunctionCall))
                        {
                            throw new ApplicationException();
                        }

                        if (edge.Ast.TokenText == last.FncName)
                        {
                            edge.MatrixSet.TMatrixes.Clear();
                            edge.MatrixSet.TMatrixes.AddRange(mtxs);
                        }
                    }
                }
            }
        }
        public bool AddVector(LeadVector tvr)
        {
            if (tvr.Lidx < 0)
            {
                return(false);
            }

            int i = 0;

            while (GArr[i] != null)
            {
                if (GArr[i].Lidx >= tvr.Lidx)
                {
                    break;
                }
                i++;
            }

            if (GArr[i] == null)
            {
                if ((tvr.Lentry != 0) && ((tvr.Lentry % 2) == 0))
                {
                    AddEven(tvr);
                }

                InsertVector(i, tvr);

                return(true);
            }
            else if (GArr[i].Lidx == tvr.Lidx)
            {
                bool change = false;

                int  rv, rg;
                long dv, dg;
                rg = b.Reduction(GArr[i].Lentry, out dg);
                rv = b.Reduction(tvr.Lentry, out dv);

                if (rg > rv)
                {
                    LeadVector tmpx = GArr[i];
                    RemoveVector(i);

                    change = true;
                    if ((tvr.Lentry != 0) && ((tvr.Lentry % 2) == 0))
                    {
                        AddEven(tvr);
                    }

                    InsertVector(i, tvr);

                    tvr = tmpx;

                    long td = dg;
                    dg = dv;
                    dv = td;

                    int tr = rg;
                    rg = rv;
                    rv = tr;
                }

                long x = (long)(1L << rv - rg) * dv;

                int    l  = tvr.Vr.Length;
                long[] wr = new long[l];
                for (int j = 0; j < l; j++)
                {
                    wr[j] = (((dg * tvr.Vr[j]) - (x * GArr[i].Vr[j])) % var_m + var_m) % var_m; // 2x modulo pro odstraneni zapornych cisel pod odecitani
                }
                LeadVector twr = new LeadVector(wr);
                if (twr.Lidx >= 0)
                {
                    change |= AddVector(twr);
                }

                return(change);
            }
            else if (GArr[i].Lidx > tvr.Lidx)
            {
                InsertVector(i, tvr);
                return(true);
            }

            return(false);
        }