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

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

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

70

IEnumerable<int> output = op2.output; List<Def> defs =

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

return PrologView.Create(input, output,

defs);

}

public static PrologView Create(IEnumerable<int> input, IEnumerable<int> output, List<Def> defs){

PrologView result = new PrologView(); result.input = input.ToArray(); result.output = output.ToArray(); result.relations = defs;

if (!result.Check()) return null;

result.AddFunction(result.input.ToList(), new List<int>(), null);//"$input");

result.AddFunction(result.output.ToList(), new List<int>(), null);// "$output");

foreach (Def def in result.relations) { result.AddFunction(def.input,

def.output, def);

}

result.AgregateFunction();

result.CreateString(); return result;

}

public static PrologView Inject(PrologView p1, int ind, PrologView inj) {

if (p1 == null) return null; if (inj == null) return null;

if (ind < 0) return null;

if (ind >= p1.relations.Count) return null;

Def relat = p1.relations[ind]; if (relat.Arity != inj.Arity)

71

return null; LOGClass.Add("PrologView", "Подстановка в "

+ p1 + " функции " + inj);

PrologView op1 = new PrologView(p1); PrologView op2 = new PrologView(inj); op1.relations.Remove(relat);

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 < relat.input.Count; i++) if (inv.Return().Exists(p => p.input ==

op2.input[i]))

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

op2.input[i]));

else

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

relat.input[i]));

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

op2.output[i]))

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

op2.output[i]));

else

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

relat.output[i]));

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

op2.Inverse(inv.Return());

op1.Inverse(inv.Return());

}

72

IEnumerable<int> input = op1.input; IEnumerable<int> output = op1.output; List<Def> defs =

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

return PrologView.Create(input, output,

defs);

}

6. Создание списка зависимостей из списка лексем class PrologWiewCreator {

class WordNumer { class Pair {

public string s; public Word w;

}

List<Pair> words = new List<Pair>();

///<summary>

///Функция возвращает первый свободный

номер

///</summary>

///<returns></returns> int GetNum() {

List<int> temp = words.Select(p =>

p.w.name).ToList();

int i = 1;

while (temp.Exists(p => p == i)) i++;

return i;

}

public Word New() {

Pair result = new Pair() { w = new Word() { name = GetNum() } };

words.Add(result); return result.w;

}

public Word Add(string s) {

73

Pair result = words.FirstOrDefault(p =>

p.s == s);

if (result == null) {

result = new Pair() { s = s, w = new Word() { name = GetNum() } };

words.Add(result);

}

return result.w;

}

public Word Get(Func<string, bool>

predicate) {

Pair p = words.FirstOrDefault(q =>

predicate(q.s));

if (p == null) return null;

else

return p.w;

}

}

WordNumer words = new WordNumer(); List<FuncGraph> relations = new

List<FuncGraph>();

List<Graph> npt = new List<Graph>(); List<Graph> otpt = new List<Graph>();

void Check(List<Graph> npt) {

for (int i = 0; i < npt.Count; i++) { if (npt[i] is FuncGraph) {

relations.Add(npt[i] as FuncGraph); Word w = words.New();

(npt[i] as FuncGraph).parent.Add(w); npt[i] = w;

}

}

}

74

List<Graph> CreateInput(List<string[]> token) { List<Graph> result = new List<Graph>(); List<string[]> forin = new List<string[]>(); int num = 0;

foreach (string[] lst in token) {

if (lst[0] == "$ПрологФункция") { if (num > 0) {

forin.Add(lst);

}

num++;

} else if (lst[0] == "$КонецПрологФункции") {

num--;

if (num == 0) {

FuncGraph New = new FuncGraph()

{ name = forin[0][1] };

New.child = CreateInput(forin.Skip(1).ToList());

result.Add(New);

forin.Clear(); } else {

forin.Add(lst);

}

} else {

if (num > 0) { forin.Add(lst);

} else {

if (lst[0] == "$Переменная") { Word word = words.Get(p => p

== lst[1]);

if (word == null) word =

words.Add(lst[1]);

//word.input.Add(result);

result.Add(word);

}

}

75

}

}

return result;

}

///<summary>

///Составление предиката(без возвр

значения) по списку лексем

///</summary>

///<param name="token">Список лексем</param>

///<returns>Граф функция</returns> FuncGraph CreateOneRelation(List<string[]>

token) {

int i = 0;

List<string[]> left = null; List<string[]> right = null;

if (token[i][0] == "$ЛеваяЧасть") { left = CreateList(token, ref i);

}

if (token[i][0] == "$ПраваяЧасть") { right = CreateList(token, ref i);

}

if (right == null)

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

правой части");

if (right.Count < 2)

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

правой части");

FuncGraph R = null;

if (right[0][0] == "$ПрологФункция") { if (right[1][0] == "$Имя") {

string Name = right[1][1]; right = right.Skip(2).ToList();

R = new FuncGraph() { name = Name }; (R as FuncGraph).child =

CreateInput(right);

} else {

76

throw new Exception("Ожидается

имя");

}

} else {

throw new Exception("Ожидается правая

часть оперделения");

}

if (R == null)

throw new Exception("Ошибка распозначания праой части опредеолния");

if (left != null) {

if (left.Count == 0)

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

левой части");

R.parent = CreateInput(left);

}

return R;

}

void CreateStructure(List<string[]> token) { int i = 0;

if (token[i][0] == "$ПрологВходы") { List<string[]> listInput =

CreateList(token, ref i);

npt = CreateInput(listInput);

}

if (token[i][0] == "$ПрологВыходы") { List<string[]> listOutput =

CreateList(token, ref i);

otpt = CreateInput(listOutput);

}

if (token[i][0] == "$ПрологОграничения") { if (i >= token.Count) return;// result; List<string[]> temp = new

List<string[]>();

for(i+=1; i < token.Count; i++) { if (token[i][0] ==

"$ПрологОграничение") {

if (temp.Count > 0)

77

relations.Add(CreateOneRelation(temp));

temp.Clear(); } else {

temp.Add(token[i]);

}

}

if (temp.Count > 0) {

relations.Add(CreateOneRelation(temp));

}

}

}

public PrologView CreatePrologView(UserFunction name, List<string[]> token) {

CreateStructure(token);

//На этот момент уже потеряли имена

переменных

Check(npt);

Check(otpt);

for (int i = 0; i < relations.Count; i++) { FuncGraph relat = relations[i]; Check(relat.child); Check(relat.parent);

}

//На этот момент уже нет вложений

List<Def> defs = relations.Select<FuncGraph,

Def>(p => {

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

p.child.Cast<Word>().Select(q => q.name).ToList(); New.output =

p.parent.Cast<Word>().Select(q => q.name).ToList();

int ind = Function.Functions.FindIndex(q => q.Name == p.name);

Pair Arity = new Pair(p.child.Count,

p.parent.Count);

Function f;

78

if (ind == -1) {

//Если такой функции нет, то её надо

создать.

f= new UserFunction(p.name);

}else {

f= ind.GetFunction();

}

//Если такая функция есть, то надо попытаться проверить арность.

if (f.AssignArity(new Pair(New.input.Count, New.output.Count))) {

New.name = f; } else {

return new Def();

}

return New; }).ToList();

if (defs.Exists(p => p == default(Def)))

return null;

PrologView result = PrologView.Create( npt.Cast<Word>().Select(p => p.name), otpt.Cast<Word>().Select(p => p.name), defs

);

return result;

}

static List<string[]> CreateList(List<string[]> token, ref int i) {

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

for (i++; i < token.Count; i++) switch (token[i][0]) {

case "$ПрологФункция": case "$Параметр":

case "$Переменная": case "$Имя":

case "$Рекурсия":

79

case "$КонецПрологФункции": result.Add(token[i]); break;

default:

goto LabelInputOk;

}

LabelInputOk: return result;

}

}

7. Класс для работы со списком замен class Inversion {

List<Pair> defs = new List<Pair>();

bool check() {

List<Pair> bk = defs; defs = new List<Pair>(); bool result = false;

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

for (int j = 0; j < defs.Count; j++) { if (defs[j].output == bk[i].input) {

defs[j].output = bk[i].output; result = true;

}

}

defs.Add(bk[i]);

}

defs = defs.Where(p => p.input != p.output).ToList();

defs = defs.Distinct().ToList(); return result;

}

public void Add(Pair def) { defs.Add(def); Check();

}