Реализация сетевой модели вычислений с аксиоматической и рекурсивной формами задания функций и предикатов (бакалаврская работа)
.pdf40
class NTerm { //Нетерминал internal string Name;
internal List<TVertex> def = new List<TVertex>();
internal static NTerm Start = null; internal OnAction action = null;
static NTerm() { CreateWord();
}
static void CreateWord() {
NTerm res = new NTerm(); res.Name = "$Буква";
Add(res);
for(int i = 97; i <= 122; i++) { TVertex v = new TVertex(); TVertex vi = new TVertex();
v.edges = new TWEdge((char)i + "", vi); res.def.Add(v);
}
res = new NTerm(); res.Name = "$ЗагБуква";
Add(res);
for(int i = 65; i < 91; i++) { TVertex v = new TVertex(); TVertex vi = new TVertex();
v.edges = new TWEdge((char)i + "", vi); res.def.Add(v);
}
res = new NTerm(); res.Name = "$Цифра";
Add(res);
for(int i = 48; i <= 57; i++) { TVertex v = new TVertex();
41
TVertex vi = new TVertex();
v.edges = new TWEdge((char)i + "", vi); res.def.Add(v);
}
res = new NTerm(); res.Name = "$Пусто";
Add(res);
res.def.Add(new TVertex());
}
public override string ToString() { return Name;
}
}
class TEdge { //эпсилон дуга
internal TVertex next; //Указатель на сл вершину internal TEdge(TVertex vertex) {
next = vertex;
}
}
class TWEdge:TEdge { //Взвешенная дуга public string c;
public TWEdge(string c, TVertex vertex) : base(vertex) {
this.c = c;
}
public override string ToString() { return c + "";
}
}
42
class TVertex { //вершина графа
internal TEdge edges = null; //Исходящие дуги
internal NTerm nterm = null; //Указатель на определяющий
нетерминал
public override string ToString() { if(edges == null)
return "final"; else
return "->" + edges;
}
}
#endregion
static List<Result> Rec(TVertex v, string str) { List<Result> bk = new List<Result>(); if(v.nterm != null) {
foreach(TVertex def in v.nterm.def)
bk = bk.Concat(Rec(def, str)).ToList(); if(bk.Count == 0) {
return new List<Result>();
} else
if(v.nterm.action != null) {
for(int i = 0; i < bk.Count; i++) {
Pair pair = new Pair(v.nterm.action , v.nterm.Name, str.Substring(0, str.Length - bk[i].s.Length));
bk[i].lst.Insert(0,pair);
}
}
} else {
bk.Add(new Result(str, new List<Pair>()));
}
//В bk список всевозможных вариантов //Для каждого варианта
List<Result> result = new List<Result>(); if(v.edges == null) {
return bk; } else {
TWEdge w = v.edges as TWEdge; if(w == null) {
43
foreach (Result res in bk)
{
List<Result> restmp = Rec(v.edges.next, res.s); foreach (Result rr in restmp)
rr.lst = res.lst.Concat(rr.lst).ToList(); result = result.Concat(restmp).ToList();
}
} else {
foreach(Result res in bk) { if(res.s.Length >= w.c.Length)
if(res.s.Substring(0, w.c.Length) == w.c) { List<Result> restmp = Rec(v.edges.next,
res.s.Substring(w.c.Length));
foreach (Result rr in restmp)
rr.lst = res.lst.Concat(rr.lst).ToList(); result = result.Concat(restmp).ToList();
}
}
}
return result;
}
}
static NTerm CreateTerm(string name) { NTerm res = new NTerm();
res.Name = name; Add(res);
return res;
}
static TVertex CreateForString(TVertex start, string s) {
TVertex v = start;
TVertex vi = new TVertex(); v.edges = new TWEdge(s, vi); v = vi;
return v;
}
static OnLog Log = null;
44
#region Паблики
public static void Create(List<string> lst, string Start, OnLog param =
null) {
AssignLog(param);
Write("Создание автомата по списку правил"); for(int i = 0; i < lst.Count; i++) {
if (lst[i].Length >= 2) {
if (lst[i].Substring(0, 2) == @"//") continue;
}
string[] arr = lst[i].Split('=');
string temp = lst[i].Substring(arr[0].Length+1); NTerm res = Get( p => p.Name == arr[0]);
if (res == null)
res = CreateTerm(arr[0]); TVertex v = new TVertex(); res.def.Add(v);
arr = temp.Split('_');
for(int j = 0; j < arr.Length; j++) { if(arr[j][0] == '$') {
if(v.nterm != null) {
TVertex v1 = new TVertex();
v1.nterm = Get(p => p.Name == arr[j]); if(v1.nterm == null)
v1.nterm = CreateTerm(arr[j]); v.edges = new TEdge(v1);
v = v1; } else {
v.nterm = Get(p => p.Name == arr[j]); if(v.nterm == null)
v.nterm = CreateTerm(arr[j]);
}
}else {
v= CreateForString(v, arr[j]);
}
}
if (Check())
NTerm.Start = Get(p => p.Name == Start);
}
45
public static void AssigEvent(params PairAssign[] input) { foreach(PairAssign p in input) {
NTerm nt = Get(q => q.Name == p.Name); if(nt == null)
Write(p.Name + " Action not assigned"); else {
nt.action = p.Action;
Write(p.Name + " Action assigned");
}
}
}
public static string Parse(string s) {
if(NTerm.Start == null)
return "Ошибка разбора - не найдено начальное состояние
автомата";
if (s.Length == 0)
return "Ошибка разбора - строка пуста"; if (s.Length >= 2)
if (s.Substring(0, 2) == @"//")
return "Разбор - стркоа закомментирована";
List<Result> bk = new List<Result>(); foreach(TVertex def in NTerm.Start.def) bk = bk.Concat(Rec(def, s)).ToList();
bk = bk.Where(p => p.s == "").ToList();
if(bk.Count > 1) {
return "Ошибка разбора - неоднозначный вывод " + s;
} else if(bk.Count == 1) {
if(NTerm.Start.action != null) {
Pair pair = new Pair(NTerm.Start.action, NTerm.Start.Name, s.Substring(0, s.Length - bk[0].s.Length));
bk[0].lst.Insert(0,pair);
}
for(int i = 0; i < bk[0].lst.Count; i++) bk[0].lst[i].Action(bk[0].lst[i].param);
46
return "Разбор - завершен удачно";
} else {
return "Ошибка разбора - не удалось произвести вывод";
}
}
static void AssignLog(OnLog param) { param("Parser", "Установка события");
Log = param;
}
#endregion
#region Работа со списком нетерминалов
static readonly List<NTerm> nterms = new List<NTerm>(); //Список всех возможных нетерминалов
static NTerm Get(int i) { return nterms[i];
}
static NTerm Get(Func<NTerm,bool> predicate) { return nterms.FirstOrDefault(p => predicate(p));
}
static bool Check() { bool result = true;
foreach(NTerm nt in nterms) { if(nt.def.Count == 0) {
Write("No defined " + nt.Name); result = false;
}
}
return result;
}
static void Add(NTerm n) { Write("Creating " + n.Name); nterms.Add(n);
}
#endregion
47
static void Write(string s) { if (Log != null) {
Log("Parser", s);
}
}
}
}
4. Классы для объектов внутреннего представления НО
public abstract class Base {
public PrologView prolog = null;
public abstract string GetTypeFunction();
///<summary>
///Пересчёт арности и построение пролог
представления
///</summary>
///<param name="recalc">Пересчитать
арность</param>
/// <returns>true если удалость пересчиать арность</returns>
public abstract bool CalcArityLite(bool recalc =
false);
public virtual string Arity() { if (prolog == null) {
return "No assigned"; } else {
return prolog.Arity.ToString();
}
}
public virtual string FullString() { if (prolog != null)
return prolog.Arity + ToString() + " = "
+ prolog.ToString(); else
return ToString();
}
48
}
public abstract class Function:Base { public RelationList Relation = new
RelationList();
public string Name;
public Function(string Name) { //Конструктор LOGClass.Add(this.GetTypeFunction(),
"Создание новой функции " + Name + " типа " + this.GetTypeFunction());
this.Name = Name;
if (Functions.Exists(p => (p != null) && (p.Name == Name))) {
LOGClass.Add(this.GetTypeFunction(),"Функцию нельзя добавить
всписок " + Name);
}else
Functions.Add(this);
}
public static ListOfFunction Functions = new ListOfFunction();
//Попытка подстановки функции с номером input в другие. Функциям, которые зависят от input посылается команда пересчета арности
public static void Inject(int input) { Function f = input.GetFunction(); LOGClass.Add(f.GetTypeFunction(),
"Подстановка " + f + " в другие функции "); f.Relation.Inject(input);
}
//Статический конструктор - инициализация
констант
static Function() {
LOGClass.Add("Static Function", " Создание
констант ");
49
new Constants("---", new Pair(1, 1), 1, 1);
//0
new Constants("-->", new Pair(1, 0), 1);//1 new Constants("<--", new Pair(0, 1), 1);//2 new Constants(">--", new Pair(2, 1), 1, 1,
1);//3
new Constants("--<", new Pair(1, 2), 1, 1,
1);//4
new Constants("]", new Pair(2, 0), 1, 1);//5 new Constants("[", new Pair(0, 2), 1, 1);//6 new Constants("><", new Pair(2, 2), 1, 2, 2,
1);//7
}
public static implicit operator int(Function i)
{
return Functions.IndexOf(i);
}
public override string ToString() { return Name;
}
public virtual bool AssignArity(Pair Arity) { LOGClass.Add(GetTypeFunction(), "Проверка
арности у " + this);
//Если у функции задана арность if (prolog != null) {
//Если арность определения не совпадает
с арностью функии
return prolog.Arity == Arity; } else {
//Если у функции не задана арность List<int> lstinput = Enumerable.Range(1,
Arity.input).ToList();
List<int> lstoutput = Enumerable.Range(Arity.input + 1,
Arity.output).ToList();
prolog = PrologView.Create(lstinput,
lstoutput,