/// <summary> /// If the statement doesn't alter anything in the block, then no problem. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var varsAffectedResults = followStatement.ResultVariables.Intersect(Limit.Dependants.Concat(Counter.Dependants).Select(s => s.RawValue)); var varsAffectedDependents = followStatement.DependentVariables.Intersect(Counter.Dependants.Select(s => s.RawValue)); return(!varsAffectedResults.Any() && !varsAffectedDependents.Any()); }
/// <summary> /// See what would be needed to combine these two things. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementTestLoopPairwise; if (otherS == null) return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); return Tuple.Create(true, replaceFirst) .RequireAreSame(_whatIsGood, otherS._whatIsGood) .RequireAreSame(_test, otherS._test) .ExceptFor(replaceFirst); }
/// <summary> /// Can this get combined? Weird if it does, actually! /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementReturn; if (otherS == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } return Tuple.Create(true, replaceFirst) .RequireAreSame(_rtnValue, otherS._rtnValue) .ExceptFor(replaceFirst); }
/// <summary> /// To make the same, what renames are required? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementRecordIndicies; if (otherS == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } return Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(_storageArray, otherS._storageArray) .RequireAreSame(_intToRecord, otherS._intToRecord) .ExceptFor(replaceFirst); }
/// <summary> /// Check to see what it would take to make this and another statement look identical. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementMinMaxTest; if (otherS == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } if (CompareOperator != otherS.CompareOperator) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } return Tuple.Create(true, replaceFirst) .RequireAreSame(exprToMinOrMaximize, otherS.exprToMinOrMaximize) .RequireForEquivForExpression(vIsFilled, otherS.vIsFilled) .RequireForEquivForExpression(MaxMinVariable, otherS.MaxMinVariable) .ExceptFor(replaceFirst); }
/// <summary> /// Can we make these two things identical? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherThrow = other as StatementThrowIfTrue; if (otherThrow == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string,string>>()); } if (_message != otherThrow._message) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } // Last, see if the tests can be made the same. return Tuple.Create(true, replaceFirst) .RequireAreSame(_testValue, otherThrow._testValue) .ExceptFor(replaceFirst); }
/// <summary> /// Collect renames required in order to turn this into another any/all statement /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementAnyAllDetector; if (otherS == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } if ((ResultValueToBe != otherS.ResultValueToBe) || ((Predicate == null && otherS.Predicate == null) || (Predicate != null && otherS.Predicate != null))) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } var r = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(Result, otherS.Result); if (Predicate != null) { r = r .RequireAreSame(Predicate, otherS.Predicate); } return r.ExceptFor(replaceFirst); }
/// <summary> /// If we can make it all look the same... /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementRecordPairValues; if (otherS == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } if (_savers.Count != otherS._savers.Count) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } var r = Tuple.Create(true, replaceFirst) .RequireAreSame(_index, otherS._index); foreach (var spair in _savers.Zip(otherS._savers, (us, them) => Tuple.Create(us, them))) { r = r .RequireAreSame(spair.Item1.indexValue, spair.Item2.indexValue) .RequireForEquivForExpression(spair.Item1.mapRecord, spair.Item2.mapRecord); } return r.ExceptFor(replaceFirst); }
/// <summary> /// Can we move the other to look like this code? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> /// <remarks> /// We do not have to worry about unique variables since they are internal only, and never make it outside /// one of these statements. /// </remarks> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst) { // Do some basic tests to try to fail early. if (!(other is CPPCodeStatement)) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } var s2 = other as CPPCodeStatement; if ((s2._linesOfCode.Count != _linesOfCode.Count) || (s2._uniqueVariableTranslations.Count != _uniqueVariableTranslations.Count) || (s2._paramReplacesments.Count != _paramReplacesments.Count)) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } // Lines of C++ code have to be identical (obviously). var differentCode = _linesOfCode .Zip(s2._linesOfCode, (u, t) => Tuple.Create(u, t)) .Where(i => i.Item1 != i.Item2); if (differentCode.Any()) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } // First, handle the result. var renames = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(_cppResult.RawValue, s2._cppResult.RawValue); // Finally, we have to look at the parameters. We do this check in order. foreach (var pTwo in _paramReplacesments.Zip(s2._paramReplacesments, (u, t) => Tuple.Create(u, t))) { // Make sure parameter names are the same. if (pTwo.Item1.Item1 != pTwo.Item2.Item1) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } renames = renames .RequireForEquivForExpression(pTwo.Item1.Item2, DependentVariables, pTwo.Item2.Item2, s2.DependentVariables); } // If here, then we are set. return renames .ExceptFor(replaceFirst); }
public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { throw new NotImplementedException(); }
/// <summary> /// We have a statement that we want to move out of this if statement. Make sure it isn't going to alter /// anything we are looking at in our if statement! /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var varsImpacted = followStatement.ResultVariables.Intersect(TestExpression.Dependants.Select(s => s.RawValue)); return(!varsImpacted.Any()); }
/// <summary> /// See if we can make these two statements the same. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { if (!(other is StatementAggregate)) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } var s2 = other as StatementAggregate; return Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(ResultVariable, s2.ResultVariable) .RequireAreSame(Expression, s2.Expression); }
/// <summary> /// To make the same, what renames are required? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementRecordIndicies; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } return(Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(_storageArray, otherS._storageArray) .RequireAreSame(_intToRecord, otherS._intToRecord) .ExceptFor(replaceFirst)); }
/// <summary> /// See if we can combine two of these. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public override Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherS = other as StatementIfOnCount; if (otherS == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } if (Comparison != otherS.Comparison) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } var renames = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(Counter, otherS.Counter) .RequireAreSame(Limit, otherS.Limit); return RequiredForEquivalenceForBase(otherS, renames); }
/// <summary> /// If we can make it all look the same... /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementRecordPairValues; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } if (_savers.Count != otherS._savers.Count) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var r = Tuple.Create(true, replaceFirst) .RequireAreSame(_index, otherS._index); foreach (var spair in _savers.Zip(otherS._savers, (us, them) => Tuple.Create(us, them))) { r = r .RequireAreSame(spair.Item1.indexValue, spair.Item2.indexValue) .RequireForEquivForExpression(spair.Item1.mapRecord, spair.Item2.mapRecord); } return(r.ExceptFor(replaceFirst)); }
/// <summary> /// Do we commute with the gateway expressions? /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var varsUsed = followStatement.ResultVariables.Intersect(_whatIsGood.Dependants.Concat(_indciesToInspect.Dependants).Select(p => p.RawValue)); return !varsUsed.Any(); }
/// <summary> /// See if we can't make everything the same. Since we have so many expressions to manage, this isn't totally "fun". /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { if (!(other is StatementRecordValue)) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var s2 = other as StatementRecordValue; if (s2._recordOnlyFirstValue != _recordOnlyFirstValue || s2._savers.Count != _savers.Count) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // Now, just look at all the expressions. Yes this is a monad. Yes I should use something real. var renames = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(_valueWasSeen, s2._valueWasSeen); foreach (var o in s2._savers) { var ms = _savers.Where(s => s.Item2.RawValue == o.Item2.RawValue).FirstOrDefault(); if (ms == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } renames = renames .RequireForEquivForExpression(o.Item1, ms.Item1); } return(renames.ExceptFor(replaceFirst)); }
public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst) { if (other is StatementWithNoSideEffects) { return Tuple.Create(true, Enumerable.Empty<Tuple<string, string>>()); } else { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } }
public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst) { if (other is StatementWithSideEffects) { var s2 = other as StatementWithSideEffects; var renames = new List<Tuple<string, string>>(); if (_trackedVar.RawValue != s2._trackedVar.RawValue) { renames.Add(new Tuple<string, string>(s2._trackedVar.RawValue, _trackedVar.RawValue)); } if (_resultVar != null && s2._resultVar != null) { if (_resultVar.RawValue != s2._resultVar.RawValue) { renames.Add(new Tuple<string, string>(s2._resultVar.RawValue, _resultVar.RawValue)); } } if ((_resultVar == null || s2._resultVar == null) && _resultVar != s2.ResultVariables) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } return Tuple.Create(true, renames as IEnumerable<Tuple<string,string>>); } else { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } }
public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst) { throw new NotImplementedException(); }
/// <summary> /// Since there is no gateway check like an if statement, this is automatically true. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { return(true); }
/// <summary> /// Check to see what it would take to make this and another statement look identical. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementMinMaxTest; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } if (CompareOperator != otherS.CompareOperator) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } return(Tuple.Create(true, replaceFirst) .RequireAreSame(exprToMinOrMaximize, otherS.exprToMinOrMaximize) .RequireForEquivForExpression(vIsFilled, otherS.vIsFilled) .RequireForEquivForExpression(MaxMinVariable, otherS.MaxMinVariable) .ExceptFor(replaceFirst)); }
/// <summary> /// Check to see if the statement commutes with our loop expression. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var varInConflict = followStatement.ResultVariables.Intersect(ArrayLength.Dependants.Select(s => s.RawValue)); return(!varInConflict.Any()); }
/// <summary> /// Can we make these two statements identical. /// In this case, we will do the substitution, and if they are the same, then we will indicate so. /// But if they aren't we will make no attempt to make them the same. So, this works only in a trivial case. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns>Tests if we can do the replacement</returns> /// <remarks> /// This will cause evaluation of the stored function. /// </remarks> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherSimple = other as StatementSimpleStatement; if (otherSimple == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // Compare - if the same then we are in good shape! var ourline = Line; var thereline = otherSimple.Line; if (ourline.ReplaceVariableNames(replaceFirst) == thereline) { return(Tuple.Create(true, Enumerable.Empty <Tuple <string, string> >())); } return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); }
/// <summary> /// Can this statement be made the same as some other statement? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementIncrementInteger; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } return(Tuple.Create(true, replaceFirst) .RequireAreSame(Integer, otherS.Integer) .ExceptFor(replaceFirst)); }
/// <summary> /// Can we move the other to look like this code? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> /// <remarks> /// We do not have to worry about unique variables since they are internal only, and never make it outside /// one of these statements. /// </remarks> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst) { // Do some basic tests to try to fail early. if (!(other is CPPCodeStatement)) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var s2 = other as CPPCodeStatement; if ((s2._linesOfCode.Count != _linesOfCode.Count) || (s2._uniqueVariableTranslations.Count != _uniqueVariableTranslations.Count) || (s2._paramReplacesments.Count != _paramReplacesments.Count)) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // Lines of C++ code have to be identical (obviously). var differentCode = _linesOfCode .Zip(s2._linesOfCode, (u, t) => Tuple.Create(u, t)) .Where(i => i.Item1 != i.Item2); if (differentCode.Any()) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // First, handle the result. var renames = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(_cppResult.RawValue, s2._cppResult.RawValue); // Finally, we have to look at the parameters. We do this check in order. foreach (var pTwo in _paramReplacesments.Zip(s2._paramReplacesments, (u, t) => Tuple.Create(u, t))) { // Make sure parameter names are the same. if (pTwo.Item1.Item1 != pTwo.Item2.Item1) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } renames = renames .RequireForEquivForExpression(pTwo.Item1.Item2, DependentVariables, pTwo.Item2.Item2, s2.DependentVariables); } // If here, then we are set. return(renames .ExceptFor(replaceFirst)); }
/// <summary> /// If the statement doesn't alter anything in the block, then no problem. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var varsAffectedResults = followStatement.ResultVariables.Intersect(Limit.Dependants.Concat(Counter.Dependants).Select(s => s.RawValue)); var varsAffectedDependents = followStatement.DependentVariables.Intersect(Counter.Dependants.Select(s => s.RawValue)); return !varsAffectedResults.Any() && !varsAffectedDependents.Any(); }
/// <summary> /// Collect renames required in order to turn this into another any/all statement /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementAnyAllDetector; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } if ((ResultValueToBe != otherS.ResultValueToBe) || ((Predicate == null && otherS.Predicate == null) || (Predicate != null && otherS.Predicate != null))) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var r = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(Result, otherS.Result); if (Predicate != null) { r = r .RequireAreSame(Predicate, otherS.Predicate); } return(r.ExceptFor(replaceFirst)); }
/// <summary> /// Two statements should become common. Take care of everything. /// </summary> /// <param name="renames"></param> /// <param name="s1"></param> /// <param name="s2"></param> /// <returns></returns> public static Tuple <bool, IEnumerable <Tuple <string, string> > > RequireForEquivForExpression(this Tuple <bool, IEnumerable <Tuple <string, string> > > renames, ICMStatementInfo s1, ICMStatementInfo s2) { if (!renames.Item1) { return(renames); } if (s1 == null || s2 == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // Run the require for the two statements. var r = s1.RequiredForEquivalence(s2, renames.Item2); if (!r.Item1) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } if (r.Item2 == null || r.Item2.Count() == 0) { return(renames); } var renamesItem = renames.Item2 == null?Enumerable.Empty <Tuple <string, string> >() : renames.Item2; return(Tuple.Create(true, renamesItem.Concat(r.Item2))); }
/// <summary> /// Since there is no gateway check like an if statement, this is automatically true. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { return true; }
/// <summary> /// Do we commute with the gateway expressions? /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var varsUsed = followStatement.ResultVariables.Intersect(_whatIsGood.Dependants.Concat(_indciesToInspect.Dependants).Select(p => p.RawValue)); return(!varsUsed.Any()); }
/// <summary> /// Can we make these two statements identical. /// In this case, we will do the substitution, and if they are the same, then we will indicate so. /// But if they aren't we will make no attempt to make them the same. So, this works only in a trivial case. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns>Tests if we can do the replacement</returns> /// <remarks> /// This will cause evaluation of the stored function. /// </remarks> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { var otherSimple = other as StatementSimpleStatement; if (otherSimple == null) return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); // Compare - if the same then we are in good shape! var ourline = Line; var thereline = otherSimple.Line; if (ourline.ReplaceVariableNames(replaceFirst) == thereline) { return Tuple.Create(true, Enumerable.Empty<Tuple<string, string>>()); } return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); }
/// <summary> /// Can we get past the loop controls? This is a bit of a mess. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var dependentVariables = _mapRecords.SelectMany(m => m.mapRecords.Dependants).Select(s => s.RawValue); return(!followStatement.ResultVariables.Intersect(dependentVariables).Any()); }
/// <summary> /// See if we can't make everything the same. Since we have so many expressions to manage, this isn't totally "fun". /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple<bool, IEnumerable<Tuple<string, string>>> RequiredForEquivalence(ICMStatementInfo other, IEnumerable<Tuple<string, string>> replaceFirst = null) { if (!(other is StatementRecordValue)) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } var s2 = other as StatementRecordValue; if (s2._recordOnlyFirstValue != _recordOnlyFirstValue || s2._savers.Count != _savers.Count) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } // Now, just look at all the expressions. Yes this is a monad. Yes I should use something real. var renames = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(_valueWasSeen, s2._valueWasSeen); foreach (var o in s2._savers) { var ms = _savers.Where(s => s.Item2.RawValue == o.Item2.RawValue).FirstOrDefault(); if (ms == null) { return Tuple.Create(false, Enumerable.Empty<Tuple<string, string>>()); } renames = renames .RequireForEquivForExpression(o.Item1, ms.Item1); } return renames.ExceptFor(replaceFirst); }
/// <summary> /// Make an attempt to combine if statements. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public override Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { // Quick check. if (!(other is StatementFilter)) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var s2 = other as StatementFilter; // Do the test expression. var renames = Tuple.Create(true, replaceFirst) .RequireAreSame(TestExpression, s2.TestExpression); // And do everything in the block return(RequiredForEquivalenceForBase(other, renames) .ExceptFor(replaceFirst)); }
/// <summary> /// See if we can combine two of these. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public override Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementIfOnCount; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } if (Comparison != otherS.Comparison) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var renames = Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(Counter, otherS.Counter) .RequireAreSame(Limit, otherS.Limit); return(RequiredForEquivalenceForBase(otherS, renames)); }
/// <summary> /// Can we figure out a way to make the second statement look like the first one? /// </summary> /// <param name="other"></param> /// <returns>What should be changed in other to make it equivalent to this statement</returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { // Well, if we can't we can't. if (!(other is StatementAssign)) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var s2 = other as StatementAssign; return(Tuple.Create(true, replaceFirst) .RequireForEquivForExpression(ResultVariable, s2.ResultVariable) .RequireAreSame(Expression, s2.Expression)); }
/// <summary> /// Can we move a statement past the for loop? /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { return(!followStatement.ResultVariables.Intersect(_mapOfGroups.Dependants.Select(p => p.RawValue)).Any()); }
/// <summary> /// Check to see if we can move past the loop limits. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { return !followStatement.ResultVariables.Intersect(arrayRecord.Dependants.Select(p => p.RawValue)).Any(); }
/// <summary> /// See what would be needed to combine these two things. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherS = other as StatementTestLoopPairwise; if (otherS == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } return(Tuple.Create(true, replaceFirst) .RequireAreSame(_whatIsGood, otherS._whatIsGood) .RequireAreSame(_test, otherS._test) .ExceptFor(replaceFirst)); }
/// <summary> /// If there is no expression surrounding, then return true. Otherwise, one will /// have to carefully double check! /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public abstract bool CommutesWithGatingExpressions(ICMStatementInfo followStatement);
/// <summary> /// Test to see if this for loop is the same as the other statement. Identical, in a way that we can delete the "other" totally after /// appropriate renaming. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public override Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { // Make sure it is a for statement. if (!(other is StatementForLoop)) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } var s2 = other as StatementForLoop; // Make sure the limit is the same, along with the initial value, after applying the replacements. Then figure out the rename // for the loop variable. var renames = Tuple.Create(true, replaceFirst) .RequireAreSame(ArrayLength, s2.ArrayLength) .RequireAreSame(InitialValue, s2.InitialValue) .RequireForEquivForExpression(_loopVariable, s2._loopVariable); // And do everything in the block return(RequiredForEquivalenceForBase(other, renames) .ExceptFor(replaceFirst)); }
/// <summary> /// We can't determine directly if we can combine. /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public virtual Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); }
/// <summary> /// Helper routine. Pass it all renames relevant, and it will do all the testing. /// It will return the FULL rename list, including everything you have passed in! /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> protected virtual Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalenceForBase(ICMStatementInfo other, Tuple <bool, IEnumerable <Tuple <string, string> > > renames) { if (!renames.Item1) { return(renames); } // We assume this works at this point! var s2 = other as StatementInlineBlockBase; // If the number of statements isn't the same, then this doesn't matter. if (Statements.Count() != s2.Statements.Count()) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // Loop through the statements, accumulating renames as we go. foreach (var s in Statements.Zip(s2.Statements, (st1, st2) => Tuple.Create(st1, st2))) { renames = renames .RequireForEquivForExpression(s.Item1 as ICMStatementInfo, s.Item2 as ICMStatementInfo); } // If we make it here, then we are good. The last thing to do before returning the result is to remove // any renames and any declared variables var declaredVariables = s2.DeclaredVariables; return(renames .FilterRenames(i => !declaredVariables.Select(p => p.RawValue).Contains(i.Item1))); }
/// <summary> /// Can we get past the loop controls? This is a bit of a mess. /// </summary> /// <param name="followStatement"></param> /// <returns></returns> public override bool CommutesWithGatingExpressions(ICMStatementInfo followStatement) { var dependentVariables = _mapRecords.SelectMany(m => m.mapRecords.Dependants).Select(s => s.RawValue); return !followStatement.ResultVariables.Intersect(dependentVariables).Any(); }
/// <summary> /// Can we make these two things identical? /// </summary> /// <param name="other"></param> /// <param name="replaceFirst"></param> /// <returns></returns> public Tuple <bool, IEnumerable <Tuple <string, string> > > RequiredForEquivalence(ICMStatementInfo other, IEnumerable <Tuple <string, string> > replaceFirst = null) { var otherThrow = other as StatementThrowIfTrue; if (otherThrow == null) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } if (_message != otherThrow._message) { return(Tuple.Create(false, Enumerable.Empty <Tuple <string, string> >())); } // Last, see if the tests can be made the same. return(Tuple.Create(true, replaceFirst) .RequireAreSame(_testValue, otherThrow._testValue) .ExceptFor(replaceFirst)); }