@@ -272,44 +272,217 @@ namespace SolveAvdoshin
272272 {
273273 BooleanFunction f = new BooleanFunction((byte)n);
274274
275− ClosedClassPrinting.PrintConservationZero(f);
275+ PostClosedClasses.CheckConservationZero(f, true);
276276
277− ClosedClassPrinting.PrintConservationOne(f);
277+ PostClosedClasses.CheckConservationOne(f, true);
278278
279− ClosedClassPrinting.PrintSelfDuality(f);
279+ PostClosedClasses.CheckSelfDuality(f, true);
280280
281− ClosedClassPrinting.PrintMonotony(f);
281+ PostClosedClasses.CheckMonotony(f, true);
282282
283− ClosedClassPrinting.PrintLinearity(f);
283+ PostClosedClasses.CheckLinearity(f, true);
284284
285285 Console.WriteLine();
286286 }
287287
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, }),
305+ };
306+
288307 public static void PrintRepresentBinariesInF(int n)
289308 {
290− Console.WriteLine("Not implemented yet");
309+ bool[] functionClasses = PostClosedClasses.GetFunctionClasses(new BooleanFunction((byte)n));
310+
311+ foreach(var t in BinariesAndClasses) {
312+ bool representable = true;
313+
314+ for(int i = 0; i < 5; i++) {
315+ if(functionClasses[i] && !t.Item2[i]) {
316+ representable = false;
317+ break;
318+ }
319+ }
320+
321+ if(!representable)
322+ continue;
323+
324+ Console.Write((new OpExpression(t.Item1, BooleanVariable.A, BooleanVariable.B)).ToString() + " = ");
325+
326+ try {
327+ Console.WriteLine(TertiaryOpExpression.FindMininalExpressionForBinary(t.Item1,
328+ new BooleanFunction((byte)n)));
329+ }
330+ catch(CouldntFindExpressionException) {
331+ Console.WriteLine("не нашлось");
332+ }
333+ }
291334 }
292335 }
293336
294− static class ClosedClassPrinting
337+ class TertiaryOpExpression : BooleanExpression
295338 {
296− public static void PrintConservationZero(BooleanFunction f)
339+ BooleanFunction F;
340+ BooleanExpression First, Second, Third;
341+
342+ public TertiaryOpExpression(BooleanFunction f, BooleanExpression first, BooleanExpression second, BooleanExpression third)
343+ {
344+ F = f;
345+ First = first;
346+ Second = second;
347+ Third = third;
348+ }
349+
350+ public override bool Equals(object obj)
351+ {
352+ return base.Equals(obj);
353+ }
354+
355+ public override int GetHashCode()
356+ {
357+ return base.GetHashCode();
358+ }
359+
360+ public override string ToString()
361+ {
362+ return String.Format("F({0},{1},{2})", First.ToString(), Second.ToString(), Third.ToString());
363+ }
364+
365+ public override int CountOps()
366+ {
367+ return 1 + First.CountOps() + Second.CountOps() + Third.CountOps();
368+ }
369+
370+ public override BooleanExpression Clone()
371+ {
372+ return new TertiaryOpExpression(F, First, Second, Third);
373+ }
374+
375+ public override byte Eval()
376+ {
377+ int res = 0;
378+
379+ for(int i = 0; i < 8; i++) {
380+ res *= 2;
381+ res += F.EvalAt(First.EvalAt(i) * 4 + Second.EvalAt(i) * 2 + Third.EvalAt(i));
382+ }
383+
384+ return (byte)res;
385+ }
386+
387+ public override HashSet<string> GetSetOfAllBlockStrings()
388+ {
389+ throw new NotImplementedException();
390+ }
391+
392+ static public IEnumerable<TertiaryOpExpression> CombineTertiary(BooleanFunction f,
393+ BooleanExpression firstExpression, BooleanExpression anotherExpression, BooleanExpression thirdExpression)
394+ {
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());
407+ }
408+
409+ public static BooleanExpression FindMininalExpressionForBinary(BooleanOperation binary, BooleanFunction f)
410+ {
411+ var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
412+ var knownTruthTables = new HashSet<byte>();
413+ var knownExpressions = new HashSet<BooleanExpression>();
414+
415+ var targetExpression = new OpExpression(binary, BooleanVariable.A, BooleanVariable.B);
416+
417+ foreach(var variable in new BooleanVariable[] { BooleanVariable.A, BooleanVariable.B, }) {
418+ queue.TryEnqueue(new VarExpression(variable), 1);
419+ }
420+
421+ while(queue.Count != 0) {
422+ var curExperession = queue.Dequeue();
423+
424+ byte truthTable = curExperession.Eval();
425+
426+ if(knownTruthTables.Contains(truthTable)) {
427+ continue;
428+ }
429+
430+ if((curExperession.Eval() & 0xAA) == (targetExpression.Eval() & 0xAA)) {
431+ return curExperession;
432+ }
433+
434+ knownExpressions.Add(curExperession);
435+ knownTruthTables.Add(truthTable);
436+
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());
441+ }
442+ }
443+ }
444+ }
445+
446+ throw new CouldntFindExpressionException();
447+ }
448+ }
449+
450+ static class PostClosedClasses
451+ {
452+ public static bool[] GetFunctionClasses(BooleanFunction f)
453+ {
454+ return new bool[] { CheckConservationZero(f), CheckConservationOne(f), CheckSelfDuality(f), CheckMonotony(f), CheckLinearity(f), };
455+ }
456+
457+ public static bool CheckConservationZero(BooleanFunction f, bool verbose = false)
297458 {
298459 if(f.EvalAt(0) == 0) {
299− Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
460+ if(verbose)
461+ Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
462+
463+ return true;
300464 }
301465 else {
302− Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
466+ if(verbose)
467+ Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
468+
469+ return false;
303470 }
304471 }
305472
306− public static void PrintConservationOne(BooleanFunction f)
473+ public static bool CheckConservationOne(BooleanFunction f, bool verbose = false)
307474 {
308475 if(f.EvalAt(7) == 1) {
309− Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
476+ if(verbose)
477+ Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
478+
479+ return true;
310480 }
311481 else {
312− Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
482+ if(verbose)
483+ Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
484+
485+ return false;
313486 }
314487 }
315488
@@ -318,16 +491,21 @@ namespace SolveAvdoshin
318491 return ((a >> 2) & 1) + "," + ((a >> 1) & 1) + "," + (a & 1);
319492 }
320493
321− public static void PrintSelfDuality(BooleanFunction f)
494+ public static bool CheckSelfDuality(BooleanFunction f, bool verbose = false)
322495 {
323496 for(int i = 0; i < 8; i++) {
324497 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));
326− return;
498+ if(verbose)
499+ Console.WriteLine("F ∉ T_*, т.к. F({0}) = F({1}) = {2}", PointAsString(i), PointAsString(7 - i), f.EvalAt(i));
500+
501+ return false;
327502 }
328503 }
329504
330− Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
505+ if(verbose)
506+ Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
507+
508+ return true;
331509 }
332510
333511 static bool AreAdjacent(int a, int b)
@@ -360,7 +538,7 @@ namespace SolveAvdoshin
360538 return onesA < onesB;
361539 }
362540
363− public static void PrintMonotony(BooleanFunction f)
541+ public static bool CheckMonotony(BooleanFunction f, bool verbose = false)
364542 {
365543 for(int i = 0; i < 8; i++) {
366544 for(int j = 0; j < 8; j++) {
@@ -368,27 +546,37 @@ namespace SolveAvdoshin
368546 continue;
369547
370548 if(f.EvalAt(i) > f.EvalAt(j)) {
371− Console.WriteLine("F ∉ T_<=, т.к. F({0}) > F({1})", PointAsString(i), PointAsString(j));
372− return;
549+ if(verbose)
550+ Console.WriteLine("F ∉ T_<=, т.к. F({0}) > F({1})", PointAsString(i), PointAsString(j));
551+
552+ return false;
373553 }
374554 }
375555 }
376556
377− Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
557+ if(verbose)
558+ Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
559+
560+ return true;
378561 }
379562
380− public static void PrintLinearity(BooleanFunction f)
563+ public static bool CheckLinearity(BooleanFunction f, bool verbose = false)
381564 {
382565 string zhegalkinRep = f.GetTailorStringXor(0);
383566
384567 foreach(string s in new string[] { "AB", "BC", "AC", "ABC", }) {
385568 if(zhegalkinRep.Contains(s)) {
386− Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
387− return;
569+ if(verbose)
570+ Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
571+
572+ return false;
388573 }
389574 }
390575
391− Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
576+ if(verbose)
577+ Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
578+
579+ return true;
392580 }
393581 }
394582
@@ -671,6 +859,11 @@ namespace SolveAvdoshin
671859 abstract public BooleanExpression Clone();
672860 abstract public int CountOps();
673861
862+ public int EvalAt(int i)
863+ {
864+ return (Eval() >> (7 - i)) & 1;
865+ }
866+
674867 public override int GetHashCode()
675868 {
676869 return ToString().GetHashCode();
@@ -704,51 +897,9 @@ namespace SolveAvdoshin
704897 return OpSymbols[(int)op];
705898 }
706899
707− class ImprovisedPriorityQueue<T>
708− {
709− public int Capacity, Count;
710− Queue<T>[] Queues;
711−
712− public ImprovisedPriorityQueue(int capacity)
713− {
714− Capacity = capacity;
715− Count = 0;
716−
717− Queues = new Queue<T>[capacity + 1];
718−
719− for(int i = 1; i <= capacity; i++) {
720− Queues[i] = new Queue<T>();
721− }
722− }
723−
724− public bool TryEnqueue(T item, int priority)
725− {
726− if(priority < 1 || priority > Capacity)
727− return false;
728−
729− Count += 1;
730− Queues[priority].Enqueue(item);
731− return true;
732− }
733−
734− public T Dequeue()
735− {
736− if(Count == 0)
737− throw new Exception("ImprovisedPriorityQueue is empty");
738−
739− for(int i = 1; i <= Capacity; i++) {
740− if(Queues[i].Count != 0) {
741− Count -= 1;
742− return Queues[i].Dequeue();
743− }
744− }
745−
746− throw new Exception("ImprovisedPriorityQueue is empty");
747− }
748− }
749−
750900 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)
752903 {
753904 var queue = new ImprovisedPriorityQueue<BooleanExpression>(20);
754905 var knownTruthTables = new HashSet<byte>();