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