public SegmentLimit <Variable> AssignInParallel <Expression>(Dictionary <Variable, FList <Variable> > sourceToTargets, Converter <Variable, Expression> convert, IExpressionDecoder <Variable, Expression> decoder) { #region Contracts Contract.Requires(sourceToTargets != null); Contract.Requires(convert != null); Contract.Requires(decoder != null); Contract.Ensures(Contract.Result <SegmentLimit <Variable> >() != null); #endregion var newSet = new Set <NormalizedExpression <Variable> >(); foreach (var x in expressions) { Contract.Assume(x != null); FList <Variable> targets; int value; Variable var; if (x.IsConstant(out value)) { newSet.Add(x); } else if (x.IsVariable(out var)) { if (sourceToTargets.TryGetValue(var, out targets)) { Contract.Assume(targets != null); foreach (var newName in targets.GetEnumerable()) { newSet.Add(NormalizedExpression <Variable> .For(newName)); } } } else if (x.IsAddition(out var, out value)) { if (sourceToTargets.TryGetValue(var, out targets)) { Contract.Assume(targets != null); foreach (var newName in targets.GetEnumerable()) { newSet.Add(NormalizedExpression <Variable> .For(newName, value)); } } // This is a special case to handle renaming for a[p++] = ... // We have (var + value) --> var Variable source; if (IsATarget(var, sourceToTargets, out source)) { Variable v; int k; if (decoder.TryMatchVarPlusConst(convert(source), out v, out k) && v.Equals(var) && k == value) { newSet.Add(NormalizedExpression <Variable> .For(var)); } } } } return(new SegmentLimit <Variable>(newSet, this.IsConditional)); }