Страницы

Поиск по вопросам

воскресенье, 16 июня 2019 г.

Не могли бы Вы помочь осознать, в чем у меня ошибка в коде на языке Prolog?

Не могли бы Вы помочь осознать, в чем у меня ошибка в коде? Очень нужно разобраться..
Задача: Описать на Прологе базу знаний, содержащую следующую информацию: Факты:
Алексей – сын Юрия, Юрий – сын Ивана, Сергей – сын Ивана, Александр – сын Ивана, Павел – сын Сергея.
Правила:
X является отцом Y, если Y – сын X X является братом Y, если это два разных человека, но оба являются сыновьями одного и того же человека X является дядей Y, если отцом Y является Z, а X и Z – братья X является дедушкой Y, если X – отец Z, а Z – отец Y
Сформулировать цели и ответить на следующие вопросы:
Вывести список братьев Сергея Как зовут дедушку Павла? Кем приходится Сергей Алексею?

predicates nondeterm son(string,string) /*who, whose*/ nondeterm father(string,string) /*who, whose*/ nondeterm brother(string,string) /*who, whose*/ nondeterm uncle(string,string) /*(who, whose*/ nondeterm grandfather(string,string) /*who, whose*/ clauses %Facts son(aleksej,yurij). son(yurij,ivan). son(sergej,ivan). son(alexandr,ivan). son(pavel,sergej). %Rules father(X,Y):-son(Y,X). brother(X,Y):-X<>Y,father(Z,X),father(Z,Y). uncle(X,Y):-father(Z,Y), brother(X,Z),brother(Z,X). grandfather(X,Y):-father(X,Z),father(Z,Y). goal brother(X,sergej). grandfather(X,pavel). X(sergej,aleksej).
Вроде бы всё логично, должно скомпилироваться и выдать результат, но почему-то выдает ошибки.. Не понимаю, что не так..


Ответ

Сразу стоит заметить, что здесь решать задачи за вас не будут. Теперь по сути. Очевидно, что у вас нет предиката X(Y,Z), который бы приводил в соответствие каждой ситуации родства слово кем является Y для Z.
Пример такого предиката:
Who(Y,Z,X):-brother(Y,Z), X="brother", Who(Y,Z,X):-father(Y,Z), X="father", ...
И так описать все возможные ситуации для этого предиката, не забыть и про племянников и внуков. Разумеется, код может быть не рабочим, так как для Prolog уйма различных вариаций интерпретаторов языка.
Но идея общая дана.
P.S. В том интерпретаторе с которым работал я должен был быть только один goal, не уверен насчёт вашего.

Можно ли каким-то образом оптимизировать вот такой парсинг XML?

Два класса для запоминания разобранного:
class Answer { public int Index { get; set; } public bool Correct { get; set; } public string Desc { get; set; } }
class Question { public int Id { get; set; } public string Content { get; set; } public string MainQuestion { get; set; } public int MainQuestionContent { get; set; } public List Answers { get; set; } = new List(); }
Далее сам XML и его парсинг:
static void Main(string[] args) { string xml = @" Вопрос 1 Ответ 1 Ответ 2 Ответ 3 ";
XElement elements = XElement.Parse(xml);
List questionsList = new List(); Question itemQuestion; Answer itemAnswer;
foreach (XElement question in elements.Element("questions").Elements("question")) { itemQuestion = new Question();
itemQuestion.Id = Convert.ToInt32(question.Attribute("id")?.Value); itemQuestion.Content = question.Attribute("content")?.Value; itemQuestion.MainQuestion = question.Element("main_question")?.Value; itemQuestion.MainQuestionContent = Convert.ToInt32(question.Element("main_question")?.Attribute("content")?.Value);
var answers = from a in question.Elements("answer") select new { AttributeIndex = a.Attribute("index")?.Value, AttributeCorrect = a.Attribute("correct")?.Value, Answer = a?.Value };
if (answers.Any()) { foreach (var item in answers) { itemAnswer = new Answer();
itemAnswer.Index = Convert.ToInt32(item.AttributeIndex); itemAnswer.Correct = Convert.ToBoolean(item.AttributeCorrect); itemAnswer.Desc = item.Answer;
itemQuestion.Answers.Add(itemAnswer); } }
questionsList.Add(itemQuestion);
} }
Хотелось бы foreach (XElement question in elements.Element("questions").Elements("question")) превратить в запрос LINQ, только я не могу сообразить как.
Благодаря подсказке @Grundy получилось оптимизировать так:
List questionsList = (from question in elements.Element("questions").Elements("question") select new Question() { Id = Convert.ToInt32(question.Attribute("id")?.Value), Content = question.Attribute("content")?.Value, MainQuestion = question.Element("main_question")?.Value, MainQuestionContent = Convert.ToInt32(question.Element("main_question")?.Attribute("content")?.Value), Answers = (from a in question.Elements("answer") select new Answer { Index = Convert.ToInt32(a.Attribute("index")?.Value), Correct = Convert.ToBoolean(a.Attribute("correct")?.Value), Desc = a?.Value
}).ToList() }).ToList();


Ответ

По сути, код эквивалентен обычному select
Например такому:
List questionsList = (from question in elements.Element("questions").Elements("question") select new Question(){ Id = Convert.ToInt32(question.Attribute("id")?.Value), ... Answers = (from a in question.Elements("answer") select new Answer { Index = Convert.ToInt32(a.Attribute("index")?.Value), ... }).ToList() }).ToList();