using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using static System.Windows.Forms.AxHost; namespace Automata_theory { partial class Laba6 { public static Partitions Partitions { get; set; } public static int GetPartitionsCount(int statesAmount) { if (statesAmount <= 4) return 2; if (statesAmount <= 8) return 3; else if (statesAmount <= 16) return 4; throw new ArgumentOutOfRangeException(); } } public class Partitions { public Partitions(AutomataTableBase table, int partitions, bool doPi, List>> P = null) { this.partitions = partitions; do { MakePiPartitions(table, doPi, P); } while (GetIntersectionOfAllSets(pi).Count < table.States.Length); MakeTables(table); MakeTauPartitions(table); MakeEtaPartitions(table); CalculateDependancies(); CalculateTranslations(table); CalculateFunctionG(table); } private void MakePiPartitions(AutomataTableBase table, bool doPi, List>> P) { if (doPi) { this.pi = P; return; } this.pi = GenerateLists(partitions, table.States.Length); } static List>> GenerateLists(int a, int b) { List>> result = new List>>(); Random rand = new Random(); for (int i = 0; i < a; i++) { List> list1 = new List>(); List numbers = new List(); for (int j = 0; j < b; j++) { numbers.Add(j); } Shuffle(numbers, rand); int midPoint = numbers.Count / 2; List subset1 = numbers.GetRange(0, midPoint); List subset2 = numbers.GetRange(midPoint, b - midPoint); list1.Add(subset1); list1.Add(subset2); result.Add(list1); } return result; } static void Shuffle(List list, Random rand) { int n = list.Count; while (n > 1) { n--; int k = rand.Next(n + 1); int value = list[k]; list[k] = list[n]; list[n] = value; } } private List> GetIntersectionOfAllSets(List>> listOfSets) { if (listOfSets == null || listOfSets.Count == 0) { // Handle invalid input, return an empty list or throw an exception as needed return new List>(); } // Initialize the result with the first set List> result = listOfSets[0]; // Iterate through the rest of the sets and find the intersection for (int i = 1; i < listOfSets.Count; i++) { result = IntersectSets(result, listOfSets[i]); } return result; } private List> IntersectSets(List> set1, List> set2) { var intersection = new List>(); foreach (var subset1 in set1) { foreach (var subset2 in set2) { var commonElements = subset1.Intersect(subset2).ToList(); if (commonElements.Count > 0) { intersection.Add(commonElements); } } } return intersection; } private void MakeTables(AutomataTableBase table) { for (int i = 0; i < partitions; i++) // for each partition { AutomataTableBase newTable = new AutomataTableBase(table.States.Length, table.Inputs); for (int j = 0; j < table.States.Length; j++) // for each state { newTable.States[j] = new AutomataStateBase(table.Inputs, j); for (int k = 0; k < table.Inputs; k++) // for each input { newTable.States[j].Cells[k] = new AutomataCellBase(ReverseState(pi[i], table.States[j].Cells[k].State), -1); } } tables.Add(newTable); } } private int ReverseState(List> sets, int state, bool invert = false) { for (int i = 0; i < sets.Count; i++) { for (int j = 0; j < sets[i].Count; j++) { if (sets[i][j] == state) return invert ? Math.Abs(i - 1) : i; } } return -1; } private void MakeTauPartitions(AutomataTableBase table) { for (int i = 0; i < partitions; i++) // for each partition { tau.Add(new List>()); List skip = new List(); for (int j = 0; j < tables[i].States.Length; j++) // for each state { if (skip.Contains(j)) continue; List set = new List() { j }; List input = new List(); for (int k = 0; k < tables[i].Inputs; k++) // for each input { input.Add(tables[i].States[j].Cells[k].State); } for (int k = j + 1; k < tables[i].States.Length; k++) // for each state after current { bool flag = true; for (int u = 0; u < tables[i].Inputs; u++) // for each input { if (tables[i].States[k].Cells[u].State != tables[i].States[j].Cells[u].State) { flag = false; break; } } if (flag) { set.Add(k); skip.Add(k); } } tau[i].Add(set); } } } private void MakeEtaPartitions(AutomataTableBase table) { for (int i = 0; i < partitions; i++) // for each partition { eta.Add(new List>()); List skip = new List(); for (int j = 0; j < tables[i].Inputs; j++) // for each state -> input { if (skip.Contains(j)) continue; List set = new List() { j }; List input = new List(); for (int k = 0; k < tables[i].States.Length; k++) // for each input -> state { input.Add(tables[i].States[k].Cells[j].State); } for (int k = j + 1; k < tables[i].Inputs; k++) // for each state after current -> input after { bool flag = true; for (int u = 0; u < tables[i].Inputs; u++) // for each input -> state { if (tables[i].States[u].Cells[k].State != tables[i].States[u].Cells[j].State) { flag = false; break; } } if (flag) { set.Add(k); skip.Add(k); } } eta[i].Add(set); } } } private void CalculateDependancies() { //for (int i = 0; i < partitions; i++) //{ // for (int j = 0; j < partitions; j++) // { // if (j == i) continue; // List> intersections = IntersectSets(pi[i], pi[j]); // if (IsSetOfSetsContained()) // } //} // TODO: Make the algorithm properly for (int i = 0; i < partitions; i++) { dependancies.Add(new List()); for (int j = 0; j < partitions; j++) { if (i == j) continue; dependancies[i].Add(j); } } } private void CalculateTranslations(AutomataTableBase table) { //--- Laba7.TriggerFunctions = new List(); //--- for (int i = 0; i < partitions; i++) { Laba7.TriggerFunctions.Add(new TriggerFunction()); relativeTables.Add(new AutomataTableRelative()); relativeTables[i].StateCount = 2; List ints = new List(); for (int j = 0; j < Math.Pow(2, dependancies[i].Count); j++) ints.Add(j); for (int j = 0; j < ints.Count; j++) // для каждой комбинации зависимостей { List states = new List(); // состояния пи разбиения (после итерации должно остаться одно) states.AddRange(pi[i][0]); states.AddRange(pi[i][1]); int currentState = ints[j]; for (int k = 0; k < dependancies[i].Count; k++) { states = states.Intersect(pi[dependancies[i][k]][currentState & 1]).ToList(); currentState >>= 1; } // вычислили все состояния (должен быть длины 1) for (int k = 0; k < eta[i].Count; k++) { List cells = new List(); // создаем новый ряд для двух состояний for (int u = 0; u < 2; u++) // для каждого (двух) состояний { List newStates = new List(states); newStates = newStates.Intersect(pi[i][u]).ToList(); if (newStates.Count == 0) cells.Add(new AutomataCellRelative(-2)); else { int st = ReverseState(pi[i], table.States[newStates[0]].Cells[eta[i][k][0]].State); cells.Add(new AutomataCellRelative(st)); if (st == 0 && u == 1) Laba7.TriggerFunctions[i].AddNewRule($"{Laba7.MakeBinary(k, eta[i].Count)}", $"{ReturnCorrectBinary(Convert.ToString(ints[j], 2).PadLeft(partitions - 1, '0'), $"{u}", i)}"); } } relativeTables[i].Rows.Add( new AutomataRowRelative(GenerateUserFriendlyName(dependancies[i].Count, 98 + i, k, ints[j]), $"{Laba7.MakeBinary(ints[j], partitions - 1, true)} {Laba7.MakeBinary(k, eta[i].Count)}", cells)); } } } } private string ReturnCorrectBinary(string a, string b, int c) { string result = ""; bool flag = false; for (int i = 0; i < a.Length; i++) { if (i == c) { result += b; flag = true; } result += a[i]; } if (!flag) result += b; return result; } private string GenerateUserFriendlyName(int numOfStates, int skipLetter, int input, int state) { string result = ""; int nextLetter = 98; for (int i = 0; i < numOfStates; i++) { if (nextLetter == skipLetter) nextLetter++; result += $"{(char)(nextLetter)}{Common.SubScripts[Math.Abs((state & 1) + 1)]} * "; nextLetter++; state >>= 1; } result = result.Substring(0, result.Length - 3); result += $", x{input + 1}"; return result; } private void CalculateFunctionG(AutomataTableBase table) { tableG = new AutomataTableG(table); Laba7.TriggerFunctions.Add(new TriggerFunction()); for (int i = 0; i < table.States.Length; i++) { List ints = new List(); for (int j = 0; j < pi.Count; j++) { if (pi[j][0].Contains(i)) ints.Add(1); else ints.Add(0); } // foud where is this state number in each pi partition string title = ""; for (int j = 0; j < ints.Count; j++) title += $"{(char)(98 + j)}{Common.SubScripts[ints[j] == 0 ? 2 : 1]} * "; title = title.Substring(0, title.Length - 3); tableG.Titles[i] = title; tableG.BinTitles[i] = string.Join(" ", ints.Select(x => Math.Abs(x -1))); for (int j = 0; j < tableG.Inputs; j++) if (table.States[i].Cells[j].Output == 2) Laba7.TriggerFunctions[partitions].AddNewRule(Laba7.MakeBinary(j, tableG.Inputs), tableG.BinTitles[i]); } } public static List IntersectSets(List> list) { if (list == null || list.Count == 0) { return new List(); } List commonNumbers = new List(list[0]); foreach (List intList in list) { commonNumbers = commonNumbers.Intersect(intList).ToList(); } return commonNumbers; } private List> dependancies = new List>(); private int partitions; private List>> pi = new List>>(); private List>> tau = new List>>(); private List>> eta = new List>>(); private List tables = new List(); private List relativeTables = new List(); private AutomataTableG tableG; public int Count { get { return partitions; } } public List>> Pi { get { return pi; } set { pi = value; } } public List>> Tau { get { return tau; } } public List>> Eta { get { return eta; } } public List Tables { get { return tables; } } public List RelativeTables { get { return relativeTables; } } public AutomataTableG TableG { get { return tableG; } } } public class AutomataTableG { public AutomataTableG(AutomataTableBase table) { _states = new AutomataStateBase[table.States.Length]; for (int i = 0; i < table.States.Length; i++) { _states[i] = new AutomataStateBase(table.Inputs, i); for (int j = 0; j < table.Inputs; j++) { _states[i].Cells[j] = new AutomataCellBase(table.States[i].Cells[j].State, table.States[i].Cells[j].Output); } } Inputs = table.Inputs; Outputs = table.Outputs; _titles = new string[table.States.Length]; _binTitles = new string[table.States.Length]; } private AutomataStateBase[] _states; private string[] _titles; private string[] _binTitles; public int Outputs; public int Inputs; public AutomataStateBase[] States { get { return _states; } } public string[] Titles { get { return _titles; } set { _titles = value; } } public string[] BinTitles { get { return _binTitles; } set { _binTitles = value; } } } public class AutomataTableRelative { public AutomataTableRelative() { _rows = new List(); } public int StateCount; private List _rows; public List Rows { get { return _rows; } set { _rows = value; } } } public class AutomataRowRelative { public AutomataRowRelative(string name) { _name = name; _cells = new List (); } public AutomataRowRelative(string name, string binName, List cells) { _name = name; _binName = binName; _cells = cells; } private string _name = string.Empty; public string Name { get { return _name; } } private string _binName = string.Empty; public string BinName { get { return _binName; } } private List _cells; public List Cells { get { return _cells; } } } public class AutomataCellRelative { public AutomataCellRelative(int state) { _state = state; } private int _state = -1; public int State { get { return _state; } } } }