public static FlatExpression Not(FlatExpression a) { if (a._operands.Count >= 64) { throw new NotImplementedException(); } var maxLines = 1ul << a._operands.Count; var expectedLines = (1ul << a._operands.Count) - (ulong)a._lines.Length; var lines = new FlatExpressionLine[expectedLines]; long index = 0; long j = 0; ulong i = 0; for (; i < maxLines && index < a._lines.LongLength; ++i) { if (i < a._lines[index].Mask) { lines[j] = new FlatExpressionLine(i); ++j; } else { ++index; } } for (; i < maxLines; ++i) { lines[j] = new FlatExpressionLine(i); ++j; } return(new FlatExpression(a.Operands, lines.ToArray())); }
public TreeExpression(FlatExpression expression) { _operands = expression.Operands; var lines = expression.Lines.ToList(); _root = Split(lines, _operands.Count - 1, 0, lines.Count); }
public static FlatExpression Or(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) { list.Add(iA.Current); hasA = iA.MoveNext(); } else { list.Add(iB.Current); hasB = iB.MoveNext(); } } while (hasA) { list.Add(iA.Current); hasA = iA.MoveNext(); } while (hasB) { list.Add(iB.Current); hasB = iB.MoveNext(); } return(new FlatExpression(allOperands, list.ToArray())); } } }
public void FlatExpression_Not(ulong mask) { var e = new FlatExpression(new Operands("A", "B"), new FlatExpressionLine[] { new FlatExpressionLine(mask), }); var not = FlatExpression.Not(e); Assert.AreEqual(3, not.Lines.Count); foreach (var line in not.Lines) { Assert.AreNotEqual(line, mask); } }
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 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 And(FlatExpression b) { return(And(this, b)); }
public FlatExpression Or(FlatExpression b) { return(Or(this, b)); }
public void FlatExpression_Empty_ToString() { var e = new FlatExpression(); Assert.AreEqual(PreprocessorExpression.False, e.ToString()); }