 |
Exercise 7: Solution
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Plato.Core;
namespace Plato.Language.Parser { /// <summary> /// Parses word-to-entity mappings. /// </summary> public class WordMappingParser { Brain brain; IEntity is_a;
public WordMappingParser(Brain brain) { this.brain = brain;
is_a = brain.Get("is_a"); }
/// <summary> /// Parse one or more lines of input that define word-to-entity /// mappings. /// </summary> /// <param name="str">The text input.</param> public void Parse(string str) { string[] lines = str.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
// Process each line of input int lineNum = 0; foreach (string line in lines) { ++lineNum; line.Trim();
if (String.IsNullOrEmpty(line)) { continue; }
try { string wordId; string mapping; List<string> wordTypes = new List<string>(); string entityId;
if (line.Contains("->")) { string[] parts = line.Split(new string[] { "->" }, StringSplitOptions.None); if (parts.Length != 2) { throw new TooManyArrowsException( "Expecting a single '->'"); } else { wordId = parts[0].Trim(); mapping = parts[1].Trim();
int colonPos = mapping.IndexOf(':');
if (colonPos >= 0) { entityId = mapping.Substring(0, colonPos).Trim(); mapping = mapping.Substring( colonPos + 1, mapping.Length - colonPos - 1).Trim();
// The word is additionally specified as being // a noun, verb, etc. wordTypes = mapping.Split( new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList<string>(); } else { entityId = mapping; }
IEntity word = brain.Get(wordId); if (word == null) { word = brain.CreateEntity(wordId); }
IEntity entity = brain.Get(entityId); if (entity == null) { entity = brain.CreateEntity(entityId); }
brain.CreateRelationship(word, is_a, entity);
foreach (string wordTypeId in wordTypes) { IEntity wordType = brain.Get(wordTypeId); if (wordType == null) { wordType = brain.CreateEntity(wordTypeId); }
brain.CreateRelationship(entity, is_a, wordType); } } } else { throw new MissingArrowException("Missing '->'"); } } catch (AlterableException e) { e.AlterMessage( String.Format("Line {0}: {1}", lineNum, e.Message)); throw e; } catch (Exception e) { throw new Exception( String.Format("Line {0}: {1}", lineNum, e.Message)); } } } } }
|
|
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Plato.Core { /// <summary> /// A tree of entities. /// </summary> public class EntityTree { EntityTreeNode root; IDictionary<string, EntityTreeNode> entities;
/// <summary> /// Create an entity tree. /// </summary> /// <param name="root">The root node.</param> /// <param name="entities">The dictionary of entities.</param> public EntityTree( IEntity root, IDictionary<string,EntityTreeNode> entities) { this.root = new EntityTreeNode(root, null); this.entities = entities; }
/// <summary> /// The root node of the Tree. /// </summary> public EntityTreeNode Root { get { return root; } }
/// <summary> /// Get a flat list of the entities. /// </summary> /// <returns></returns> public ICollection<EntityTreeNode> GetList() { return entities.Values; } } }
|
|
using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Plato.Core { /// <summary> /// Represents a node in a tree of entities. /// </summary> public class EntityTreeNode { IEntity entity; IList<EntityTreeNode> children; EntityTreeNode parent;
public EntityTreeNode(IEntity entity, EntityTreeNode parent) { this.entity = entity; this.parent = parent; this.children = new List<EntityTreeNode>(); }
/// <summary> /// The node's entity. /// </summary> public IEntity Entity { get { return entity; } }
/// <summary> /// The node's parent. /// </summary> public EntityTreeNode Parent { get { return parent; } }
/// <summary> /// The node's children. /// </summary> public IList<EntityTreeNode> Children { get { return children; } } } }
|
|
/// <summary> /// Returns a tree that represents the entity's is_a relationships. /// </summary> /// <returns>A tree.</returns> public EntityTree GetIsATree() { IDictionary<string, EntityTreeNode> entities = new Dictionary<string, EntityTreeNode>();
EntityTree tree = new EntityTree(this, entities);
PopulateIsATree(tree.Root, entities);
return tree; }
/// <summary> /// Helper function for GetIsATree. /// </summary> /// <param name="treeNode">The tree node to populate.</param> /// <param name="entities">Dictionary of already-processed entities.</param> private void PopulateIsATree(EntityTreeNode treeNode, IDictionary<string, EntityTreeNode> entities) { entities.Add(new KeyValuePair<string, EntityTreeNode>( this.Id, treeNode));
// Depth-first, recursive iteration foreach (List<IRelationship> relationshipList in relatedEntities.Values) { foreach (IRelationship relationship in relationshipList) { if (relationship.Relation.Id == "is_a") { if (!entities.ContainsKey(relationship.Entity2.Id)) { EntityTreeNode child = new EntityTreeNode( relationship.Entity2, treeNode);
((Entity)relationship.Entity2).PopulateIsATree(child, entities);
treeNode.Children.Add(child); } } } } }
|
|
|
|
 |