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); } }
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 }); } } } } } }
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); }
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); }