using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Automata_theory { partial class Laba5_1 { public static AutomataTableBase CurrentTable { get; set; } public static SPPartition CurrentPartition { get; set; } public static AutomataTableBase CurrentSP1 { get; set; } public static AutomataTableSP CurrentSP2 { get; set; } } public class SPPartition { public SPPartition(AutomataTableBase table) { if (CalculateBBlocks(table)) { CalculateCBlocks(); ReadyBlocks(); CalculateProduct(); CalculateTable(); isGood = true; } else { MessageBox.Show("Нет СП разбиений", "Лаба 5.1", MessageBoxButtons.OK, MessageBoxIcon.Information); isGood = false; } } private bool CalculateBBlocks(AutomataTableBase table) { for (int i = 0; i < table.States.Length; i++) for (int j = i + 1; j < table.States.Length; j++) { List> blocks = CalculateSuggestion(table, 0, 2); if (blocks.Count > 1) { _bBlocks = blocks; return true; } } return false; } private List> CalculateSuggestion(AutomataTableBase table, int first, int second) { List> result = new List> { new List { first, second } }; List> toSkip = new List> { new List { first, second } }; result = CalculateState(result, table); while (!CheckStop(result, table)) { for (int i = 0; i < result.Count; i++) { List block = new List(result[i]); if (Contains(toSkip, result[i])) continue; result = CalculateState(result, table, i); toSkip.Add(block); i = 0; if (CheckStop(result, table)) break; } } return result; } private bool Contains(List> list, List item) { for (int i = 0; i < list.Count; i++) { if (list[i].Count == item.Count) { bool flag = true; for (int j = 0; j < item.Count; j++) if (list[i][j] != item[j]) { flag = false; break; } if (flag) return true; } } return false; } private List> CalculateState(List> blocks, AutomataTableBase table, int index = 0) { List> result = new List>(blocks); for (int i = 0; i < table.Inputs; i++) { List block = new List { }; for (int j = 0; j < blocks[index].Count; j++) if (!block.Contains(table.States[blocks[index][j]].Cells[i].State)) block.Add(table.States[blocks[index][j]].Cells[i].State); block.Sort(); result.Insert(index + 1, block); } result = CleanBlocks(result); return result; } private List> CleanBlocks(List> blocks) { blocks.Sort((a, b) => a[0].CompareTo(b[0])); for (int i = 0; i < blocks.Count; i++) for (int j = i + 1; j < blocks.Count; j++) for (int k = 0; k < blocks[j].Count; k++) if (blocks[i].Contains(blocks[j][k])) { for (int t = 0; t < blocks[j].Count; t++) if (!blocks[i].Contains(blocks[j][t])) blocks[i].Add(blocks[j][t]); blocks.RemoveAt(j); i = 0; j = 0; break; } for (int i = 0; i < blocks.Count; i++) blocks[i].Sort(); blocks.Sort((a, b) => a[0].CompareTo(b[0])); return blocks; } private bool CheckStop(List> blocks, AutomataTableBase table) { List checks = new List(); for (int i = 0; i < table.States.Length; i++) checks.Add(i); for (int i = 0; i < blocks.Count; i++) for (int j = 0; j < blocks[i].Count; j++) checks.Remove(blocks[i][j]); for (int i = 1; i < blocks.Count; i++) if (blocks[i].Count != blocks[0].Count) return false; return checks.Count == 0; } private void ReadyBlocks() { for (int i = 0; i < _bBlocks.Count; i++) _bBlocks[i].Sort(); _bBlocks.Sort((a, b) => a[0].CompareTo(b[0])); _bBlocksDisplay = new List>(); for (int i = 0; i < _bBlocks.Count; i++) { List block = new List(); for (int j = 0; j < _bBlocks[i].Count; j++) block.Add(i); _bBlocksDisplay.Add(block); } for (int i = 0; i < _bBlocks.Count; i++) for (int j = 0; j < _bBlocks[i].Count; j++) _bBlocksDisplay[i][j] = _bBlocks[i][j] + 1; for (int i = 0; i < _cBlocks.Count; i++) _cBlocks[i].Sort(); _cBlocks.Sort((a, b) => a[0].CompareTo(b[0])); _cBlocksDisplay = new List>(); for (int i = 0; i < _cBlocks.Count; i++) { List block = new List(); for (int j = 0; j < _cBlocks[i].Count; j++) block.Add(i); _cBlocksDisplay.Add(block); } for (int i = 0; i < _cBlocks.Count; i++) for (int j = 0; j < _cBlocks[j].Count; j++) _cBlocksDisplay[i][j] = _cBlocks[i][j] + 1; } private void CalculateCBlocks() { for (int i = 0; i < _bBlocks[0].Count; i++) { List block = new List(); for (int j = 0; j < _bBlocks.Count; j++) { block.Add(_bBlocks[j][i]); } _cBlocks.Add(block); } } private void CalculateProduct() { _states = new int[_bBlocks.Count, _cBlocks.Count]; for (int i = 0; i < _bBlocks.Count; i++) for (int j = 0; j < _cBlocks.Count; j++) _states[i, j] = GetMutual(_bBlocks[i], _cBlocks[j]); } private int GetMutual(List first, List second) { for (int i = 0; i < first.Count; i++) for (int j = 0; j < second.Count; j++) if (first[i] == second[j]) return first[i]; throw new Exception(); } private void CalculateTable() { Laba5_1.CurrentSP1 = new AutomataTableBase(_bBlocks.Count, Laba5_1.CurrentTable.Inputs); for (int i = 0; i < _bBlocks.Count; i++) { for (int j = 0; j < Laba5_1.CurrentSP1.Inputs; j++) { Laba5_1.CurrentSP1.States[i].Cells[j] = new AutomataCellBase(ReverseState(_bBlocks, Laba5_1.CurrentTable.States[_bBlocks[i][0]].Cells[j].State), 0); } } Laba5_1.CurrentSP2 = new AutomataTableSP(_cBlocks.Count, Laba5_1.CurrentTable.Inputs * 2); for (int i = 0; i < _cBlocks.Count; i++) // for each c state { for (int j = 0; j < Laba5_1.CurrentTable.Inputs; j++) // for each input { for (int k = 0; k < _bBlocks.Count; k++) // for each b state { if (i == 0) Laba5_1.CurrentSP2.Header.Add(new int[] { j+1, k+1 }); // add title if first pass of c state // access (x and b)th input of sp2 and set state and output Laba5_1.CurrentSP2.States[i].Cells[j * 2 + k] = new AutomataCellBase( ReverseState(_cBlocks, Laba5_1.CurrentTable.States[_states[k, i]].Cells[j].State), Laba5_1.CurrentTable.States[_states[k, i]].Cells[j].Output ); } } } } private int ReverseState(List> states, int state) { for (int i = 0; i < states.Count; i++) { for (int j = 0; j < states[i].Count; j++) { if (states[i][j] == state) return i; } } return -1; } private List> _bBlocks = new List>(); private List> _bBlocksDisplay; private List> _cBlocks = new List>(); private List> _cBlocksDisplay; private int[,] _states; private bool isGood; public List> BBlocks { get { return _bBlocks; } } public List> BBlocksDisplay { get { return _bBlocksDisplay; } } public List> CBlocks { get { return _cBlocks; } } public List> CBlocksDisplay { get { return _cBlocksDisplay; } } public int[,] States { get { return _states; } } public bool IsGood { get { return isGood; } } } public class AutomataTableSP { public AutomataTableSP(int statesAmount, int inputAmount) { _states = new AutomataStateBase[statesAmount]; for (int i = 0; i < statesAmount; i++) _states[i] = new AutomataStateBase(inputAmount, i); Inputs = inputAmount; } private AutomataStateBase[] _states; private List _header = new List(); public int Inputs; public List Header { get { return _header; } } public AutomataStateBase[] States { get { return _states; } } } }