Exercise 30 Solution

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Services;
using Microsoft.Web.Services3.Messaging;
using Plato;
using Plato.Derivation;
using Plato.Derivation.Parser;
using Plato.Core;
using Plato.Derivation.Solve;
using Plato.Language.Parser;
using Grace.VoiceCommands;
using log4net;

namespace Grace
{
    class GraceService : SoapService
    {
        private static ILog log = LogManager.GetLogger(typeof(GraceService));

        public static PlatoInstance Plato { get; set; }

        /// <summary>
        /// Get the list of food items currently on the grocery list.
        /// </summary>
        /// <returns>The list of food items.</returns>
        [SoapMethod("GetGroceryList")]
        public string[] GetGroceryList()
        {
            log.Info("GetGroceryList()");

            IList<IEntity> entities = SolveQuery("$x: our_family needs_grocery_item $x");

            List<string> list = new List<string>();
            foreach (IEntity entity in entities)
            {
                list.Add(entity.Id);
            }

            return list.ToArray();
        }

        /// <summary>
        /// Add an item to the grocery list.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns>An error string if applicable.</returns>
        [SoapMethod("AddGroceryItem")]
        public string AddGroceryItem(string item)
        {
            log.Info("AddGroceryItem(" + item + ")");

            try
            {
                IEntity entity1 = Plato.Brain.Get("our_family");
                IEntity relation = Plato.Brain.Get("needs_grocery_item");
                IEntity entity2 = Plato.Brain.Get(item);
                Plato.Brain.CreateRelationship(entity1, relation, entity2);

                return "";
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        /// <summary>
        /// Remove an item to the grocery list.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns>An error string if applicable.</returns>
        [SoapMethod("RemoveGroceryItem")]
        public string RemoveGroceryItem(string item)
        {
            log.Info("RemoveGroceryItem(" + item + ")");

            try
            {
                IEntity entity1 = Plato.Brain.Get("our_family");
                IEntity relation = Plato.Brain.Get("needs_grocery_item");
                IEntity entity2 = Plato.Brain.Get(item);
                Plato.Brain.RemoveRelationship(entity1, relation, entity2);

                return "";
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }

        /// <summary>
        /// Get the list of food items known by the system.
        /// </summary>
        /// <returns>The list of food items.</returns>
        [SoapMethod("GetFoodItems")]
        public string[] GetFoodItems()
        {
            log.Info("GetFoodItems()");

            IList<IEntity> entities = SolveQuery("$x: $x is_a food_item");

            List<string> list = new List<string>();
            foreach (IEntity entity in entities)
            {
                list.Add(entity.Id);
            }

            return list.ToArray();
        }

        /// <summary>
        /// Solve a query.
        /// </summary>
        /// <param name="queryStr">The string reprentation of the query.</param>
        /// <returns>The new query object.</returns>
        private IList<IEntity> SolveQuery(string queryStr)
        {
            Query query = CreateQuery(queryStr);
            return RuleSolver.Solve(Plato.Brain, query,
                                    Plato.Language.IToken)query.Conclusion,
                                    new Dictionary<string, IEntity>());
        }

        /// <summary>
        /// Create a query object.
        /// </summary>
        /// <param name="query">The string reprentation of the query.</param>
        /// <returns>The new query object.</returns>
        private Query CreateQuery(string query)
        {
            return new QueryParser(Plato.Brain,
                                   new TransformationParser(Plato.Brain)).Parse(query);
        }
    }
}