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

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

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

50

new List<Def>() { new Def() { name = this,

input = lstinput, output = lstoutput } }

);

LOGClass.Add(GetTypeFunction(), "Задание арности " + prolog.Arity + " для " + this);

Inject(this);

//Пытаемся подставить эту функцию в

другие

}

return true;

}

public override bool CalcArityLite(bool recalc =

false) {

return true;

}

public override string GetTypeFunction() { return "Function";

}

}

//Класс для пользовательской функции public class UserFunction:Function {

public List<Definition> definition = new List<Definition>();

//Определения функции

public UserFunction(string Name) : base(Name) { //Конструктор

}

public bool AssignArity(Base def) { return AssignArity(def.prolog.Arity);

}

51

///<summary>

///Пересчитать арность функци

///</summary>

public override bool CalcArityLite(bool recalc =

false) {

LOGClass.Add(GetTypeFunction(),"Пересчет арности для " + Name);

definition = definition.Select(p => { if (p.Type == Definition.TType.Tree)

if (p.Tree.CalcArityLite())

//ВЫчисляем его.

if (p.Tree.prolog != null)

if (AssignArity(p.Tree)) {

p.Upgrade(p.Tree.prolog);

return p;// new

Definition(p.Tree.prolog);

} else

throw new

Exception("Арности не совпадают"); else

return null;

else

return p;

else

return p;

}).Where(p => p != null).ToList(); return true;

}

public override string GetTypeFunction()

{

return "UserFunction";

}

public static UserFunction CreateFunction(string Name, List<string[]> lst, string SArity = null) {

Function maintmp = UserFunction.Functions.Where(p => (p != null) &&

(p.Name == Name)).FirstOrDefault();

52

UserFunction main;

if (maintmp == null) { //Если функции не

было

LOGClass.Add("Saver", "Определяется новая функция " + Name);

main = new UserFunction(Name);

//Создадим её

} else {

if (maintmp is UserFunction) { main = maintmp as UserFunction; LOGClass.Add("Saver", "Найдена

функция с именем " + Name); } else

throw new Exception("C именем " + Name + " объявлен конструктор " + maintmp.prolog.ToString());

}

//В main лежит определяемая функция if (SArity != null) {

string[] arr = SArity.Split(')', '(', ':'); //Отделяем имя от определения

arr = arr.Where(p => p != "").ToArray(); if (arr.Length != 2)

throw new Exception("Ошибка парсинга

" + SArity);

int input = Convert.ToInt16(arr[0]); int output = Convert.ToInt16(arr[1]);

Pair inArity = new Pair(input, output); if (!main.AssignArity(inArity))

throw new Exception("Арности не

совпадают");

}

LOGClass.Add("Saver", "Создание дерева из списка лексем ");

TypeTree defin = CreateOperand(main, lst); //Определеие по списку токенов

53

LOGClass.Add("Saver", "Дерево создано: " +

defin);

LOGClass.Add("Saver", "Попытка создания Prolog представления: ");

if (defin == null) {

LOGClass.Add("Saver", "Дерево " + defin + " редуцировалось к пустому");

} else if (defin.Type == TypeTree.TType.Tree) {

if (defin.Tree.prolog != null) { LOGClass.Add("Saver", "Создано

prolog представление " + defin.Tree.prolog);

if (main.AssignArity(defin.Tree)) { Definition d = new

Definition(defin.Tree);

d.Upgrade(defin.Tree.prolog);

main.definition.Add(d); } else

throw new Exception("Арности не

совпадают");

} else {

LOGClass.Add("Saver", "Не все зависимые функции определены");

main.definition.Add(new

Definition(defin.Tree));

List<int> relat = defin.Tree.GetRelation();

foreach (int pt in relat) {

Function.Functions[pt].Relation.Add(main);

}

}

} else {

if (defin.prolog != null) main.definition.Add(new

Definition(defin.Prolog));

}

return main;

}

public static UserFunction CreateProlog(string Name, List<string[]> lst, string SArity = null) {

54

Function maintmp = UserFunction.Functions.Where(p => (p != null) &&

(p.Name ==

Name)).FirstOrDefault(); UserFunction main;

if (maintmp == null) { //Если функции не

было

LOGClass.Add("Saver", "Определяется новая функция " + Name);

main = new UserFunction(Name);

//Создадим её

} else {

if (maintmp is UserFunction) { main = maintmp as UserFunction; LOGClass.Add("Saver", "Найдена

функция с именем " + Name); } else

throw new Exception("C именем " + Name + " объявлен конструктор " + maintmp.prolog);

}

//В main лежит определяемая функция if (SArity != null) {

string[] arr = SArity.Split(')', '(', ':'); //Отделяем имя от определения

arr = arr.Where(p => p != "").ToArray(); if (arr.Length != 2)

throw new Exception("Ошибка парсинга

" + SArity);

int input = Convert.ToInt16(arr[0]); int output = Convert.ToInt16(arr[1]);

Pair inArity = new Pair(input, output); if

(!main.AssignArity(inArity))

throw new Exception("Арности не

совпадают");

}

LOGClass.Add("Saver", "Создание пролог представления из списка лексем ");

55

PrologWiewCreator pc = new PrologWiewCreator();

PrologView defin = pc.CreatePrologView(main,

lst);

//Определеие по списку токенов if (defin != null) {

LOGClass.Add("Saver", "Создано prolog представление " + defin);

if (main.AssignArity(defin.Arity)) main.definition.Add(new

Definition(defin));

else

throw new Exception("Арности не

совпадают");

} else

LOGClass.Add("Saver", "Представление " + defin + " редуцировалось к пустому");

return main;

}

static List<List<string[]>> TokenListToStruct(List<string[]> lst) {

List<List<string[]>> result = new List<List<string[]>>();

int countInt = 0;

for (int i = 0; i < lst.Count; i++) { if (lst[i][0] == "$Константа") {

if (countInt == 0)

result.Add(new List<string[]>()

{ lst[i] });

else

result.Last().Add(lst[i]); } else if (lst[i][0] == "$Имя") {

if (countInt == 0)

result.Add(new List<string[]>()

{ lst[i] });

else

result.Last().Add(lst[i]);

} else if (lst[i][0] == "$Рекурсия") { if (countInt == 0)

56

result.Add(new List<string[]>()

{ lst[i] });

else

result.Last().Add(lst[i]);

} else if (lst[i][0] == "$Операция") { if (countInt == 0)

result.Add(new List<string[]>()

{ lst[i] });

else

result.Last().Add(lst[i]); } else if (lst[i][0] ==

"$НачалоВСкобках") {

if (countInt == 0) result.Add(new

List<string[]>());

else

result.Last().Add(lst[i]); countInt++;

} else if (lst[i][0] ==

"$КонецВСкобках") {

countInt--; } else {

throw new NotImplementedException();

}

}

return result;

}

static TypeTree CreateOperand(UserFunction name, List<string[]> token) {

List<List<string[]>> lst = TokenListToStruct(token);

if (lst.Count == 1) { //Если всего 1 лексема, то она опреанд

if (lst[0].Count == 1) { Function f = null;

if (lst[0][0][0] == "$Константа") { f =

UserFunction.Functions.Where(p => (p != null) &&

57

(p.Name == lst[0][0][1])).FirstOrDefault();

} else if (lst[0][0][0] == "$Имя") { f =

UserFunction.Functions.Where(p => (p != null) && (p.Name ==

lst[0][0][1])).FirstOrDefault();

if (f == null) { f = new

UserFunction(lst[0][0][1]);

}

} else if (lst[0][0][0] ==

"$Рекурсия") {

f = name; } else {

throw new Exception("Error

type");

}

return f; } else {

return CreateOperand(name, lst[0]);

}

} else {

return TokenList_to_Tree(name, lst);

}

}

static TypeTree TokenList_to_Tree(UserFunction name, List<List<string[]>> token) {

string stat = ""; TypeTree operandl = null; TypeTree operandr = null; if (token.Count > 1) {

operandl = CreateOperand(name,

token[0]);

if (operandl == null) return null;

} else if (token.Count == 1) {

return CreateOperand(name, token[0]); } else {

throw new NotImplementedException();

58

}

for (int i = 1; i < token.Count; i++) { // Преобразуем список операндов в список

деревьев

if (i % 2 == 0) {

operandr = CreateOperand(name,

token[i]);

if (operandr == null) return null;

if (stat == "*") {

if ((operandl.Type ==

TypeTree.TType.Tree) &&

(operandl.Tree is LinearTree)) {

operandl.Tree.operands.Add(operandr); } else {

operandl = new

LinearTree(operandl, operandr);

}

} else if (stat == "#") { if ((operandl.Type ==

TypeTree.TType.Tree) &&

(operandl.Tree is ParallelTree)) {

operandl.Tree.operands.Add(operandr); } else {

operandl = new ParallelTree(operandl, operandr);

}

} else { throw new

Exception("Неопределнная лексема " + stat);

}

if (operandl.CalcArityLite(true)) { if (operandl.Tree.prolog ==

null) {

//Дерево редуцировалось к

пустому

return null;

59

}

}

} else { //Если вх лексема - опреатор if (token[i][0][0] != "$Операция") throw new Exception("Error");

stat = token[i][0][1];

}

}

//На этом этапе в памяти 1 опреанд. return operandl;

}

}

public class Constants:Function {

public Constants(string Name, Pair Arity, params int[] lst) : base(Name) {

prolog = new PrologView(lst.Take(Arity.input), lst.Skip(Arity.input));

}

public override string GetTypeFunction() { return "Constant";

}

}

class Constructor: Function { Constructor(string Name, Pair Arity) :

base(Name) {

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,

new List<Def>() { new Def() { name = this,

input = lstinput, output = lstoutput } }