Files
2024-07-10 19:07:44 +03:00

290 lines
10 KiB
C#

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<List<int>> blocks = CalculateSuggestion(table, 0, 2);
if (blocks.Count > 1)
{
_bBlocks = blocks;
return true;
}
}
return false;
}
private List<List<int>> CalculateSuggestion(AutomataTableBase table, int first, int second)
{
List<List<int>> result = new List<List<int>> { new List<int> { first, second } };
List<List<int>> toSkip = new List<List<int>> { new List<int> { first, second } };
result = CalculateState(result, table);
while (!CheckStop(result, table))
{
for (int i = 0; i < result.Count; i++)
{
List<int> block = new List<int>(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<int>> list, List<int> 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<List<int>> CalculateState(List<List<int>> blocks, AutomataTableBase table, int index = 0)
{
List<List<int>> result = new List<List<int>>(blocks);
for (int i = 0; i < table.Inputs; i++)
{
List<int> block = new List<int> { };
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<List<int>> CleanBlocks(List<List<int>> 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<List<int>> blocks, AutomataTableBase table)
{
List<int> checks = new List<int>();
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<List<int>>();
for (int i = 0; i < _bBlocks.Count; i++)
{
List<int> block = new List<int>();
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<List<int>>();
for (int i = 0; i < _cBlocks.Count; i++)
{
List<int> block = new List<int>();
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<int> block = new List<int>();
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<int> first, List<int> 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<List<int>> 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<List<int>> _bBlocks = new List<List<int>>();
private List<List<int>> _bBlocksDisplay;
private List<List<int>> _cBlocks = new List<List<int>>();
private List<List<int>> _cBlocksDisplay;
private int[,] _states;
private bool isGood;
public List<List<int>> BBlocks { get { return _bBlocks; } }
public List<List<int>> BBlocksDisplay { get { return _bBlocksDisplay; } }
public List<List<int>> CBlocks { get { return _cBlocks; } }
public List<List<int>> 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<int[]> _header = new List<int[]>();
public int Inputs;
public List<int[]> Header { get { return _header; } }
public AutomataStateBase[] States { get { return _states; } }
}
}