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

339 lines
13 KiB
C#

using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// this is all good, no need to touch anything here
namespace Automata_theory
{
public partial class Laba4
{
public static AutomataTableBase CurrentTable { get; set; }
public static AngerPoll CurrentAngerPoll { get; set; }
public static AutomataTableBase NewTable { get; set; }
public static AngerPoll CalculateAngerPoll(AutomataTableBase table)
{
AngerPoll angerPoll = new AngerPoll(table);
return angerPoll;
}
public static void DisplayAngerPoll(AutomataTableBase table, AngerPoll angerPoll)
{
Range RG = (Range)Globals.ThisAddIn.Application.InputBox($"Куда вставить треугольную таблицу:", Type: 8);
for (int i = 2; i < table.States.Length + 1; i++)
{
RG.Columns[1].Rows[i - 1].Value2 = "s" + Common.SubScripts[i];
//RG.Columns[1].Rows[i - 1].Value2 = "s" + i;
for (int j = i; j < table.States.Length + 1; j++)
{
RG.Columns[i].Rows[j - 1].Value2 =
angerPoll.States1[i - 2, j - 1] == -1 ? ("X " + angerPoll.States2[i - 2, j - 1]).TrimEnd() :
angerPoll.States[i - 2, j - 1] == 1 ? "V" : (angerPoll.States[i - 2, j - 1] == -1 ? "X\n" + angerPoll.States2[i - 2, j - 1] : angerPoll.States[i - 2, j - 1].ToString());
if (angerPoll.States[i - 2, j - 1] == 1) RG.Columns[i].Rows[j - 1].Interior.Color = Color.FromArgb(198, 239, 206);
else if (angerPoll.States[i - 2, j - 1] == -1) RG.Columns[i].Rows[j - 1].Interior.Color = Color.FromArgb(255, 199, 206);
else RG.Columns[i].Rows[j - 1].Interior.Color = Color.FromArgb(255, 235, 156);
}
}
for (int i = 1; i < table.States.Length; i++)
RG.Columns[i + 1].Rows[table.States.Length] = "s" + Common.SubScripts[i];
}
public static AutomataTableBase CalculateNew(AngerPoll angerPoll, AutomataTableBase table)
{
AutomataTableBase newTable = new AutomataTableBase(angerPoll.Sets.Count, table.States[0].Cells.Length);
for (int i = 0; i < newTable.States.Length; i++)
{
AutomataStateBase automataState = new AutomataStateBase(table.States[0].Cells.Length, i);
for (int j = 0; j < newTable.States[i].Cells.Length; j++)
{
int forState = 0, forOutput = 0;
AutomataCellBase automataCell =
new AutomataCellBase(ReverseState(angerPoll.Sets,
table.States[angerPoll.Sets[i][forState]].Cells[j].State),
table.States[angerPoll.Sets[i][forOutput]].Cells[j].Output);
for (; forState < angerPoll.Sets[i].Count && automataCell.State == -1 && angerPoll.Sets[i].Count > 1; forState++)
{
automataCell =
new AutomataCellBase(ReverseState(angerPoll.Sets,
table.States[angerPoll.Sets[i][forState]].Cells[j].State),
table.States[angerPoll.Sets[i][forOutput]].Cells[j].Output);
}
for (; forOutput < angerPoll.Sets[i].Count && automataCell.Output == -1 && angerPoll.Sets[i].Count > 1; forOutput++)
{
automataCell =
new AutomataCellBase(ReverseState(angerPoll.Sets,
table.States[angerPoll.Sets[i][forState]].Cells[j].State),
table.States[angerPoll.Sets[i][forOutput]].Cells[j].Output);
}
automataState.Cells[j] = automataCell;
}
newTable.States[i] = automataState;
}
newTable.Outputs = table.Outputs;
return newTable;
}
public static int ReverseState(List<List<int>> states, int inputState)
{
if (inputState == -1) return -1;
for (int i = 0; i < states.Count; i++)
for (int j = 0; j < states[i].Count; j++)
if (states[i][j] == inputState)
return i;
throw new Exception();
}
}
public class AngerPoll
{
public AngerPoll(AutomataTableBase table)
{
InitTable(table.States.Length);
CheckConflict(table);
CheckSimilarity(table);
CheckConditional(table);
CalculateSets();
}
private void InitTable(int size)
{
_states = new int[size, size];
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
_states[i, j] = -2;
}
private void CheckConflict(AutomataTableBase table)
{
for (int i = 0; i < _states.GetLength(0); i++)
{
for (int j = 0; j < _states.GetLength(1); j++)
{
bool flag = true;
for (int k = 0; k < table.States[0].Cells.Length; k++)
{
if (!flag) break;
if (!(table.States[i].Cells[k].Output ==
table.States[j].Cells[k].Output ||
table.States[i].Cells[k].Output == -1 ||
table.States[j].Cells[k].Output == -1))
flag = false;
}
if (!flag) _states[i, j] = -1;
}
}
_1 = _states;
}
private void CheckSimilarity(AutomataTableBase table)
{
for (int i = 0; i < _states.GetLength(0); i++)
{
for (int j = 0; j < _states.GetLength(1); j++)
{
if (_states[i, j] == -1) continue;
bool flag = true;
for (int k = 0; k < table.States[0].Cells.Length; k++)
{
if (!flag) break;
if (!(table.States[i].Cells[k].State ==
table.States[j].Cells[k].State ||
table.States[i].Cells[k].State == -1 ||
table.States[j].Cells[k].State == -1))
flag = false;
}
_states[i, j] = flag ? 1 : 0;
}
}
}
private void CheckConditional(AutomataTableBase table)
{
_2 = new string[_states.GetLength(0), _states.GetLength(1)];
bool isDone = false;
int counter = 0;
while (!isDone && counter < 100)
{
isDone = true;
for (int i = 0; i < _states.GetLength(0); i++)
{
for (int j = 0; j < _states.GetLength(1); j++)
{
if (_states[i, j] != 0) continue;
bool flag = true; int answer = 0;
for (int k = 0; k < table.States[0].Cells.Length; k++)
{
if (counter == 0 && table.States[i].Cells[k].State + 1 != table.States[j].Cells[k].State + 1)
{
_2[i, j] += $"{table.States[i].Cells[k].State + 1}, {table.States[j].Cells[k].State + 1}\n";
}
if (!flag) break;
if (table.States[i].Cells[k].State != -1 &&
table.States[j].Cells[k].State != -1 &&
_states[table.States[i].Cells[k].State,
table.States[j].Cells[k].State] == -1)
flag = false;
if (table.States[i].Cells[k].State != -1 &&
table.States[j].Cells[k].State != -1 &&
_states[table.States[i].Cells[k].State,
table.States[j].Cells[k].State] == 0)
{
isDone = false;
counter++;
answer = Convert.ToInt32($"{table.States[i].Cells[k].State + 1}" +
$"{table.States[j].Cells[k].State + 1}");
}
}
_states[i, j] = flag ? (counter < 99 ? 0 : (answer == 0 ? 1 : answer)) : -1;
}
}
}
}
private void CalculateSets()
{
List<int[]> skipCell = new List<int[]>();
for (int i = 0; i < _states.GetLength(0); i++)
{
for (int j = _states.GetLength(1) - 1; j > i; j--)
{
if (Contains(skipCell, new int[] { i, j })) continue;
if (_states[i, j] == 1)
{
int vertical = -1, horizontal = -1;
bool hasVertical = false, hasHorizontal = false;
for (int k = j - 1; k > i; k--)
if (_states[i, k] == 1)
{
hasVertical = true;
vertical = i;
break;
//skipCell.Add(new int[] { i, k });
}
for (int k = i + 1; k < j; k++)
if (_states[k, j] == 1)
{
hasHorizontal = true;
horizontal = k;
break;
//skipCell.Add(new int[] { k, j });
}
if (hasVertical && hasHorizontal)
{
skipCell.Add(new int[] { horizontal, j });
skipCell.Add(new int[] { i, horizontal });
_sets.Add(new List<int> { vertical, horizontal, j });
_setsDisp.Add(new List<int> { vertical + 1, horizontal + 1, j + 1 });
}
else
{
_sets.Add(new List<int> { i, j });
_setsDisp.Add(new List<int> { i + 1, j + 1 });
}
}
}
}
for (int i = 0; i < _states.GetLength(0); i++)
{
bool skip = false;
for (int j = 0; j < _sets.Count; j++)
{
for (int k = 0; k < _sets[j].Count; k++)
if (_sets[j][k] == i)
{
skip = true;
break;
}
if (skip) break;
}
if (skip) continue;
else
{
_sets.Add(new List<int> { i });
_setsDisp.Add(new List<int> { i + 1 });
}
}
}
private bool Contains(List<int[]> cells, int[] cell)
{
for (int i = 0; i < cells.Count; i++)
if (cells[i][0] == cell[0] && cells[i][1] == cell[1])
return true;
return false;
}
private int[,] _states;
private int[,] _1;
private string[,] _2;
private List<List<int>> _sets = new List<List<int>>();
private List<List<int>> _setsDisp = new List<List<int>>();
public int[,] States { get { return _states; } }
public int[,] States1 { get { return _1; } }
public string[,] States2 { get { return _2; } }
public List<List<int>> Sets { get { return _sets; } }
public List<List<int>> SetsDisp { get { return _setsDisp; } }
}
public class AutomataTableBase
{
public AutomataTableBase(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;
public int Outputs;
public int Inputs;
public AutomataStateBase[] States { get { return _states; } }
}
public class AutomataStateBase
{
public AutomataStateBase(int inputs, int number)
{
_cells = new AutomataCellBase[inputs];
Number = number;
}
public int Number { get; private set; }
private AutomataCellBase[] _cells;
public AutomataCellBase[] Cells { get { return _cells; } }
}
public class AutomataCellBase
{
public AutomataCellBase(int state, int output)
{
_state = state;
_output = output;
}
private int _state = -1;
private int _output = -1;
public int State { get { return _state; } }
public int Output { get { return _output; } }
}
}