public static OperandsMap Create(Operands from, Operands to) { if (to.Count >= from.Count) { if (from.Zip(to, (a, b) => a == b).All(_ => _)) { return(new MatchingOperandsMap(from, to)); } } return(new UnmatchingOperandsMap(from, to)); }
public UnmatchingOperandsMap(Operands from, Operands to) { _numTargetOperands = to.Count; UnusedMask = (1ul << to.Count) - 1; UnusedCount = to.Count - from.Count; var lookup = to.Select((_, i) => new KeyValuePair <string, int>(_, i)) .ToDictionary(_ => _.Key, _ => _.Value); _indices = new int[from.Count]; for (var index = 0; index < from.Count; index++) { var i = _indices[index] = lookup[from[index]]; UnusedMask &= ~(1ul << i); } }
public TruthTable(FlatExpression expression) { _operands = expression.Operands; ulong size = 1; if (_operands.Count > 5) { size = 1ul << (_operands.Count - 5); } _table = new uint[size]; foreach (var line in expression.Lines) { this[line.Mask] = true; } }
public void And(int numOperands) { var rnd = new Random(10); var operandsA = new Operands(Enumerable.Range(0, numOperands).Select(_ => (char)('A' + rnd.Next(0, numOperands * 2))).Distinct().OrderBy(_ => _).Select(_ => _.ToString())); var operandsB = new Operands(Enumerable.Range(0, numOperands).Select(_ => (char)('A' + rnd.Next(0, numOperands * 2))).Distinct().OrderBy(_ => _).Select(_ => _.ToString())); var itemsA = Enumerable.Range(0, 1 << (numOperands - 1)).Select(_ => (ulong)rnd.Next(0, 1 << operandsA.Count)).Distinct().OrderBy(_ => _).Select(_ => new FlatExpressionLine(_)).ToArray(); var itemsB = Enumerable.Range(0, 1 << (numOperands - 1)).Select(_ => (ulong)rnd.Next(0, 1 << operandsB.Count)).Distinct().OrderBy(_ => _).Select(_ => new FlatExpressionLine(_)).ToArray(); var a = new FlatExpression(operandsA, itemsA); var b = new FlatExpression(operandsB, itemsB); Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(a.And(b)); Console.WriteLine(a.Or(b)); Console.WriteLine(new TruthTable(a.Or(b))); }
public static FlatExpression And(FlatExpression a, FlatExpression b) { var allOperands = new Operands(a.Operands.Concat(b.Operands).Distinct().OrderBy(_ => _)); var expandedA = a.ExpandTo(allOperands).Lines.ToList(); expandedA.Sort(); var expandedB = b.ExpandTo(allOperands).Lines.ToList(); expandedB.Sort(); var list = new List <FlatExpressionLine>(); using (var iA = expandedA.GetEnumerator()) { using (var iB = expandedB.GetEnumerator()) { var hasA = iA.MoveNext(); var hasB = iB.MoveNext(); while (hasA && hasB) { if (iA.Current.Mask == iB.Current.Mask) { list.Add(iA.Current); hasA = iA.MoveNext(); hasB = iB.MoveNext(); } else if (iA.Current.Mask < iB.Current.Mask) { hasA = iA.MoveNext(); } else { hasB = iB.MoveNext(); } } return(new FlatExpression(allOperands, list.ToArray())); } } }
public void RandomExpression_ConvertFromFlatToTreeAndBack_SameResult(int numOperands, int numRandoms, int randomSeed) { var operands = new Operands(Enumerable.Range(0, numOperands).Select(_ => (char)('A' + _)).Select(_ => _.ToString())); var rnd = new Random(randomSeed); var items = Enumerable.Range(0, numRandoms).Select(_ => (ulong)rnd.Next(0, 1 << numOperands)).Distinct().OrderBy(_ => _).Select(_ => new FlatExpressionLine(_)).ToArray(); var originalFlat = new FlatExpression(operands, items); var tree = originalFlat.AsTreeExpression(); var flatExpression = originalFlat.AsFlatExpression(); if (numOperands <= 5) { Console.WriteLine(originalFlat); Console.WriteLine(tree); Console.WriteLine(flatExpression); } Assert.AreEqual(originalFlat.Lines.Count, flatExpression.Lines.Count); for (var index = 0; index < flatExpression.Lines.Count; index++) { Assert.AreEqual(originalFlat.Lines[index], flatExpression.Lines[index]); } }
public FlatExpression(Operands operands, params FlatExpressionLine[] lines) { _operands = operands; _lines = lines; }
public FlatExpression ExpandTo(Operands operands) { var map = OperandsMap.Create(_operands, operands); return(new FlatExpression(operands, map.Variator.GetVariations(_lines))); }
public FlatExpression() { _operands = Operands.Empty; _lines = emptyLines; }
public string ToString(Operands operands) { if (Type == TreeExpressionItemType.Always) { return(PreprocessorExpression.True); } if (Type == TreeExpressionItemType.Never) { return(PreprocessorExpression.False); } var ifDef = IfDefined.AsBool(); var ifNotDef = IfNotDefined.AsBool(); var sb = new StringBuilder(); if (ifDef != false) { if (ifNotDef != false) { sb.Append("("); } { if (ifDef != true) { sb.Append("("); } sb.Append("defined("); sb.Append(operands[Index]); sb.Append(")"); if (ifDef != true) { sb.Append(" && "); sb.Append(IfDefined.ToString(operands)); sb.Append(")"); } } if (ifNotDef != false) { sb.Append(" || "); if (ifNotDef != true) { sb.Append("("); } sb.Append("!defined("); sb.Append(operands[Index]); sb.Append(")"); if (ifNotDef != true) { sb.Append(" && "); sb.Append(IfNotDefined.ToString(operands)); sb.Append(")"); } sb.Append(")"); } } else { if (ifNotDef != true) { sb.Append("("); } sb.Append("!defined("); sb.Append(operands[Index]); sb.Append(")"); if (ifNotDef != true) { sb.Append(" && "); sb.Append(IfNotDefined.ToString(operands)); sb.Append(")"); } } return(sb.ToString()); }
public MatchingOperandsMap(Operands from, Operands to) { _varitationBits = to.Count - from.Count; _varitationOffset = from.Count; }
public TreeExpression() { _operands = Operands.Empty; _root = TreeExpressionItem.Never; }