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