private void CreateLinearEquations(ProgramAst prg) { Queue <IaNode> q = new Queue <IaNode>(); q.Enqueue(prg.VarGraph); foreach (IaNode node in prg.Graph.Values) { q.Enqueue(node); } while (q.Count > 0) { IaNode n = q.Dequeue(); if ((n.GeneratorSet != null) && (n.LinearEquations == null)) { n.LinearEquations = new LinearEquations(n, bg, printLE); n.LinearEquations.CalculateLE(); foreach (IaEdge edge in n.Edges) { if (edge.To.LinearEquations == null) { q.Enqueue(edge.To); } } } } }
private void CreateEmptyFunctionG(ProgramAst prg, List <IaEdge> fncCallEdges) { foreach (IaNode node in prg.Graph.Values) { Queue <IaNode> q = new Queue <IaNode>(); q.Enqueue(node); while (q.Count > 0) { IaNode n = q.Dequeue(); if (n.FunctionGSet == null) { n.FunctionGSet = new GeneratorSet(n, bfm); foreach (IaEdge edge in n.Edges) { if ((edge.Ast != null) && (edge.Ast.AstType == AstNodeTypes.FunctionCall)) { fncCallEdges.Add(edge); } if (edge.To.FunctionGSet == null) { q.Enqueue(edge.To); } } } } } }
private bool WriteLinearEquations(IaNode node, List<string> vars, string prefix) { bool isAchievable = true; string p = prefix + " "; file.WriteLine("{0}/*", p); if (node != null) { if (node.LinearEquations == null) { file.WriteLine("{0} * Nedosazitelny stav", p); isAchievable = false; } else if (node.LinearEquations.GArr[0] == null) file.WriteLine("{0} * Zadna omezeni", p); else { int i = 0; while ((i < node.LinearEquations.GArr.Length) && (node.LinearEquations.GArr[i] != null)) { file.WriteLine("{0} * {1}", p, node.LinearEquations.PrintLE(i, vars)); i++; } } } else { file.WriteLine("{0} * Uzel neni ulozen...", p); } file.WriteLine("{0}*/", p); return isAchievable; }
private void CreateTransitionMatrixes(ProgramAst prg) { Queue <IaNode> q = new Queue <IaNode>(); q.Enqueue(prg.VarGraph); foreach (string name in prg.OrigFncs.Keys) { q.Enqueue(prg.Graph[name]); } while (q.Count > 0) { IaNode n = q.Dequeue(); if (n != null) { foreach (IaEdge edge in n.Edges) { if (edge.MatrixSet == null) { var mtx = new TransitionMatrixSet(edge, bg); mtx.GetMatrix(prg.Vars); edge.MatrixSet = mtx; if (printM) { mtx.Print(); } q.Enqueue(edge.To); } } } } }
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 bool CreateVariableGraph(ProgramAst program) { IaNode node = new IaNode { FncName = "var_decl", Name = "var_decl_begin" }; program.VarGraph = node; foreach (string varName in program.Vars) { BaseAst ast = program.VarsDecl[varName]; if (ast != null) { IaNode to = new IaNode { FncName = "var_decl", Name = "var_decl_after_" + varName }; ast.Node = to; node.Next = new IaEdge { Name = "var_decl_expr_line#" + ast.TokenStartLine, Ast = ast, From = node, To = to }; node = to; } } return(true); }
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 LinearEquations(IaNode parent, BaseFunctions b, bool print) : base("GLa", parent, b) { this.print = print; }
private bool CreateFunctionGraphs(ProgramAst program) { foreach (string fncName in program.ConvFncs.Keys) { FunctionAst fnc = program.ConvFncs[fncName] as FunctionAst; if (fnc != null) { if ((fnc.Body != null) && (fnc.Body.Statements != null) && (fnc.Body.Statements.Count > 0)) { bool isAnyCmd = false; foreach (BaseAst st in fnc.Body.Statements) { if ((st is OperatorAst) || (st is ConditionAst) || (st.AstType == AstNodeTypes.FunctionCall) || (st.AstType == AstNodeTypes.Return)) { isAnyCmd = true; break; } } if (isAnyCmd) { Dictionary <string, IaNode> lbls = new Dictionary <string, IaNode>(); List <Tuple <string, IaNode, string, int> > gts = new List <Tuple <string, IaNode, string, int> >(); IaNode node = new IaNode { FncName = fncName, Name = fncName + "_fnc_begin" }; program.OrigFncs[fncName].Node = node; program.Graph.Add(fncName, node); int i = 0; while (i < fnc.Body.Statements.Count) { BaseAst st = fnc.Body.Statements[i]; if (st is OperatorAst) { IaNode next = new IaNode { FncName = fncName, Name = fncName + "_after_expr_line#" + st.TokenStartLine }; st.Node = next; node.Next = new IaEdge { Name = fncName + "_expr_line#" + st.TokenStartLine, Ast = st, From = node, To = next }; node = next; i++; continue; } if (st.AstType == AstNodeTypes.FunctionCall) { IaNode next = new IaNode { FncName = fncName, Name = fncName + "_after_fnccall_line#" + st.TokenStartLine }; st.Node = next; node.Next = new IaEdge { Name = fncName + "_fnccall_line#" + st.TokenStartLine, Ast = st, From = node, To = next }; node = next; i++; continue; } if (st is ConditionAst) { IaNode next = new IaNode { FncName = fncName, Name = fncName + "_after_condition_line#" + st.TokenStartLine }; st.Node = next; node.Next = new IaEdge { Name = fncName + "_condition_line#" + st.TokenStartLine, Ast = st, From = node, To = next }; node = next; i++; BaseAst gt = fnc.Body.Statements[i]; node.ReverseAst = gt; gts.Add(new Tuple <string, IaNode, string, int>("IsTrue", node, (gt as GotoAst).Label, st.TokenStartLine)); next = new IaNode { FncName = fncName, Name = fncName + "_condition_false_line#" + st.TokenStartLine }; node.IsFalse = new IaEdge { Name = fncName + "_condition_false_line#" + st.TokenStartLine, From = node, To = next }; node = next; i++; continue; } if (st.AstType == AstNodeTypes.Label) { node.Name = fncName + "_label_" + st.TokenText; lbls.Add(st.TokenText, node); i++; continue; } if (st is GotoAst) { node.ReverseAst = st; gts.Add(new Tuple <string, IaNode, string, int>("Next", node, (st as GotoAst).Label, st.TokenStartLine)); node = new IaNode { FncName = fncName, Name = fncName + "_after_goto_line#" + (st as GotoAst).Label }; // po goto musi byt novy node (nova vetev) i++; continue; } if (st.AstType == AstNodeTypes.Return) { node.ReverseAst = st; gts.Add(new Tuple <string, IaNode, string, int>("End", node, "$End$", st.TokenStartLine)); node = new IaNode { FncName = fncName, Name = fncName + "_after_return_line#" + st.TokenStartLine }; // aktualni node je konec funkce, novy node pro pokracovani, jinak se zahodi i++; continue; } } program.LastNode.Add(fncName, node); lbls.Add("$End$", node); foreach (Tuple <string, IaNode, string, int> gt in gts) { IaNode to = lbls[gt.Item3]; if (to == null) { Console.WriteLine("Neznamy label {0} pri vytvareni grafu.", gt.Item3); return(false); } if (gt.Item1 == "Next") { gt.Item2.Next = new IaEdge { Name = fncName + "_goto_line#" + gt.Item4, From = gt.Item2, To = to } } ; else if (gt.Item1 == "IsTrue") { gt.Item2.IsTrue = new IaEdge { Name = fncName + "_condition_true_line#" + gt.Item4, From = gt.Item2, To = to } } ; else if (gt.Item1 == "End") { gt.Item2.Next = new IaEdge { Name = fncName + "_return#" + gt.Item4, From = gt.Item2, To = to } } ; if (gt.Item2.ReverseAst != null) { gt.Item2.ReverseAst.Node = to; } } } } } } return(true); }
public GeneratorSet(IaNode parent, BaseFunctions b) : this("G", parent, b) { }