public Problem ParseProblem(string sProblemFile, Domain d) { StreamReader sr = new StreamReader(sProblemFile); CompoundExpression exp = (CompoundExpression)ToExpression(sr); sr.Close(); Problem p = null; CompoundExpression eSub = null; foreach (Expression e in exp.SubExpressions) { eSub = (CompoundExpression)e; if (eSub.Type == "problem") { p = new Problem(eSub.SubExpressions.First().ToString(), d); } if (eSub.Type == ":domain") { if (eSub.SubExpressions.First().ToString() != d.Name) { throw new InvalidDataException("Domain and problem files don't match!"); } } if (eSub.Type == ":objects") { ReadConstants(eSub, d); } if (eSub.Type == ":init") { CompoundExpression eAnd = (CompoundExpression)eSub.SubExpressions.First(); if (eAnd.Type == "and") { ReadInitState(p, d, eAnd); } else { ReadInitState(p, d, eSub); } //throw new InvalidDataException("Expecting 'and', got " + eAnd.Type); } if (eSub.Type == ":goal") { ReadGoal(p, d, eSub.SubExpressions[0]); } if (eSub.Type == ":metric") { ReadMetric(p, d, eSub); } } //p.AddReasoningActions(); not needed as long as we use FF to do the planning for us d.ComputeAlwaysKnown(); p.CompleteKnownState(); List <Predicate> lConstantPredicates = new List <Predicate>(); foreach (Predicate pKnown in p.Known) { if (d.AlwaysConstant(pKnown)) { lConstantPredicates.Add(pKnown); } } //Problem here - sometimes ~p and p are both effects (remove p and immediately add it), and the current code forbids that - not sure what to do... //d.RemoveUniversalQuantifiers(lConstantPredicates); //p.RemoveUniversalQuantifiers(); d.ComputePrivateActions(); return(p); }