@@ -272,44 +272,217 @@ namespace SolveAvdoshin
273 BooleanFunction f = new BooleanFunction((byte)n);
273 BooleanFunction f = new BooleanFunction((byte)n);
275− ClosedClassPrinting.PrintConservationZero(f);
275+ PostClosedClasses.CheckConservationZero(f, true);
277− ClosedClassPrinting.PrintConservationOne(f);
277+ PostClosedClasses.CheckConservationOne(f, true);
279− ClosedClassPrinting.PrintSelfDuality(f);
279+ PostClosedClasses.CheckSelfDuality(f, true);
281− ClosedClassPrinting.PrintMonotony(f);
281+ PostClosedClasses.CheckMonotony(f, true);
283− ClosedClassPrinting.PrintLinearity(f);
283+ PostClosedClasses.CheckLinearity(f, true);
285 Console.WriteLine();
285 Console.WriteLine();
288+ static readonly Tuple<BooleanOperation, bool[]>[] BinariesAndClasses = {
289+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Zero, new bool[5] { true, false, false, true, true, }),
290+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.And, new bool[5] { true, true, false, true, false, }),
291+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.CoImp, new bool[5] { true, false, false, false, false, }),
292+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.A, new bool[5] { false, false, false, false, false, } ),
293+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.BCoImp, new bool[5] { false, false, false, false, false, } ),
294+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.B, new bool[5] { false, false, false, false, false, } ),
295+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Xor, new bool[5] { true, false, false, false, true, }),
296+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Or, new bool[5] { true, true, false, true, false, }),
297+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.NOR, new bool[5] { false, false, false, false, false, }),
298+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Eq, new bool[5] { false, true, false, false, true, }),
299+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.NotB, new bool[5] { false, false, false, false, false, } ),
300+// new Tuple<BooleanOperation, bool[]>(BooleanOperation.BImp, new bool[5] { false, false, false, false, false, } ),
301+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.NotA, new bool[5] { false, false, true, false, true, }),
302+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.Imp, new bool[5] { false, true, false, false, false, }),
303+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.NAND, new bool[5] { false, false, false, false, false, }),
304+ new Tuple<BooleanOperation, bool[]>(BooleanOperation.One, new bool[5] { false, true, false, true, true, }),
288 public static void PrintRepresentBinariesInF(int n)
307 public static void PrintRepresentBinariesInF(int n)
309+ bool[] functionClasses = PostClosedClasses.GetFunctionClasses(new BooleanFunction((byte)n));
311+ foreach(var t in BinariesAndClasses) {
312+ bool representable = true;
314+ for(int i = 0; i < 5; i++) {
315+ if(functionClasses[i] && !t.Item2[i]) {
316+ representable = false;
324+ Console.Write((new OpExpression(t.Item1, BooleanVariable.A, BooleanVariable.B)).ToString() + " = ");
327+ Console.WriteLine(TertiaryOpExpression.FindMininalExpressionForBinary(t.Item1,
328+ new BooleanFunction((byte)n)));
330+ catch(CouldntFindExpressionException) {
290− Console.WriteLine("Not implemented yet");
331+ Console.WriteLine("не нашлось");
294− static class ClosedClassPrinting
337+ class TertiaryOpExpression : BooleanExpression
296− public static void PrintConservationZero(BooleanFunction f)
339+ BooleanFunction F;
340+ BooleanExpression First, Second, Third;
342+ public TertiaryOpExpression(BooleanFunction f, BooleanExpression first, BooleanExpression second, BooleanExpression third)
350+ public override bool Equals(object obj)
352+ return base.Equals(obj);
355+ public override int GetHashCode()
357+ return base.GetHashCode();
360+ public override string ToString()
362+ return String.Format("F({0},{1},{2})", First.ToString(), Second.ToString(), Third.ToString());
365+ public override int CountOps()
367+ return 1 + First.CountOps() + Second.CountOps() + Third.CountOps();
370+ public override BooleanExpression Clone()
372+ return new TertiaryOpExpression(F, First, Second, Third);
375+ public override byte Eval()
379+ for(int i = 0; i < 8; i++) {
381+ res += F.EvalAt(First.EvalAt(i) * 4 + Second.EvalAt(i) * 2 + Third.EvalAt(i));
387+ public override HashSet<string> GetSetOfAllBlockStrings()
389+ throw new NotImplementedException();
392+ static public IEnumerable<TertiaryOpExpression> CombineTertiary(BooleanFunction f,
393+ BooleanExpression firstExpression, BooleanExpression anotherExpression, BooleanExpression thirdExpression)
395+ yield return new TertiaryOpExpression(f, firstExpression.Clone(), anotherExpression.Clone(),
396+ thirdExpression.Clone());
397+ yield return new TertiaryOpExpression(f, firstExpression.Clone(), thirdExpression.Clone(),
398+ anotherExpression.Clone());
399+ yield return new TertiaryOpExpression(f, anotherExpression.Clone(), firstExpression.Clone(),
400+ thirdExpression.Clone());
401+ yield return new TertiaryOpExpression(f, thirdExpression.Clone(), firstExpression.Clone(),
402+ anotherExpression.Clone());
403+ yield return new TertiaryOpExpression(f, anotherExpression.Clone(), thirdExpression.Clone(),
404+ firstExpression.Clone());
405+ yield return new TertiaryOpExpression(f, thirdExpression.Clone(), anotherExpression.Clone(),
406+ firstExpression.Clone());
409+ public static BooleanExpression FindMininalExpressionForBinary(BooleanOperation binary, BooleanFunction f)
411+ var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
412+ var knownTruthTables = new HashSet<byte>();
413+ var knownExpressions = new HashSet<BooleanExpression>();
415+ var targetExpression = new OpExpression(binary, BooleanVariable.A, BooleanVariable.B);
417+ foreach(var variable in new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, }) {
418+ queue.TryEnqueue(new VarExpression(variable), 1);
421+ while(queue.Count != 0) {
422+ var curExperession = queue.Dequeue();
424+ byte truthTable = curExperession.Eval();
426+ if(knownTruthTables.Contains(truthTable)) {
430+ if((curExperession.Eval() & 0xAA) == (targetExpression.Eval() & 0xAA)) {
431+ return curExperession;
434+ knownExpressions.Add(curExperession);
435+ knownTruthTables.Add(truthTable);
437+ foreach(var anotherExpression in knownExpressions) {
438+ foreach(var thirdExpression in knownExpressions) {
439+ foreach(var neighbourExpression in CombineTertiary(f, curExperession, anotherExpression, thirdExpression)) {
440+ queue.TryEnqueue(neighbourExpression, neighbourExpression.CountOps());
446+ throw new CouldntFindExpressionException();
450+ static class PostClosedClasses
452+ public static bool[] GetFunctionClasses(BooleanFunction f)
454+ return new bool[] { CheckConservationZero(f), CheckConservationOne(f), CheckSelfDuality(f), CheckMonotony(f), CheckLinearity(f), };
457+ public static bool CheckConservationZero(BooleanFunction f, bool verbose = false)
298 if(f.EvalAt(0) == 0) {
459 if(f.EvalAt(0) == 0) {
299− Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
461+ Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
302− Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
467+ Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
306− public static void PrintConservationOne(BooleanFunction f)
473+ public static bool CheckConservationOne(BooleanFunction f, bool verbose = false)
308 if(f.EvalAt(7) == 1) {
475 if(f.EvalAt(7) == 1) {
309− Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
477+ Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
312− Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
483+ Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
@@ -318,16 +491,21 @@ namespace SolveAvdoshin
318 return ((a >> 2) & 1) + "," + ((a >> 1) & 1) + "," + (a & 1);
491 return ((a >> 2) & 1) + "," + ((a >> 1) & 1) + "," + (a & 1);
321− public static void PrintSelfDuality(BooleanFunction f)
494+ public static bool CheckSelfDuality(BooleanFunction f, bool verbose = false)
323 for(int i = 0; i < 8; i++) {
496 for(int i = 0; i < 8; i++) {
324 if(f.EvalAt(i) == f.EvalAt(7 - i)) {
497 if(f.EvalAt(i) == f.EvalAt(7 - i)) {
325− Console.WriteLine("F ∉ T_*, т.к. F({0}) = F({1}) = {2}", PointAsString(i), PointAsString(7 - i), f.EvalAt(i));
499+ Console.WriteLine("F ∉ T_*, т.к. F({0}) = F({1}) = {2}", PointAsString(i), PointAsString(7 - i), f.EvalAt(i));
326− return;
501+ return false;
330− Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
506+ Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
333 static bool AreAdjacent(int a, int b)
511 static bool AreAdjacent(int a, int b)
@@ -360,7 +538,7 @@ namespace SolveAvdoshin
360 return onesA < onesB;
538 return onesA < onesB;
363− public static void PrintMonotony(BooleanFunction f)
541+ public static bool CheckMonotony(BooleanFunction f, bool verbose = false)
365 for(int i = 0; i < 8; i++) {
543 for(int i = 0; i < 8; i++) {
366 for(int j = 0; j < 8; j++) {
544 for(int j = 0; j < 8; j++) {
@@ -368,27 +546,37 @@ namespace SolveAvdoshin
368 continue;
546 continue;
370 if(f.EvalAt(i) > f.EvalAt(j)) {
548 if(f.EvalAt(i) > f.EvalAt(j)) {
371− Console.WriteLine("F ∉ T_<=, т.к. F({0}) > F({1})", PointAsString(i), PointAsString(j));
550+ Console.WriteLine("F ∉ T_<=, т.к. F({0}) > F({1})", PointAsString(i), PointAsString(j));
372− return;
552+ return false;
377− Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
558+ Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
380− public static void PrintLinearity(BooleanFunction f)
563+ public static bool CheckLinearity(BooleanFunction f, bool verbose = false)
382 string zhegalkinRep = f.GetTailorStringXor(0);
565 string zhegalkinRep = f.GetTailorStringXor(0);
384 foreach(string s in new string[] { "AB", "BC", "AC", "ABC", }) {
567 foreach(string s in new string[] { "AB", "BC", "AC", "ABC", }) {
385 if(zhegalkinRep.Contains(s)) {
568 if(zhegalkinRep.Contains(s)) {
386− Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
570+ Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
387− return;
572+ return false;
391− Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
577+ Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
@@ -671,6 +859,11 @@ namespace SolveAvdoshin
671 abstract public BooleanExpression Clone();
859 abstract public BooleanExpression Clone();
672 abstract public int CountOps();
860 abstract public int CountOps();
862+ public int EvalAt(int i)
864+ return (Eval() >> (7 - i)) & 1;
674 public override int GetHashCode()
867 public override int GetHashCode()
676 return ToString().GetHashCode();
869 return ToString().GetHashCode();
@@ -704,51 +897,9 @@ namespace SolveAvdoshin
704 return OpSymbols[(int)op];
897 return OpSymbols[(int)op];
707− class ImprovisedPriorityQueue<T>
709− public int Capacity, Count;
712− public ImprovisedPriorityQueue(int capacity)
714− Capacity = capacity;
717− Queues = new Queue<T>[capacity + 1];
719− for(int i = 1; i <= capacity; i++) {
720− Queues[i] = new Queue<T>();
724− public bool TryEnqueue(T item, int priority)
726− if(priority < 1 || priority > Capacity)
730− Queues[priority].Enqueue(item);
737− throw new Exception("ImprovisedPriorityQueue is empty");
739− for(int i = 1; i <= Capacity; i++) {
740− if(Queues[i].Count != 0) {
742− return Queues[i].Dequeue();
746− throw new Exception("ImprovisedPriorityQueue is empty");
750 public enum ExpressionSearchMode { CountOps, CountBlocks, };
900 public enum ExpressionSearchMode { CountOps, CountBlocks, };
751− public static BooleanExpression FindMininalExpressionInBasis(int n, BooleanOperation[] ops, BooleanVariable[] vars, ExpressionSearchMode mode = ExpressionSearchMode.CountOps)
901+ public static BooleanExpression FindMininalExpressionInBasis(int n, BooleanOperation[] ops,
902+ BooleanVariable[] vars, ExpressionSearchMode mode = ExpressionSearchMode.CountOps)
753 var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
904 var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
754 var knownTruthTables = new HashSet<byte>();
905 var knownTruthTables = new HashSet<byte>();