git.iko.soy/ikoHSE/SolveAvdoshin
on master help sign in
ex. 15
81a9365Ilya Gulkov
SolveAvdoshin/BooleanFunctions.cs+220−69
@@ -272,44 +272,217 @@ namespace SolveAvdoshin
272 {
272 {
273 BooleanFunction f = new BooleanFunction((byte)n);
273 BooleanFunction f = new BooleanFunction((byte)n);
274
274
275− ClosedClassPrinting.PrintConservationZero(f);
275+ PostClosedClasses.CheckConservationZero(f, true);
276
276
277− ClosedClassPrinting.PrintConservationOne(f);
277+ PostClosedClasses.CheckConservationOne(f, true);
278
278
279− ClosedClassPrinting.PrintSelfDuality(f);
279+ PostClosedClasses.CheckSelfDuality(f, true);
280
280
281− ClosedClassPrinting.PrintMonotony(f);
281+ PostClosedClasses.CheckMonotony(f, true);
282
282
283− ClosedClassPrinting.PrintLinearity(f);
283+ PostClosedClasses.CheckLinearity(f, true);
284
284
285 Console.WriteLine();
285 Console.WriteLine();
286 }
286 }
287
287
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+
288 public static void PrintRepresentBinariesInF(int n)
307 public static void PrintRepresentBinariesInF(int n)
289 {
308 {
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) {
290− Console.WriteLine("Not implemented yet");
331+ Console.WriteLine("не нашлось");
332+ }
333+ }
291 }
334 }
292 }
335 }
293
336
294− static class ClosedClassPrinting
337+ class TertiaryOpExpression : BooleanExpression
295 {
338 {
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)
297 {
458 {
298 if(f.EvalAt(0) == 0) {
459 if(f.EvalAt(0) == 0) {
460+ if(verbose)
299− Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
461+ Console.WriteLine("F ∈ T_0, т.к. F(0,0,0) = 0");
462+
463+ return true;
300 }
464 }
301 else {
465 else {
466+ if(verbose)
302− Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
467+ Console.WriteLine("F ∉ T_0, т.к. F(0,0,0) = 1");
468+
469+ return false;
303 }
470 }
304 }
471 }
305
472
306− public static void PrintConservationOne(BooleanFunction f)
473+ public static bool CheckConservationOne(BooleanFunction f, bool verbose = false)
307 {
474 {
308 if(f.EvalAt(7) == 1) {
475 if(f.EvalAt(7) == 1) {
476+ if(verbose)
309− Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
477+ Console.WriteLine("F ∈ T_1, т.к. F(1,1,1) = 1");
478+
479+ return true;
310 }
480 }
311 else {
481 else {
482+ if(verbose)
312− Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
483+ Console.WriteLine("F ∉ T_1, т.к. F(1,1,1) = 0");
484+
485+ return false;
313 }
486 }
314 }
487 }
315
488
@@ -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);
319 }
492 }
320
493
321− public static void PrintSelfDuality(BooleanFunction f)
494+ public static bool CheckSelfDuality(BooleanFunction f, bool verbose = false)
322 {
495 {
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)) {
498+ if(verbose)
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));
500+
326− return;
501+ return false;
327 }
502 }
328 }
503 }
329
504
505+ if(verbose)
330− Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
506+ Console.WriteLine("F ∈ T_*, т.к. я на всех наборах проверял, честно!");
507+
508+ return true;
331 }
509 }
332
510
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;
361 }
539 }
362
540
363− public static void PrintMonotony(BooleanFunction f)
541+ public static bool CheckMonotony(BooleanFunction f, bool verbose = false)
364 {
542 {
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;
369
547
370 if(f.EvalAt(i) > f.EvalAt(j)) {
548 if(f.EvalAt(i) > f.EvalAt(j)) {
549+ if(verbose)
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));
551+
372− return;
552+ return false;
373 }
553 }
374 }
554 }
375 }
555 }
376
556
557+ if(verbose)
377− Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
558+ Console.WriteLine("F ∈ T_<=, т.к. я на всех наборах проверял, честно!");
559+
560+ return true;
378 }
561 }
379
562
380− public static void PrintLinearity(BooleanFunction f)
563+ public static bool CheckLinearity(BooleanFunction f, bool verbose = false)
381 {
564 {
382 string zhegalkinRep = f.GetTailorStringXor(0);
565 string zhegalkinRep = f.GetTailorStringXor(0);
383
566
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)) {
569+ if(verbose)
386− Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
570+ Console.WriteLine("F ∉ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
571+
387− return;
572+ return false;
388 }
573 }
389 }
574 }
390
575
576+ if(verbose)
391− Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
577+ Console.WriteLine("F ∈ T_L, т.к. F(A,B,C) = " + zhegalkinRep);
578+
579+ return true;
392 }
580 }
393 }
581 }
394
582
@@ -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();
673
861
862+ public int EvalAt(int i)
863+ {
864+ return (Eval() >> (7 - i)) & 1;
865+ }
866+
674 public override int GetHashCode()
867 public override int GetHashCode()
675 {
868 {
676 return ToString().GetHashCode();
869 return ToString().GetHashCode();
@@ -704,51 +897,9 @@ namespace SolveAvdoshin
704 return OpSymbols[(int)op];
897 return OpSymbols[(int)op];
705 }
898 }
706
899
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−
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)
752 {
903 {
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>();
SolveAvdoshin/DataStructures.csnew file+49
@@ -0,0 +1,49 @@
1+using System;
2+using System.Collections.Generic;
3+
4+namespace SolveAvdoshin
5+{
6+ public class ImprovisedPriorityQueue<T>
7+ {
8+ public int Capacity, Count;
9+ Queue<T>[] Queues;
10+
11+ public ImprovisedPriorityQueue(int capacity)
12+ {
13+ Capacity = capacity;
14+ Count = 0;
15+
16+ Queues = new Queue<T>[capacity + 1];
17+
18+ for(int i = 1; i <= capacity; i++) {
19+ Queues[i] = new Queue<T>();
20+ }
21+ }
22+
23+ public bool TryEnqueue(T item, int priority)
24+ {
25+ if(priority < 1 || priority > Capacity)
26+ return false;
27+
28+ Count += 1;
29+ Queues[priority].Enqueue(item);
30+ return true;
31+ }
32+
33+ public T Dequeue()
34+ {
35+ if(Count == 0)
36+ throw new Exception("ImprovisedPriorityQueue is empty");
37+
38+ for(int i = 1; i <= Capacity; i++) {
39+ if(Queues[i].Count != 0) {
40+ Count -= 1;
41+ return Queues[i].Dequeue();
42+ }
43+ }
44+
45+ throw new Exception("ImprovisedPriorityQueue is empty");
46+ }
47+ }
48+}
49+
SolveAvdoshin/SolveAvdoshin.csproj+1
@@ -37,6 +37,7 @@
37 <Compile Include="AndXorEquation.cs" />
37 <Compile Include="AndXorEquation.cs" />
38 <Compile Include="SolveAvdoshin.cs" />
38 <Compile Include="SolveAvdoshin.cs" />
39 <Compile Include="BooleanFunctions.cs" />
39 <Compile Include="BooleanFunctions.cs" />
40+ <Compile Include="DataStructures.cs" />
40 </ItemGroup>
41 </ItemGroup>
41 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
42 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
42</Project>
43</Project>