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

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

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

60

);

}

public static Constructor Create(string SArity, string Name) {

LOGClass.Add("Static Constructor" ,"Создание конструктора из " + SArity + Name);

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 Arity = new Pair(input, output);

int result = Functions.FindIndex(p => (p != null) && (p.Name == Name)); if(result == -1) { //Если функции не было

LOGClass.Add("Static Constructor","Конструктор " + Arity + Name + " ещё не упомянался ");

Constructor c = new Constructor(Name, Arity); //Создадим её

return c; } else {

LOGClass.Add("Static Constructor", "Конструктор " + Arity + Name + " уже упомянался ");

bool usl = (Functions[result] is UserFunction) && ((Functions[result] as UserFunction).definition.Count > 0);

if (!(Functions[result] is

UserFunction))

usl = true; if((Functions[result].prolog == null) &&

!usl) {

61

Constructor c = new Constructor(Name, Arity); //Создадим её

c.Relation = Functions[result].Relation;

Functions[result] = c; Inject(result); return c;

} else {

throw new Exception("Функция " + result.GetFunction() + " уже определена");

}

}

}

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

}

}

5. Класс для графического представления public class PrologView {

public List<Def> relations = new List<Def>(); int[] input = null;

int[] output = null; string str;

List<Word> words = new List<Word>(); //Список всевозможных букв

List<FuncGraphPoint> functions = new List<FuncGraphPoint>(); //Список всевозможных функций

PrologView() {

}

public PrologView(IEnumerable<int> input, IEnumerable<int> output) {

this.input = input.ToArray(); this.output = output.ToArray();

62

str = "{";

if (this.input.Length > 0) str += input.Select(p =>

p.ToChar().ToString()).Aggregate((x, y) => x + ", " + y); if (this.output.Length > 0) {

str += ":";

str += output.Select(p => p.ToChar().ToString()).Aggregate((x, y) => x + ", " + y);

}

str += "}";

}

PrologView(PrologView p1) { this.input = p1.input.ToArray();

this.output = p1.output.ToArray(); foreach( Def f in p1.relations) {

this.relations.Add(new Def(f));

}

}

void AddFunction(List<int> paraminput, List<int> paramout, Def def) {;// param) {//, string param = null) {

FuncGraphPoint New = new FuncGraphPoint() {

def = def };

functions.Add(New);

for (int j = 0; j < paraminput.Count; j++) { Word w = words.FirstOrDefault(p =>

p.name == paraminput[j]);

if (w == null) {

w = new Word() { name =

paraminput[j] };

words.Add(w);

}

w.input.Add(New);

New.child.Add(w);

}

for (int j = 0; j < paramout.Count; j++) { Word w = words.FirstOrDefault(p =>

p.name == paramout[j]);

63

if (w == null) {

w = new Word() { name = paramout[j]

};

words.Add(w);

}

w.output.Add(New);

New.parent.Add(w);

}

}

void AgregateFunction() {

foreach (Word word in words) { if (word.output.Count == 1) {

if (word.input.Count == 1) { if (word.input[0] !=

word.output[0]) {

if (word.output[0].parent.Count == 1) {

int ind =

word.input[0].child.IndexOf(word);

word.output[0].parent.Clear();

word.input[0].child[ind]

= word.output[0];

functions.Remove(word.output[0]);

}

}

} else if (word.input.Count == 0) { word.name = 0;

}

} else if (word.output.Count == 2) { if (word.input.Count == 0) {

if (word.output[0].parent.Count

== 1) {

int ind = word.output[1].parent.IndexOf(word);

word.output[1].parent[ind] =

word.output[0];

word.output[0].parent.Clear();

64

functions.Remove(word.output[0]);

} else if (word.output[1].parent.Count == 1) {

int ind = word.output[0].parent.IndexOf(word);

word.output[0].parent[ind] =

word.output[1];

word.output[1].parent.Clear();

functions.Remove(word.output[1]);

}

}

} else if (word.output.Count + word.input.Count <= 1) {

word.name = 0;

}

}

functions = functions.Where<FuncGraphPoint>(p => {

if(p.def == null) return true;

if(p.def.name is Constructor) { if (p.parent.Count == 0)

return true;

if (p.parent.All(q => q is Word)) { List<Word> tmp =

p.parent.Cast<Word>().ToList();

if (tmp.All(q => q.name == 0)) { return false;

} else {

return true;

}

} else {

return true;

}

} else {

return true;

65

}

}).ToList();

}

void CreateString() {

List<Graph> input = functions[0].child; List<Graph> output = functions[1].child; functions = functions.Skip(2).ToList(); str = "{";

if (input.Count > 0)

str += input.Select(p => p.ToString()).Aggregate((x, y) => x + ", " + y);

if (output.Count > 0) { str += ":";

str += output.Select(p => p.ToString()).Aggregate((x, y) => x + ", " + y);

}

if (functions.Count > 0) { str += "?";

str += functions.Select(p => p.ToString()).Aggregate((x, y) => x + ", " + y);

}

str += "}";

}

void CheckOneConstructor() {

relations = relations.Distinct().ToList(); if(relations.Count == 0)

return; IEnumerable<IGrouping<string, Def>> lst =

relations.Where(p => p.name is Constructor).GroupBy<Def, string>(p => p.name.Name);

Inversion inv = new Inversion();

foreach (IGrouping<string, Def> ind1 in lst)

{

//Внутри одного конструктора List<Def> ind = ind1.ToList();

for (int i = 0; i < ind.Count(); i++) {

66

for (int j = i + 1; j < ind.Count();

j++) {

if (RelationFunction.Equals(ind[i].input, ind[j].input))

for (int k = 0; k <

ind[i].output.Count; k++)

inv.Add(new Pair(ind[j].output[k], ind[i].output[k]));

if (RelationFunction.Equals(ind[i].output, ind[j].output))

for (int k = 0; k <

ind[i].input.Count; k++)

inv.Add(new

Pair(ind[j].input[k], ind[i].input[k]));

}

}

}

if (inv.Return().Count != 0) Inverse(inv.Return());

}

bool CheckManyConstructors() {

relations = relations.Distinct().ToList(); if (relations.Count == 0)

return true; IEnumerable<IGrouping<string, Def>> lst =

relations.Where(p => p.name is Constructor).GroupBy<Def, string>(p => p.name.Name);

if (lst.Count() <= 1) return true;

foreach (IGrouping<string, Def> group in

lst) {

List<Def> temp = lst.Where(j => j.Key != group.Key).Select(q => q as IEnumerable<Def>).Aggregate((x, y) => x.Concat(y)).ToList();

foreach( Def def in group)

for (int k = 0; k < temp.Count; k++) if

(RelationFunction.Equals(def.output, temp[k].output)) return false;

}

67

return true;

}

bool Check() { CheckOneConstructor();

return CheckManyConstructors();

}

public Pair Arity { get {

return new Pair(input.Length,

output.Length);

}

}

public override string ToString() { return str;

}

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

}

static List<int> CreateListOfWord(PrologView

op1) {

IEnumerable<int> lockedWord; if (op1.relations.Count > 0)

lockedWord = op1.relations.Select(p => p.input.Union(p.output)).Aggregate((x, y) => x.Union(y));

else

lockedWord = new List<int>(); lockedWord =

lockedWord.Union(op1.input).Union(op1.output); lockedWord = lockedWord.Distinct(); return lockedWord.ToList();

}

void Inverse(List<Pair> inv) {

68

Func<int, int> lol = i => {

Pair inve = inv.FirstOrDefault(p =>

p.input == i);

return inve == null ? i : inve.output;

};

relations = relations.Select<Def, Def>(d =>

{

Def New = new Def(); New.name = d.name; New.input =

d.input.Select(lol).ToList(); New.output =

d.output.Select(lol).ToList(); return New;

}).ToList();

input = input.Select(lol).ToArray(); output = output.Select(lol).ToArray();

}

public static PrologView operator +(PrologView op1, PrologView op2) {

if (op1 == null) return null; if (op2 == null) return null;

List<int> lockedWord = CreateListOfWord(op1);

List<Pair> inv = new List<Pair>(); foreach (int i in CreateListOfWord(op2))

inv.Add(new Pair(i, lockedWord.GetFree()));

op2.Inverse(inv); IEnumerable<int> input =

op1.input.Concat(op2.input); IEnumerable<int> output =

op1.output.Concat(op2.output); List<Def> defs =

op1.relations.Concat(op2.relations).ToList();

69

return PrologView.Create(input, output,

defs);

}

public static PrologView operator * (PrologView op1, PrologView op2) {

if (op1 == null) return null; if (op2 == null) return null;

if (op1.Arity.output != op2.Arity.input) throw new Exception("Арности не

совпадают " + op1 + "*" + op2 ); List<int> lockedWord =

CreateListOfWord(op1);

List<Pair> invop2 = new List<Pair>(); foreach (int i in CreateListOfWord(op2))

invop2.Add(new Pair(i, lockedWord.GetFree()));

//Составлен список замен if (invop2.Count > 0)

op2.Inverse(invop2);

//На этом этапе переменные у op2 и op1 не

пересекаются.

Inversion inv = new Inversion(); //Далее надо делать замены

for (int i = 0; i < op1.output.Length; i++) if (inv.Return().Exists(p => p.input ==

op2.input[i]))

inv.Add(new Pair(op1.output[i],

op2.input[i]));

else

inv.Add(new Pair(op2.input[i],

op1.output[i]));

inv.Check(); if(inv.Return().Count > 0) {

op2.Inverse(inv.Return());

op1.Inverse(inv.Return());

}

IEnumerable<int> input = op1.input;