Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Реализация сетевой модели вычислений с аксиоматической и рекурсивной формами задания функций и предикатов (бакалаврская работа)

.pdf
Скачиваний:
6
Добавлен:
28.06.2014
Размер:
704.41 Кб
Скачать

40

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,