private void ReadPrivateConstants(CompoundExpression exp, Domain d)
        {
            string        sType = "?", sExp = "";
            List <string> lUndefined = new List <string>();

            for (int iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
            {
                sExp = exp.SubExpressions[iExpression].ToString().Trim();
                if (sExp == "-")
                {
                    sType = exp.SubExpressions[iExpression + 1].ToString();
                    iExpression++;
                    foreach (string sName in lUndefined)
                    {
                        d.AddPrivateConstant(new Constant(sType, sName));
                    }
                    lUndefined.Clear();
                }
                else if (!sExp.StartsWith(":"))
                {
                    lUndefined.Add(sExp);
                }
            }
            if (lUndefined.Count > 0)
            {
                //supporting objects with undefined types as type "OBJ"
                foreach (string sName in lUndefined)
                {
                    d.AddPrivateConstant(new Constant("OBJ", sName));
                }
                //throw new NotImplementedException();
            }
        }
        private void ReadParameters(CompoundExpression exp, ParametrizedAction pa)
        {
            int iExpression = 0;

            //unfortunately, expressions have a weird non standard structure with no type - (?i - pos ?j - pos )
            //so we must have a special case for the first parameter
            if (exp.SubExpressions.Count == 0 || exp.SubExpressions[0].ToString()[0] == '?')//no types
            {
                string sName = exp.Type;
                pa.AddParameter(new Parameter("OBJ", sName));
                for (iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
                {
                    sName = exp.SubExpressions[iExpression].ToString();
                    pa.AddParameter(new Parameter("OBJ", sName));
                }
            }
            else//types for expressions
            {
                string sName = exp.Type, sType = exp.SubExpressions[1].ToString();
                pa.AddParameter(new Parameter(sType, sName));
                for (iExpression = 2; iExpression < exp.SubExpressions.Count; iExpression += 3)
                {
                    sName = exp.SubExpressions[iExpression].ToString();
                    sType = exp.SubExpressions[iExpression + 2].ToString();
                    if (exp.SubExpressions[iExpression + 1].ToString() != "-")
                    {
                        throw new InvalidDataException("Expression " + exp + " has the wrong format");
                    }
                    pa.AddParameter(new Parameter(sType, sName));
                }
            }
        }
        private Formula ReadFormula(CompoundExpression exp, Dictionary <string, string> dParameterNameToType, bool bParamterized, Domain d)
        {
            bool bPredicate = true;

            //Debug.WriteLine(exp);
            if (d != null && d.IsFunctionExpression(exp.Type))
            {
                Predicate p = ReadFunctionExpression(exp, dParameterNameToType, d);
                return(new PredicateFormula(p));
            }
            else if (IsUniversalQuantifier(exp))
            {
                CompoundExpression eParameter = (CompoundExpression)exp.SubExpressions[0];
                CompoundExpression eBody      = (CompoundExpression)exp.SubExpressions[1];
                string             sParameter = eParameter.Type;
                string             sType      = eParameter.SubExpressions[1].ToString();
                dParameterNameToType[sParameter] = sType;
                ParametrizedFormula cfQuantified = new ParametrizedFormula(exp.Type);
                cfQuantified.Parameters[sParameter] = sType;
                Formula fBody = ReadFormula(eBody, dParameterNameToType, true, d);
                cfQuantified.AddOperand(fBody);
                return(cfQuantified);
            }
            else
            {
                foreach (Expression eSub in exp.SubExpressions)
                {
                    if (eSub is CompoundExpression)
                    {
                        bPredicate = false;
                        break;
                    }
                }
                if (bPredicate)
                {
                    return(ReadPredicate(exp, dParameterNameToType, bParamterized, d));
                }
                else
                {
                    CompoundFormula cf          = new CompoundFormula(exp.Type);
                    int             iExpression = 0;
                    for (iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
                    {
                        if (exp.SubExpressions[iExpression] is StringExpression)
                        {
                            throw new InvalidDataException();
                        }
                        Formula f = ReadFormula((CompoundExpression)exp.SubExpressions[iExpression], dParameterNameToType, bParamterized, d);
                        cf.SimpleAddOperand(f);
                    }
                    if (cf.Operator == "not" && cf.Operands[0] is PredicateFormula)
                    {
                        PredicateFormula fNegate = new PredicateFormula(((PredicateFormula)cf.Operands[0]).Predicate.Negate());
                        return(fNegate);
                    }
                    return(cf);
                }
            }
        }
 private void ReadPrivatePredicates(CompoundExpression exp, Domain d)
 {
     foreach (Expression e in exp.SubExpressions)
     {
         CompoundExpression eSub = (CompoundExpression)e;
         Predicate          p    = ReadPredicate(eSub, d);
         d.AddPrivatePredicate(p);
     }
 }
        public ParameterizedFunctionPredicate ReadFunctionExpression(CompoundExpression exp, Dictionary <string, string> dParameterNameToType, Domain d)
        {
            ParameterizedFunctionPredicate pp = new ParameterizedFunctionPredicate(exp.Type);

            foreach (Expression e in exp.SubExpressions)
            {
                pp.AddParameter(ReadFunctionArgument(e, dParameterNameToType, d));
            }
            return(pp);
        }
        public CompoundFormula ParseFormula(string sFile, Domain d)
        {
            string             sPath = sFile.Substring(0, sFile.LastIndexOf(@"\") + 1);
            StreamReader       sr    = new StreamReader(sFile);
            CompoundExpression exp   = (CompoundExpression)ToExpression(sr);

            sr.Close();
            Formula cf = ReadFormula(exp, null, false, d);

            return((CompoundFormula)cf);
        }
 private void ReadFunctions(CompoundExpression eFunctions, Domain d)
 {
     foreach (Expression eSub in eFunctions.SubExpressions)
     {
         if (eSub.ToString() != ":functions")
         {
             if (eSub is CompoundExpression)
             {
                 CompoundExpression eFunction = (CompoundExpression)eSub;
                 //BUGBUG - not validating function parameters
                 d.AddFunction(eFunction.Type);
             }
         }
     }
 }
        private void ReadObserve(CompoundExpression exp, Action pa, Domain d, bool bParametrized)
        {
            string  sOperator = exp.Type;
            Formula f         = null;

            if (pa is ParametrizedAction)
            {
                f = ReadFormula(exp, ((ParametrizedAction)pa).ParameterNameToType, bParametrized, d);
            }
            else
            {
                f = ReadFormula(exp, d.ConstantNameToType, bParametrized, d);
            }
            pa.Observe = f;
        }
        private GroundedPredicate ReadGroundedPredicate(CompoundExpression exp, Domain d)
        {
            GroundedPredicate gp = new GroundedPredicate(exp.Type);
            int      iExpression = 0;
            Constant c           = null;
            string   sName       = "";

            for (iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
            {
                sName = exp.SubExpressions[iExpression].ToString();
                c     = d.GetConstant(sName);
                gp.AddConstant(c);
            }
            return(gp);
        }
        private Action ReadAction(CompoundExpression exp, Domain d)
        {
            string sName       = exp.SubExpressions[0].ToString();
            Action pa          = null;
            int    iExpression = 0;

            for (iExpression = 1; iExpression < exp.SubExpressions.Count; iExpression++)
            {
                if (exp.SubExpressions[iExpression].ToString() == ":parameters")
                {
                    CompoundExpression ceParams = (CompoundExpression)exp.SubExpressions[iExpression + 1];
                    if (ceParams.Type != "N/A")
                    {
                        pa = new ParametrizedAction(sName);
                        ReadParameters((CompoundExpression)exp.SubExpressions[iExpression + 1], (ParametrizedAction)pa);
                    }
                    iExpression++;
                }
                else if (exp.SubExpressions[iExpression].ToString() == ":effect")
                {
                    if (pa == null)
                    {
                        pa = new Action(sName);
                    }
                    ReadEffect((CompoundExpression)exp.SubExpressions[iExpression + 1], pa, d, pa is ParametrizedAction);
                    iExpression++;
                }
                else if (exp.SubExpressions[iExpression].ToString() == ":precondition")
                {
                    if (pa == null)
                    {
                        pa = new Action(sName);
                    }
                    ReadPrecondition((CompoundExpression)exp.SubExpressions[iExpression + 1], pa, d, pa is ParametrizedAction);
                    iExpression++;
                }
                else if (exp.SubExpressions[iExpression].ToString() == ":observe")
                {
                    if (pa == null)
                    {
                        pa = new Action(sName);
                    }
                    ReadObserve((CompoundExpression)exp.SubExpressions[iExpression + 1], pa, d, pa is ParametrizedAction);
                    iExpression++;
                }
            }
            return(pa);
        }
        private Formula ReadPredicate(CompoundExpression exp, Dictionary <string, string> dParameterNameToType, bool bParametrized, Domain d)
        {
            Predicate p           = null;
            int       iExpression = 0;
            string    sName       = "";

            if (bParametrized)
            {
                p = new ParametrizedPredicate(exp.Type);
            }
            else
            {
                p = new GroundedPredicate(exp.Type);
            }
            for (iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
            {
                sName = exp.SubExpressions[iExpression].ToString();
                if (bParametrized)
                {
                    Argument a = null;
                    if (sName.StartsWith("?"))
                    {
                        a = new Parameter(dParameterNameToType[sName], sName);
                    }
                    else
                    {
                        a = new Constant(d.ConstantNameToType[sName], sName);
                    }
                    ((ParametrizedPredicate)p).AddParameter(a);
                }
                else
                {
                    Constant c = new Constant(d.ConstantNameToType[sName], sName);
                    ((GroundedPredicate)p).AddConstant(c);
                }
            }
            if (bParametrized)
            {
                if (!MatchParametersToPredicateDeclaration((ParametrizedPredicate)p, d))
                {
                    throw new NotImplementedException();
                }
            }

            PredicateFormula vf = new PredicateFormula(p);

            return(vf);
        }
 private void ReadPredicates(CompoundExpression exp, Domain d)
 {
     foreach (Expression e in exp.SubExpressions)
     {
         CompoundExpression eSub = (CompoundExpression)e;
         if (eSub.Type == ":private")
         {
             ReadPrivatePredicates(eSub, d);
         }
         else
         {
             Predicate p = ReadPredicate(eSub, d);
             d.AddPublicPredicate(p);
         }
     }
 }
        private Formula ReadGroundedFormula(CompoundExpression exp, Domain d)
        {
            bool bPredicate = true;

            if (IsUniversalQuantifier(exp))
            {
                CompoundExpression          eParameter           = (CompoundExpression)exp.SubExpressions[0];
                CompoundExpression          eBody                = (CompoundExpression)exp.SubExpressions[1];
                string                      sParameter           = eParameter.Type;
                string                      sType                = eParameter.SubExpressions[1].ToString();
                Dictionary <string, string> dParameterNameToType = new Dictionary <string, string>();
                dParameterNameToType[sParameter] = sType;
                ParametrizedFormula cfQuantified = new ParametrizedFormula(exp.Type);
                cfQuantified.Parameters[sParameter] = sType;
                Formula fBody = ReadFormula(eBody, dParameterNameToType, true, d);
                cfQuantified.AddOperand(fBody);
                return(cfQuantified);
            }
            foreach (Expression eSub in exp.SubExpressions)
            {
                if (eSub is CompoundExpression)
                {
                    bPredicate = false;
                    break;
                }
            }
            if (bPredicate)
            {
                return(new PredicateFormula(ReadGroundedPredicate(exp, d)));
            }
            else
            {
                CompoundFormula cf          = new CompoundFormula(exp.Type);
                int             iExpression = 0;
                for (iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
                {
                    Formula f = ReadGroundedFormula((CompoundExpression)exp.SubExpressions[iExpression], d);
                    cf.AddOperand(f);
                }
                if (cf.Operator == "not" && cf.Operands[0] is PredicateFormula)
                {
                    return(new PredicateFormula(((PredicateFormula)cf.Operands[0]).Predicate.Negate()));
                }
                return(cf);
            }
        }
        private Argument ReadFunctionArgument(Expression exp, Dictionary <string, string> dParameterNameToType, Domain d)
        {
            string sName  = exp.ToString();
            double dValue = 0.0;

            if (double.TryParse(sName, out dValue))
            {
                Constant c = new Constant("Number", sName);
                return(c);
            }
            if (exp is CompoundExpression)
            {
                CompoundExpression ce = (CompoundExpression)exp;
                if (!d.Functions.Contains(ce.Type))
                {
                    throw new ArgumentException("Function arguments can only be numbers, parameters, or functions");
                }
                ParameterizedFunctionPredicate fp = new ParameterizedFunctionPredicate(ce.Type);
                foreach (Expression e in ce.SubExpressions)
                {
                    string sParam = e.ToString();
                    if (dParameterNameToType != null && dParameterNameToType.ContainsKey(sParam))
                    {
                        fp.AddParameter(new Parameter(dParameterNameToType[sParam], sParam));
                    }
                    else if (d.ConstantNameToType.ContainsKey(sParam))
                    {
                        fp.AddParameter(new Constant(d.ConstantNameToType[sParam], sParam));
                    }
                    else
                    {
                        throw new ArgumentException("Unknown function parameter");
                    }
                }
                FunctionParameter fa = new FunctionParameter(fp);
                return(fa);
            }
            if (dParameterNameToType.ContainsKey(sName))
            {
                return(new Parameter(dParameterNameToType[sName], sName));
            }
            throw new ArgumentException("Unknown function parameter");
        }
        private Expression ToExpression(Stack <string> sStack)
        {
            string sToken = sStack.Pop();

            if (sToken == "(")
            {
                bool bDone             = false;
                CompoundExpression exp = new CompoundExpression();
                sToken = sStack.Pop();
                if (sToken == ")")
                {
                    exp.Type = "N/A";
                    bDone    = true;
                }
                else
                {
                    exp.Type = sToken;
                }
                while (!bDone)
                {
                    if (sStack.Count == 0)
                    {
                        throw new InvalidDataException("Exp " + exp.Type + " was not closed");
                    }
                    sToken = sStack.Pop();
                    if (sToken == ")")
                    {
                        bDone = true;
                    }
                    else
                    {
                        sStack.Push(sToken);
                        exp.SubExpressions.Add(ToExpression(sStack));
                    }
                }
                return(exp);
            }
            else
            {
                return(new StringExpression(sToken));
            }
        }
        private void ReadInitState(Problem p, Domain d, CompoundExpression eInitState)
        {
            foreach (Expression e in eInitState.SubExpressions)
            {
                CompoundExpression eSub = (CompoundExpression)e;
                if (d.IsFunctionExpression(eSub.Type))
                {
                    p.AddKnown(ReadFunctionExpression(eSub, null, d));
                }
                else if (d.ContainsPredicate(eSub.Type))
                {
                    p.AddKnown(ReadGroundedPredicate(eSub, d));
                }
                else
                {
                    if (eSub.Type != "unknown")
                    {
                        Formula f = ReadGroundedFormula(eSub, d);
                        if (f is CompoundFormula)
                        {
                            p.AddHidden((CompoundFormula)f);
                        }
                        if (f is PredicateFormula)//this happens in (not (p)) statments
                        {
                            p.AddKnown(((PredicateFormula)f).Predicate);
                        }
                    }
                    else
                    {
                        //causing a problem - add operand does some basic reasoning - adding p and ~p results in true for or statements.
                        //skipping unknown for now...

                        Predicate       pUnknown = ReadGroundedPredicate((CompoundExpression)eSub.SubExpressions[0], d);
                        CompoundFormula cfOr     = new CompoundFormula("or");
                        cfOr.SimpleAddOperand(pUnknown);
                        cfOr.SimpleAddOperand(pUnknown.Negate());
                        p.AddHidden(cfOr);
                    }
                }
            }
        }
        private Predicate ReadPredicate(CompoundExpression exp, Domain d)
        {
            ParametrizedPredicate pp            = new ParametrizedPredicate(exp.Type);
            int              iExpression        = 0;
            Parameter        p                  = null;
            string           sName              = "";
            List <Parameter> lUntypedParameters = new List <Parameter>();

            for (iExpression = 0; iExpression < exp.SubExpressions.Count; iExpression++)
            {
                sName = exp.SubExpressions[iExpression].ToString();
                if (sName == "-")
                {
                    string sType = exp.SubExpressions[iExpression + 1].ToString();
                    foreach (Parameter pUntyped in lUntypedParameters)
                    {
                        pUntyped.Type = sType;
                    }
                    lUntypedParameters.Clear();
                    iExpression++;//skip the "-" and the type
                }
                else
                {
                    p = new Parameter("N/A", sName);
                    lUntypedParameters.Add(p);
                    pp.AddParameter(p);
                }
            }
            if (d.Types.Count == 1)
            {
                foreach (Parameter pUntyped in lUntypedParameters)
                {
                    pUntyped.Type = d.Types[0];
                }
            }
            return(pp);
        }
 private void ReadMetric(Problem p, Domain d, CompoundExpression eSub)
 {
     p.AddMetric(eSub.ToString());
 }
        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);
        }
        public Domain ParseDomain(string sDomainFile)
        {
            string       sPath = sDomainFile.Substring(0, sDomainFile.LastIndexOf("/") + 1);
            StreamReader sr    = new StreamReader(sDomainFile);

            /*
             * Stack<string> s = ToStack(new StreamReader(sDomainFile));
             * Stack<string> s2 = ToStackII(new StreamReader(sDomainFile));
             *
             * for (int i = 0; i < s.Count; i++)
             *  if (s.ElementAt(i) != s2.ElementAt(i))
             *      Debug.WriteLine(s.ElementAt(i) + " =/= " + s2.ElementAt(i));
             */


            CompoundExpression exp = (CompoundExpression)ToExpression(sr);

            sr.Close();

            Domain d = null;

            foreach (Expression e in exp.SubExpressions)
            {
                if (e is CompoundExpression)
                {
                    CompoundExpression eSub = (CompoundExpression)e;
                    if (eSub.Type == "domain")
                    {
                        d = new Domain(eSub.SubExpressions.First().ToString(), sPath);
                    }
                    else if (eSub.Type == ":requirements")
                    {
                    }
                    else if (eSub.Type == ":types")
                    {
                        d.Types.Add("object");
                        List <string>      lTypes = new List <string>();
                        CompoundExpression eTypes = ((CompoundExpression)eSub);
                        for (int i = 0; i < eTypes.SubExpressions.Count; i++)
                        {
                            Expression eType = eTypes.SubExpressions[i];
                            string     sType = eType.ToString().Trim();
                            if (sType == "-")
                            {
                                Expression eParentType = eTypes.SubExpressions[i + 1];
                                i++;
                                string sParentType = eParentType.ToString();
                                foreach (string sSubType in lTypes)
                                {
                                    d.TypeHierarchy[sSubType] = sParentType;
                                }
                                lTypes = new List <string>();
                            }
                            else
                            {
                                d.Types.Add(sType);
                                lTypes.Add(sType);
                            }
                        }
                    }
                    else if (eSub.Type == ":constants")
                    {
                        ReadConstants(eSub, d);
                    }
                    else if (eSub.Type == ":functions")
                    {
                        ReadFunctions(eSub, d);
                    }
                    else if (eSub.Type == ":predicates")
                    {
                        ReadPredicates(eSub, d);
                    }
                    else if (eSub.Type == ":action")
                    {
                        d.AddAction(ReadAction(eSub, d));
                    }
                }
            }

            return(d);
        }
 private bool IsUniversalQuantifier(CompoundExpression exp)
 {
     return(exp.Type.ToLower() == "forall" || exp.Type.ToLower() == "exists");
 }