/* * given m=2, k=3, y=3x+2 */ public static void FromSlopeInterceptToLineSlopeIntercept(EqGoal slopeGoal, EqGoal interceptGoal, LineSymbol ls) { //1. Substitute slope and intercept properties into the line slope-intercept form y=mx+b. //////////////////////////////////////////////////////// var ts0 = new TraceStep(null, slopeGoal, GeometryScaffold.KC_LineSlopeForm, PlottingRule.PlottingStrategy, PlottingRule.Plot(slopeGoal)); var ts1 = new TraceStep(null, interceptGoal, GeometryScaffold.KC_LineInterceptForm, PlottingRule.PlottingStrategy, PlottingRule.Plot(interceptGoal)); ls._innerLoop.Add(ts0); var abstractLs = new Line(ls.Shape.Label, slopeGoal.Lhs, interceptGoal.Lhs); var abstractLss = new LineSymbol(abstractLs); var internalLs = new Line(ls.Shape.Label, ls.SymSlope, interceptGoal.Lhs); var internalLss = new LineSymbol(internalLs); var traceStep1 = new TraceStep(abstractLss, internalLss, SubstitutionRule.SubstituteKC(), SubstitutionRule.SubstitutionStrategy, SubstitutionRule.ApplySubstitute(abstractLss, slopeGoal)); ls._innerLoop.Add(traceStep1); ls._innerLoop.Add(ts1); /* * var rule = "Substitute given property to line slope-intercept form."; * var appliedRule1 = string.Format("Substitute slope={0} into y=mx+b", ls.SymSlope); * var appliedRule2= string.Format("Substitute intercept={0} into y=mx+b", ls.SymIntercept);*/ var traceStep2 = new TraceStep(internalLss, ls, SubstitutionRule.SubstituteKC(), SubstitutionRule.SubstitutionStrategy, SubstitutionRule.ApplySubstitute(internalLss, interceptGoal)); ls._innerLoop.Add(traceStep2); string strategy = "Substitute slope and intercept properties into the line slope-intercept form y = mx + b."; ls.GenerateATrace(strategy); }
public void SendSubstitution(Substitution s) { string delimiter = s.Delimiter; for (int i = 0; i < s.SubRule.Length; i++) { SubstitutionRule r = s.SubRule[i]; if (Enum.TryParse(r.Type, true, out ccSR type)) { if (XMLwriter != null) { XMLwriter.WriteStartElement(r.Type); } SetSubValues(type, r, delimiter); if (XMLwriter != null) { XMLwriter.WriteEndElement(); } } else { Log?.Invoke(p, $"Unknown substitution rule type =>{r.Type}<="); } } }
// Add a new rule to either msg or global private void AddOneRule(Src n) { ccSR attr = (ccSR)cbAttribute.SelectedIndex; // Make sure the user filled it in if (ruleSpecified(attr)) { // Get the new rule SubstitutionRule sr = GetSubstitutionRule(attr); if (Subs[(int)n] == null) { // Create a whole new substitution with one rule Subs[(int)n] = GetNewSubstitution(); Subs[(int)n].SubRule = new SubstitutionRule[] { sr }; } else { // Delete the rule if it exists List <SubstitutionRule> r = new List <SubstitutionRule>(); foreach (SubstitutionRule t in Subs[(int)n].SubRule) { if (t.Type != attr.ToString()) { r.Add(t); } } // Add the new rule to the list and turn it back to an array r.Add(sr); Subs[(int)n].SubRule = r.ToArray(); } } }
// Adding rules into the model public void Add(SubstitutionRule r) { substitutionRules.Add(r); r.AddToDomain(this); if (r.isTransposable) { substitutionRules.Add(r.Contrapositive()); } }
public static void FromPointPointToLine(PointSymbol ps1, PointSymbol ps2, LineSymbol ls) { var m = new Var("m"); var k = new Var("k"); var x = new Var("x"); var y = new Var("y"); var term = new Term(Expression.Multiply, new List <object>() { m, x }); var term1 = new Term(Expression.Add, new List <object>() { term, k }); var eqPattern = new Equation(y, term1); var term2 = new Term(Expression.Multiply, new List <object>() { m, ps1.SymXCoordinate }); var term22 = new Term(Expression.Add, new List <object>() { term2, k }); var eqPattern1 = new Equation(ps1.SymYCoordinate, term22); var term3 = new Term(Expression.Multiply, new List <object>() { m, ps2.SymXCoordinate }); var term33 = new Term(Expression.Add, new List <object>() { term3, k }); var eqPattern2 = new Equation(ps2.SymYCoordinate, term33); string strategy = "Generate a line by substituting two given points into the line slope-intercept form y=mx+k."; var ts0 = new TraceStep(eqPattern, eqPattern1, SubstitutionRule.SubstituteKC(), SubstitutionRule.SubstitutionStrategy, SubstitutionRule.ApplySubstitute(eqPattern, ps1)); var ts1 = new TraceStep(eqPattern, eqPattern2, SubstitutionRule.SubstituteKC(), SubstitutionRule.SubstitutionStrategy, SubstitutionRule.ApplySubstitute(eqPattern, ps2)); string kc = GeometryScaffold.KC_LineSlopeForm; var ts2 = new TraceStep(null, ls, kc, "calculate m and k through the above two linear equations.", "calculate m and k through linear equation and retrieve y=mx+k line form."); ls._innerLoop.Add(ts0); ls._innerLoop.Add(ts1); ls._innerLoop.Add(ts2); ls.GenerateATrace(strategy); }
private void SendSubstitution(Substitution s, string delimiter) { for (int i = 0; i < s.SubRule.Length; i++) { SubstitutionRule r = s.SubRule[i]; if (Enum.TryParse(r.Type, true, out ccSR type)) { SetSubValues(type, r, delimiter); } else { LogIt($"Unknown substitution rule type =>{r.Type}<="); } } }
private void SetSubValues(ccSR attribute, SubstitutionRule r, string delimiter) { Prop prop = EIP.AttrDict[ClassCode.Substitution_rules, (byte)attribute].Set; string[] s = r.Text.Split(delimiter[0]); for (int i = 0; i < s.Length; i++) { int n = r.Base + i; // Avoid user errors if (n >= prop.Min && n <= prop.Max) { byte[] data = FormatOutput(prop, n, 1, s[i]); SetAttribute(ClassCode.Substitution_rules, (byte)attribute, data); } } }
private void SetSubValues(ccSR attribute, SubstitutionRule r, string delimiter) { Prop prop = Data.AttrDict[ClassCode.Substitution_rules, (int)attribute].Data; string[] s = r.Text.Split(delimiter[0]); string t = new string(' ', prop.Len); for (int i = 0; i < s.Length; i++) { int n = r.Base + i; // Avoid user errors if (n >= prop.Min && n <= prop.Max) { string t2 = new string(' ', prop.Len) + s[i]; p.SetAttribute(attribute, n - prop.Min, t2.Substring(t2.Length - prop.Len)); } } }
// Set the values associated with a rule private void SetSubValues(ccSR attribute, SubstitutionRule r, string delimiter) { AttrData attr = p.GetAttrData(attribute); Prop prop = attr.Data; string[] s = r.Text.Split(delimiter[0]); int n = Math.Min(attr.Count, s.Length); Section <ccSR> sub = new Section <ccSR>(p, attribute, 0, prop.Len * n, false); { // Avoid many I/Os for (int i = 0; i < n; i++) { if (!string.IsNullOrEmpty(s[i])) { sub.SetAttribute(attribute, i, s[i]); } } sub.WriteSection(); } }
// Send the substitution header public void SendSubstitution(Substitution s) { string delimiter = s.Delimiter; // Need to load the rule (Rule number is 1-origin) p.SetAttribute(ccIDX.Start_Stop_Management_Flag, 1); // Not sure that this is needed p.SetAttribute(ccIDX.Substitution_Rule, s.RuleNumber); // Load the needed substitution rule into memory p.SetAttribute(ccIDX.Start_Stop_Management_Flag, 2); // Again, unsure of the need for this p.SetAttribute(ccIDX.Start_Stop_Management_Flag, 1); // Stack up all substitutions p.SetAttribute(ccSR.Start_Year, s.StartYear); // Set the base year for (int i = 0; i < s.SubRule.Length; i++) // Step thru all rules in the packet { SubstitutionRule r = s.SubRule[i]; // Create a shorthand if (Enum.TryParse(r.Type, true, out ccSR type)) // Valid type? { SetSubValues(type, r, delimiter); // Send the substitution values } else { p.LogIt($"Unknown substitution rule type =>{r.Type}<="); } } p.SetAttribute(ccIDX.Start_Stop_Management_Flag, 2); // Now process the stacked requests }
public static void FromPointsToMidPoint(PointSymbol ps1, PointSymbol ps2, PointSymbol midPoint) { //1. plot the ps1, ps2 and the line //2. generate x coordinate //3. generate y coordinate //4. generate point (x,y) string strategy; var ts00 = new TraceStep(null, ps1, null, PlottingRule.PlottingStrategy, PlottingRule.Plot(ps1)); var ts01 = new TraceStep(null, ps2, null, PlottingRule.PlottingStrategy, PlottingRule.Plot(ps2)); var ls = LineBinaryRelation.Unify(ps1, ps2) as LineSymbol; var ts02 = new TraceStep(null, ls, null, PlottingRule.PlottingStrategy, PlottingRule.Plot(ls)); strategy = "Plot the given two points and the connected line."; midPoint._innerLoop.Add(ts00); midPoint._innerLoop.Add(ts01); midPoint._innerLoop.Add(ts02); midPoint.GenerateATrace(strategy); //////////////////////////////////////////////// var xCoord = new Var("x"); var pt1 = ps1.Shape as Point; Debug.Assert(pt1 != null); var pt2 = ps2.Shape as Point; Debug.Assert(pt2 != null); var term1 = new Term(Expression.Add, new List <object>() { pt1.XCoordinate, pt2.XCoordinate }); var term2 = new Term(Expression.Divide, new List <object>() { term1, 2 }); var eq = new Equation(xCoord, term2); ///////////////////////////////////////////////// object obj; bool result = eq.IsEqGoal(out obj); EqGoal goal1 = null; if (result) { goal1 = obj as EqGoal; Debug.Assert(goal1 != null); Debug.Assert(goal1.Traces.Count == 1); var currentTrace = goal1.Traces.ToList()[0]; strategy = "Generate x coordinate of midpoint."; var newTrace = new Tuple <object, object>(strategy, currentTrace.Item2); midPoint.Traces.Add(newTrace); } ////////////////////////////////////////////////// var yCoord = new Var("y"); term1 = new Term(Expression.Add, new List <object>() { pt1.YCoordinate, pt2.YCoordinate }); term2 = new Term(Expression.Divide, new List <object>() { term1, 2 }); var eq1 = new Equation(yCoord, term2); result = eq1.IsEqGoal(out obj); EqGoal goal2 = null; if (result) { goal2 = obj as EqGoal; Debug.Assert(goal2 != null); Debug.Assert(goal2.Traces.Count == 1); var currentTrace1 = goal2.Traces.ToList()[0]; strategy = "Generate y coordinate of midpoint."; var newTrace = new Tuple <object, object>(strategy, currentTrace1.Item2); midPoint.Traces.Add(newTrace); } ////////////////////////////////////////////////////// var ps = new Point(xCoord, yCoord); var psym = new PointSymbol(ps); var mid = midPoint.Shape as Point; Debug.Assert(mid != null); var ps_inter1 = new Point(mid.XCoordinate, yCoord); var psym_inter1 = new PointSymbol(ps_inter1); var metaRule = "Consider substitute generate x coordinate into the point form."; var appliedRule = SubstitutionRule.ApplySubstitute(goal1, psym); var ts1 = new TraceStep(psym, psym_inter1, null, metaRule, appliedRule); metaRule = "Consider substitute generate y coordinate into the point form."; appliedRule = SubstitutionRule.ApplySubstitute(goal2, psym_inter1); var ts2 = new TraceStep(psym_inter1, midPoint, null, metaRule, appliedRule); strategy = "Generate point (x,y) by subsitute generated x and y."; midPoint._innerLoop.Add(ts1); midPoint._innerLoop.Add(ts2); midPoint.GenerateATrace(strategy); }
public void OptionsOverrideTest() { SubstitutionRule rule = (new Regex(@"^\s*?\#pragma[\sa-zA-Z0-9\/]+$"), "", 0); Assert.Equal(RegexOptions.Compiled | RegexOptions.Multiline, rule.MatchPattern.Options); }
public static void FromPointSlopeToLine(PointSymbol ps, EqGoal goal, LineSymbol ls) { string strategy = "Substitute point and slope property into line form."; // 1. Substitute slope property into the line slope-intercept form. // 2. Calculate the line intercept by substituting the point into line pattern. ////////////////////////////////////////////////////////////////////// string strategy1 = "Substitute slope property into the line slope-intercept form."; var m = new Var("m"); var k = new Var("k"); var x = new Var("x"); var y = new Var("y"); var term = new Term(Expression.Multiply, new List <object>() { m, x }); var term1 = new Term(Expression.Add, new List <object>() { term, k }); var eqPattern = new Equation(y, term1); var term2 = new Term(Expression.Multiply, new List <object>() { goal.Rhs, x }); var term3 = new Term(Expression.Add, new List <object>() { term2, k }); var eqInternal1 = new Equation(y, term3); var appliedRule1 = SubstitutionRule.ApplySubstitute(eqPattern, goal); var ts0 = new TraceStep(eqPattern, eqInternal1, SubstitutionRule.SubstituteKC(), strategy1, appliedRule1); ls._innerLoop.Add(ts0); ////////////////////////////////////////////////////////////////////// var point = ps.Shape as Point; Debug.Assert(point != null); string strategy2 = "Calculate the line intercept by substituting the point into line pattern."; var term4 = new Term(Expression.Multiply, new List <object>() { goal.Rhs, point.XCoordinate }); var term5 = new Term(Expression.Add, new List <object>() { term4, k }); var eqinternal2 = new Equation(point.YCoordinate, term5); object obj; bool result = eqinternal2.IsEqGoal(out obj); var eqGoal = obj as EqGoal; Debug.Assert(eqGoal != null); var gTuple = eqGoal.Traces[0]; var gLst = gTuple.Item2 as List <TraceStep>; Debug.Assert(gLst != null); ls._innerLoop.AddRange(gLst); var appliedRule2 = SubstitutionRule.ApplySubstitute(eqInternal1, ps); var ts = new TraceStep(eqInternal1, ls, SubstitutionRule.SubstituteKC(), strategy2, appliedRule2); ls._innerLoop.Add(ts); ls.GenerateATrace(strategy); }
/* * Automatic scaffolding * * Distance function (x-x0)^2+(y-y0)^2 = d^2 * * Forward chaining to derive d. * Backward chaining to derive other four parameters. */ private static Tuple <object, object> SlopeSubstitution(Point pt1, Point pt2, double value) { //out strategy string strategy = "Substitute two points and slope value into the slope function."; //1. Substitute two points into the line slope function. //2. Substitute slope property into the line slope function. var lst = new List <TraceStep>(); /////////////////////////////////////////////////////////////////// var variable = new Var('m'); //1. string step1metaRule = "Consider the Line Slope Function: m=(y1-y0)/(x1-x0)"; string step1AppliedRule = String.Format( "Substitute two points value into the slope function {0}=({1}-{2})/({3}-{4})", variable, pt2.YCoordinate.ToString(), pt1.YCoordinate.ToString(), pt2.XCoordinate.ToString(), pt1.XCoordinate.ToString()); /* var pt1X = new Var("x0"); * var pt1Y = new Var("y0"); * var pt2X = new Var("x1"); * var pt2Y = new Var("y1");*/ /* var term1_1 = new Term(Expression.Subtract, new List<object>() { pt1X, pt2X }); * var term2_1 = new Term(Expression.Subtract, new List<object>() { pt1Y, pt2Y }); * var rhs_1 = new Term(Expression.Divide, new List<object>() { term2_1, term1_1 }); * * var old_eq = new Equation(variable, rhs_1);*/ var term1_11 = new Term(Expression.Subtract, new List <object>() { pt2.XCoordinate, pt1.XCoordinate }); var term2_11 = new Term(Expression.Subtract, new List <object>() { pt2.YCoordinate, pt1.YCoordinate }); var rhs_11 = new Term(Expression.Divide, new List <object>() { term1_11, term2_11 }); var eq = new Equation(variable, rhs_11); string kc = GeometryScaffold.KC_LineSlopeForm; var trace1 = new TraceStep(null, eq, kc, step1metaRule, step1AppliedRule); //lst.Add(trace1); lst.Add(trace1); /////////////////////////////////////////////////////////////////////////// //2. var newEq = new Equation(value, rhs_11); string step2metaRule = "Substitute slope property into the Line Slope Function: m=(y1-y0)/(x1-x0)"; string step2AppliedRule = String.Format( "Substitute slope value into the slope function {0}=({1}-{2})/({3}-{4})", value, pt2.YCoordinate.ToString(), pt1.YCoordinate.ToString(), pt2.XCoordinate.ToString(), pt1.XCoordinate.ToString()); kc = SubstitutionRule.SubstituteKC(); var trace2 = new TraceStep(null, newEq, kc, step2metaRule, step2AppliedRule); //lst.Add(trace1); lst.Add(trace2); //////////////////////////////////////////////////////////////////////////// var newTuple = new Tuple <object, object>(strategy, lst); return(newTuple); }
public void GenerateYCacheSymbol(object obj, EqGoal goal) { var point = Shape as Point; Debug.Assert(point != null); CachedGoals.Add(new KeyValuePair <object, EqGoal>(PointAcronym.Y, goal)); if (CachedSymbols.Count == 0) { var gPoint = new Point(point.Label, point.XCoordinate, obj); var gPointSymbol = new PointSymbol(gPoint); gPointSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(PointAcronym.Y, goal)); CachedSymbols.Add(gPointSymbol); gPointSymbol.Traces.AddRange(goal.Traces); //transform goal trace for (int i = goal.Traces.Count - 1; i >= 0; i--) { gPoint.Traces.Insert(0, goal.Traces[i]); } //Substitution trace var rule = SubstitutionRule.ApplySubstitute(); var appliedRule = SubstitutionRule.ApplySubstitute(this, goal); var ts = new TraceStep(this, gPointSymbol, SubstitutionRule.SubstituteKC(), rule, appliedRule); gPointSymbol._innerLoop.Add(ts); string strategy = "Reify a Point's y-coordinate by substituing a given fact."; gPointSymbol.GenerateATrace(strategy); //gPoint.Traces.Insert(0, ts); } else { foreach (ShapeSymbol ss in CachedSymbols.ToList()) { var pt = ss.Shape as Point; if (pt != null) { var yResult = LogicSharp.Reify(pt.YCoordinate, goal.ToDict()); if (!pt.YCoordinate.Equals(yResult)) { var gPt = new Point(pt.Label, pt.XCoordinate, pt.YCoordinate); var gPointSymbol = new PointSymbol(gPt); //substitute pt.YCoordinate = yResult; ss.CachedGoals.Add(new KeyValuePair <object, EqGoal>(PointAcronym.Y, goal)); gPointSymbol.Traces.AddRange(goal.Traces); //transform goal trace for (int i = goal.Traces.Count - 1; i >= 0; i--) { pt.Traces.Insert(0, goal.Traces[i]); } string rule = SubstitutionRule.ApplySubstitute(); string appliedRule = SubstitutionRule.ApplySubstitute(this, goal); var ts = new TraceStep(this, gPointSymbol, SubstitutionRule.SubstituteKC(), rule, appliedRule); gPointSymbol._innerLoop.Add(ts); string strategy = "Reify a Point's y-coordinate by substituing a given fact."; gPointSymbol.GenerateATrace(strategy); //pt.Traces.Insert(0, ts); } else { //generate var gPoint = new Point(pt.Label, pt.XCoordinate, obj); var gPointSymbol = new PointSymbol(gPoint); gPointSymbol.Traces.AddRange(goal.Traces); gPointSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(PointAcronym.Y, goal)); foreach (KeyValuePair <object, EqGoal> pair in ss.CachedGoals) { if (pair.Key.Equals(PointAcronym.X)) { gPointSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(PointAcronym.X, pair.Value)); } } CachedSymbols.Add(gPointSymbol); //substitute //Add traces from pt to gPoint for (int i = pt.Traces.Count - 1; i >= 0; i--) { gPoint.Traces.Insert(0, pt.Traces[i]); } //transform goal trace for (int i = goal.Traces.Count - 1; i >= 0; i--) { gPoint.Traces.Insert(0, goal.Traces[i]); } var rule = SubstitutionRule.ApplySubstitute(); var appliedRule = SubstitutionRule.ApplySubstitute(this, goal); var ts = new TraceStep(this, gPointSymbol, SubstitutionRule.SubstituteKC(), rule, appliedRule); gPointSymbol._innerLoop.Add(ts); string strategy = "Reify a Point's y-coordinate by substituing a given fact."; gPointSymbol.GenerateATrace(strategy); //gPoint.Traces.Insert(0, ts); } } } } }
public void CacheC(object obj, EqGoal goal) { CachedGoals.Add(new KeyValuePair <object, EqGoal>(LineAcronym.C, goal)); if (CachedSymbols.Count == 0) { var line = Shape as Line; Debug.Assert(line != null); #region generate new object var gLine = new Line(line.Label, line.A, line.B, obj); var gLineSymbol = new LineSymbol(gLine); gLineSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(LineAcronym.C, goal)); CachedSymbols.Add(gLineSymbol); //Transform goal trace for (int i = goal.Traces.Count - 1; i >= 0; i--) { gLine.Traces.Insert(0, goal.Traces[i]); } //Substitution trace string rule = SubstitutionRule.ApplySubstitute(); string appliedRule = SubstitutionRule.ApplySubstitute(this, goal); string kc = SubstitutionRule.SubstituteKC(); var ts = new TraceStep(this, gLineSymbol, kc, rule, appliedRule); gLine._innerLoop.Add(ts); gLine.GenerateATrace(SubstitutionRule.SubstitutionStrategy); //gLine.Traces.Insert(0, ts); #endregion } else { #region Iterate existing point object foreach (ShapeSymbol ss in CachedSymbols.ToList()) { var line = ss.Shape as Line; if (line != null) { var cResult = LogicSharp.Reify(line.C, goal.ToDict()); if (!line.C.Equals(cResult)) { var gline = new Line(line.Label, line.A, line.B, line.C); var gLineSymbol = new LineSymbol(gline); //substitute line.C = cResult; ss.CachedGoals.Add(new KeyValuePair <object, EqGoal>(LineAcronym.C, goal)); //transform goal trace for (int i = goal.Traces.Count - 1; i >= 0; i--) { line.Traces.Insert(0, goal.Traces[i]); } string rule = SubstitutionRule.ApplySubstitute(); string appliedRule = SubstitutionRule.ApplySubstitute(gLineSymbol, goal); string kc = SubstitutionRule.SubstituteKC(); var ts = new TraceStep(gLineSymbol, ss, kc, rule, appliedRule); //line.Traces.Insert(0, ts); line._innerLoop.Add(ts); line.GenerateATrace(SubstitutionRule.SubstitutionStrategy); } else { //generate var gLine = new Line(line.Label, line.A, line.B, obj); var gLineSymbol = new LineSymbol(gLine); gLineSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(LineAcronym.C, goal)); foreach (KeyValuePair <object, EqGoal> pair in ss.CachedGoals) { if (pair.Key.Equals(LineAcronym.A)) { gLineSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(LineAcronym.A, pair.Value)); } else if (pair.Key.Equals(LineAcronym.B)) { gLineSymbol.CachedGoals.Add(new KeyValuePair <object, EqGoal>(LineAcronym.B, pair.Value)); } } CachedSymbols.Add(gLineSymbol); //substitute //Add traces from line to gLine for (int i = line.Traces.Count - 1; i >= 0; i--) { gLine.Traces.Insert(0, line.Traces[i]); } //transform goal trace for (int i = goal.Traces.Count - 1; i >= 0; i--) { gLine.Traces.Insert(0, goal.Traces[i]); } string rule = SubstitutionRule.ApplySubstitute(); string appliedRule = SubstitutionRule.ApplySubstitute(gLineSymbol, goal); string kc = SubstitutionRule.SubstituteKC(); var ts = new TraceStep(ss, gLineSymbol, kc, rule, appliedRule); gLine._innerLoop.Add(ts); gLine.GenerateATrace(SubstitutionRule.SubstitutionStrategy); //gLine.Traces.Insert(0, ts); } } } #endregion } }