// Reads in a domain from a file. public static Domain GetDomain(string file, PlanType type) { bool readInStat = true; int start = 0; // The domain object. Domain domain = new Domain(); // Set the domain's type. domain.Type = type; // Read the domain file into a string. string input = System.IO.File.ReadAllText(file); // Split the input string by space, line feed, character return, and tab. string[] words = input.Split(new char[] { ' ', '\r', '\n', '\t' }); // Remove all empty elements of the word array. words = words.Where(x => !string.IsNullOrEmpty(x)).ToArray(); // Loop through the word array. for (int i = 0; i < words.Length; i++) { // Set the domain name. if (words[i].Equals("(domain")) { start = i - 1; domain.Name = words[i + 1].Remove(words[i + 1].Length - 1); } // Begin types definitions. if (words[i].Equals("(:types")) { // If the list is not empty. if (!words[i + 1].Equals(")")) { // Loop until list is finished. while (words[i][words[i].Length - 1] != ')') { // Create a list for sub-types. List <string> subTypes = new List <string>(); // Read in the sub-types. while (!Regex.Replace(words[++i], @"\t|\n|\r", "").Equals("-")) { subTypes.Add(Regex.Replace(words[i], @"\t|\n|\r", "")); } // Associate sub-types with type in domain object. domain.AddTypeList(subTypes, Regex.Replace(words[++i], @"\t|\n|\r|[()]", "")); } } } // Begin constants definitions. if (words[i].Equals("(:constants")) { // If the list is not empty. if (!words[i + 1].Equals(")")) { // Loop until list is finished. while (words[i][words[i].Length - 1] != ')') { // Create a list for sub-types. List <string> constants = new List <string>(); // Read in the sub-types. while (!Regex.Replace(words[++i], @"\t|\n|\r", "").Equals("-")) { constants.Add(Regex.Replace(words[i], @"\t|\n|\r", "")); } // Associate sub-types with type in domain object. domain.AddConstantsList(constants, Regex.Replace(words[++i], @"\t|\n|\r|[()]", "")); } } } // Begin predicates definitions. if (words[i].Equals("(:predicates")) { // If the list is not empty. if (!words[i + 1].Equals(")")) { // Loop until list is finished. while ((words[i][words[i].Length - 1] != ')' || words[i][words[i].Length - 2] != ')') && (words[i][words[i].Length - 1] != ')' || !words[i + 1].Equals(")"))) { Predicate pred = new Predicate(); pred.Name = Regex.Replace(words[++i], @"\t|\n|\r|[()]", ""); while (words[i][words[i].Length - 1] != ')') { Term term = new Term(); term.Variable = Regex.Replace(words[++i], @"\t|\n|\r|[()]", ""); if (Regex.Replace(words[i + 1], @"\t|\n|\r", "").Equals("-")) { i++; term.Type = Regex.Replace(words[++i], @"\t|\n|\r|[()]", ""); pred.Terms.Add(term); } } domain.Predicates.Add(pred); } } } // Begin an action definition. if (words[i].Equals("(:action")) { if (readInStat) { for (int stat = start; stat < i; stat++) { domain.staticStart += " " + words[stat]; } readInStat = false; } IOperator temp = null; if (type == PlanType.PlanSpace) { // Create an operator object. temp = new Operator(); } else if (type == PlanType.StateSpace) { // Create an action object. temp = new Operator(); } // Name the operator's predicate. temp.Name = Regex.Replace(words[i + 1], @"\t|\n|\r", ""); // Add the operator to the domain object. domain.Operators.Add(temp); } // Fill in an operator's internal information. if (words[i].Equals(":parameters")) { // Add the operator's parameters. while (!Regex.Replace(words[i++], @"\t|\n|\r", "").Equals(":precondition")) { if (words[i][0] == '(' || words[i][0] == '?') { // Create a new term using the variable name. Term term = new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", "")); // Check if the term has a specified type. if (Regex.Replace(words[i + 1], @"\t|\n|\r", "").Equals("-")) { // Iterate the counter past the dash. i++; // Add the type to the term object. term.Type = Regex.Replace(words[++i], @"\t|\n|\r|[()]", ""); } // Add the term to the operator's predicate. domain.Operators.Last().Predicate.Terms.Add(term); } } // Create a list to hold the preconditions. List <IPredicate> preconditions = new List <IPredicate>(); // Create a list to hold nonequality constraints List <List <ITerm> > Nonequalities = new List <List <ITerm> >(); bool lastWasNonEquality = false; // Add the operator's preconditions while (!Regex.Replace(words[i++], @"\t|\n|\r", "").Equals(":effect")) { if (words[i][0] == '(') { if (!words[i].Equals("(and")) { // Create a new precondition object. Predicate pred = new Predicate(); // Check for a negative precondition. if (words[i].Equals("(not")) { // Iterate the counter. i++; // Set the effect's sign to false. pred.Sign = false; } // Set the precondition's name. pred.Name = Regex.Replace(words[i], @"\t|\n|\r|[()]", ""); if (pred.Name.Equals("=")) { if (pred.Sign) { throw new System.Exception(); } // this is a nonequality constraint lastWasNonEquality = true; Nonequalities.Add(new List <ITerm>()); } else { lastWasNonEquality = false; // Add the precondition to the operator. preconditions.Add(pred); } } } else { if (lastWasNonEquality) { if (!Regex.Replace(words[i], @"\t|\n|\r", "").Equals(":effect") && !words[i].Equals(")")) { if (Regex.Replace(words[i], @"\t|\n|\r|[()]", "")[0] == '?') { Nonequalities.Last().Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); } else { Nonequalities.Last().Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""), true)); } } } else { // Add the precondition's terms. if (!Regex.Replace(words[i], @"\t|\n|\r", "").Equals(":effect") && !words[i].Equals(")")) { if (Regex.Replace(words[i], @"\t|\n|\r|[()]", "")[0] == '?') { preconditions.Last().Terms.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); } else { preconditions.Last().Terms.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""), true)); } } } } } // Add the preconditions to the last created operator. domain.Operators.Last().Preconditions = preconditions; domain.Operators.Last().NonEqualities = Nonequalities; // Create a list to hold the effects. List <IPredicate> effects = new List <IPredicate>(); // Add the operator's effects. while (!Regex.Replace(words[i + 1], @"\t|\n|\r", "").Equals("(:action") && !Regex.Replace(words[i], @"\t|\n|\r", "").Equals(":agents") && i < words.Length - 2) { if (words[i][0] == '(') { // Check for a conditional effect. // THIS SHOULD PROBABLY BE CONDENSED if (words[i].Equals("(forall") || words[i].Equals("(when")) { // Create a new axiom object. Axiom axiom = new Axiom(); if (words[i].Equals("(forall")) { // Read in the axiom's terms. while (!Regex.Replace(words[++i], @"\t|\n|\r", "").Equals("(when")) { axiom.Terms.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); } } // If the preconditions are conjunctive. if (Regex.Replace(words[++i], @"\t|\n|\r", "").Equals("(and")) { // Initialize a parentheses stack counter. int parenStack = 1; i++; // Use the stack to loop through the conjunction. while (parenStack > 0) { // Check for an open paren. if (words[i][0] == '(') { // Create new predicate. Predicate pred = new Predicate(); // Check for a negative effect. if (words[i].Equals("(not")) { // Iterate the counter. i++; // Set the effect's sign to false. pred.Sign = false; } // Name the predicate. pred.Name = Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""); // Read in the terms. while (words[i][words[i].Length - 1] != ')') { pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); } // Read the last term. pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); // Add the predicate to the axiom's preconditions. axiom.Preconditions.Add(pred); } // Check for a close paren. if (words[i][words[i].Length - 1] == ')') { parenStack--; } } } else { // Check for an open paren. if (words[i][0] == '(') { // Create new predicate. Predicate pred = new Predicate(); // Check for a negative effect. if (words[i].Equals("(not")) { // Iterate the counter. i++; // Set the effect's sign to false. pred.Sign = false; } // Name the predicate. pred.Name = Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""); // Read in the terms. while (words[i][words[i].Length - 1] != ')') { pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); } // Read the last term. pred.Terms.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); // Add the predicate to the axiom's preconditions. axiom.Preconditions.Add(pred); } } // If the preconditions are conjunctive. if (Regex.Replace(words[++i], @"\t|\n|\r", "").Equals("(and")) { // Initialize a parentheses stack counter. int parenStack = 1; i++; // Use the stack to loop through the conjunction. while (parenStack > 0) { // Check for an open paren. if (words[i][0] == '(') { // Create new predicate. Predicate pred = new Predicate(); parenStack++; // Check for a negative effect. if (words[i].Equals("(not")) { // Iterate the counter. i++; // Set the effect's sign to false. pred.Sign = false; parenStack++; } // Name the predicate. pred.Name = Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""); // Read in the terms. while (words[i][words[i].Length - 1] != ')') { pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); } // Read the last term. pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); // Add the predicate to the axiom's effects. axiom.Effects.Add(pred); } // Check for a close paren. if (words[i - 1][words[i - 1].Length - 1] == ')') { parenStack--; } if (words[i - 1].Length > 1) { if (words[i - 1][words[i - 1].Length - 2] == ')') { parenStack--; } } if (words[i - 1].Length > 2) { if (words[i - 1][words[i - 1].Length - 3] == ')') { parenStack--; } } } } else { // Check for an open paren. if (words[i][0] == '(') { // Create new predicate. Predicate pred = new Predicate(); // Check for a negative effect. if (words[i].Equals("(not")) { // Iterate the counter. i++; // Set the effect's sign to false. pred.Sign = false; } // Name the predicate. pred.Name = Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""); // Read in the terms. while (words[i][words[i].Length - 1] != ')') { pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); } // Read the last term. pred.Terms.Add(new Term(Regex.Replace(words[i++], @"\t|\n|\r|[()]", ""))); // Add the predicate to the axiom's effects. axiom.Effects.Add(pred); } } // Add the axiom to the set of conditional effects. domain.Operators.Last().Conditionals.Add(axiom); } else if (!words[i].Equals("(and")) { // Create a new effect object. Predicate pred = new Predicate(); // Check for a negative effect. if (words[i].Equals("(not")) { // Iterate the counter. i++; // Set the effect's sign to false. pred.Sign = false; } // Set the effect's name. pred.Name = Regex.Replace(words[i], @"\t|\n|\r|[()]", ""); // Add the effect to the operator. effects.Add(pred); } } else { // Add the effect's terms. if (!Regex.Replace(words[i], @"\t|\n|\r", "").Equals("(:action") && !words[i].Equals(")")) { if (Regex.Replace(words[i], @"\t|\n|\r|[()]", "")[0] == '?') { effects.Last().Terms.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); } else { effects.Last().Terms.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""), true)); } } } // Iterate the counter. i++; } // Add the effects to the last created operator. domain.Operators.Last().Effects = effects; // Create a list for storing consenting agents. List <ITerm> consenting = new List <ITerm>(); // Check if the action has any consenting agents. if (Regex.Replace(words[i], @"\t|\n|\r", "").Equals(":agents")) { // If so, iterate through them. while (Regex.Replace(words[++i], @"\t|\n|\r", "")[Regex.Replace(words[i], @"\t|\n|\r", "").Length - 1] != ')') { // And add them to the list. consenting.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); } // Add the final item to the list. consenting.Add(new Term(Regex.Replace(words[i], @"\t|\n|\r|[()]", ""))); } // Add the consenting agents to the action. domain.Operators.Last().ConsentingAgents = consenting; } } // Create a working copy of the domain file. Writer.DomainToPDDL(Parser.GetTopDirectory() + @"Benchmarks\" + domain.Name.ToLower() + @"\domrob.pddl", domain); return(domain); }