Реализация сетевой модели вычислений с аксиоматической и рекурсивной формами задания функций и предикатов (бакалаврская работа)
.pdf50
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 } }