private static bool TryNonExclusiveQueryDeterministicParent( out ELNode foundNode, out ELNodeEnumerator enumerator, ELNode parentNode, object key, LogicVariable v) { // Deterministic parent path // The expression is UniqueParent/Something if (parentNode.IsExclusive) { throw new ELNodeExclusionException("Non-exclusive query of an exclusive node", parentNode, key); } if (v == null) { // fully deterministic path // UniqueParent/Key corresponds to at most one ELNode. enumerator = null; return parentNode.TryLookup(key, out foundNode); } // UniqueParent/Variable, so do a singly-nested iteration. foundNode = null; enumerator = new ELNodeEnumeratorLogicVariableFromNode(parentNode, v); return true; }
public static bool TryQuery(object term, PrologContext context, out ELNode foundNode, out ELNodeEnumerator enumerator) { // Dereference any top-level variables. var t = Term.Deref(term); // Dereference indexicals var i = t as Indexical; if (i != null) t = i.GetValue(context); // A game object means the gameobject's EL KB. var g = t as GameObject; if (g != null) t = g.KnowledgeBase().ELRoot; // If it's already an ELNode, use that. var n = t as ELNode; if (n != null) { foundNode = n; enumerator = null; return true; } // Otherwise, it's an expression, so evaluate it. var s = t as Structure; if (s != null) return TryQueryStructure(s, context, out foundNode, out enumerator); var v = t as LogicVariable; if (v != null && !v.IsBound) throw new Exception("EL query root is an unbound variable: " + v); throw new Exception("Malformed EL query: " + ISOPrologWriter.WriteToString(term)); }
public static bool TryQueryStructure( Structure term, PrologContext context, out ELNode foundNode, out ELNodeEnumerator enumerator) { // // Dispatch based on the functor and arity. // // Handle root queries, i.e. /Key if (term.IsFunctor(Symbol.Slash, 1)) return TryRootQuery(term, context, out foundNode, out enumerator); if (!IsELTerm(term)) throw new Exception("Malformed EL query: " + ISOPrologWriter.WriteToString(term)); if (term.IsFunctor(SBindNodeOperator, 2)) { var variableToBind = term.Argument(1) as LogicVariable; if (variableToBind == null) throw new ArgumentException("RHS of >> must be an uninstantiated variable: "+ ISOPrologWriter.WriteToString(term.Argument(1))); foundNode = null; return TryNodeBindingQuery(out enumerator, term.Argument(0), variableToBind, context); } return TryChildQuery( out foundNode, out enumerator, term.Argument(0), term.Argument(1), term.Functor == Symbol.Colon, context); }
public static bool TryChildQuery( out ELNode foundNode, out ELNodeEnumerator enumerator, object parentExpression, object keyExpression, bool isExclusive, PrologContext context) { // Decode the parent expression ELNode parentNode; ELNodeEnumerator parentEnumerator; if (!TryQuery(parentExpression, context, out parentNode, out parentEnumerator)) { // Parent failed, so we fail enumerator = null; foundNode = null; return false; } // // Decode the key argument // var key = keyExpression; var v = key as LogicVariable; return isExclusive?TryExclusiveQuery(out foundNode, out enumerator, parentNode, parentEnumerator, key, v) : TryNonExclusiveQuery(out foundNode, out enumerator, parentNode, key, v, parentEnumerator); }
private static bool TryNonExclusiveQueryEnumeratedParent( out ELNode foundNode, out ELNodeEnumerator enumerator, object key, LogicVariable v, ELNodeEnumerator parentEnumerator) { // Enumerated parent path // NonUniqueParent/Something foundNode = null; if (v == null) { // NonUniqueParent/Key // Enumerate parent, then do deterministic lookup for child. enumerator = new ELNodeEnumeratorFixedChildFromParentEnumerator(parentEnumerator, key); return true; } if (parentEnumerator.BindsVar(v)) { // We're doing a search for a variable that's aready bound. enumerator = new ELNodeEnumeratorPreboundVariable(parentEnumerator, v, false); return true; } // NonUniqueParent/Variable // Enumerate both parent and child. enumerator = new ELNodeEnumeratorLogicVariableFromParentEnumerator(parentEnumerator, v); return true; }
private void MakeKB() { var parent = transform.parent; KB parentKB = null; if (parent != null) { parentKB = parent.GetComponent <KB>(); } kb = IsGlobal? KnowledgeBase.Global : new KnowledgeBase( gameObject.name, gameObject, parentKB == null ? GameObject.Find(GlobalKBGameObjectName).KnowledgeBase() : parentKB.KnowledgeBase); // Add UID counter. ELNode.Store(kb.ELRoot / Symbol.Intern("next_uid") % 0); try { foreach (var file in SourceFiles) { kb.Consult(file); } } catch (Exception) { Debug.Break(); // Pause the game throw; } }
private static bool TryNonExclusiveQuery(out ELNode foundNode, out ELNodeEnumerator enumerator, ELNode parentNode, object key, LogicVariable v, ELNodeEnumerator parentEnumerator) { if (parentNode != null) { return TryNonExclusiveQueryDeterministicParent(out foundNode, out enumerator, parentNode, key, v); } return TryNonExclusiveQueryEnumeratedParent(out foundNode, out enumerator, key, v, parentEnumerator); }
/// <summary> /// Thrown when attempting to write a non-exclusive value to an exclusive value or vice-versa. /// </summary> public ELNodeExclusionException(string message, ELNode node, object key) : base(string.Format("{0}: {1}{2}{3}", message, node, node.IsExclusive?ELProlog.ExclusiveOperator:ELProlog.NonExclusiveOperator, ISOPrologWriter.WriteToString(key))) { }
private void ToggleNode(ELNode node) { if (displayChildren.Contains(node)) { displayChildren.Remove(node); } else { displayChildren.Add(node); } }
private static bool TryRootQuery(Structure term, PrologContext context, out ELNode foundNode, out ELNodeEnumerator enumerator) { // Expression is /Key. var arg0 = term.Argument(0); // This is a "/constant" expression, i.e. a top-level lookup. if (arg0 is LogicVariable) { throw new NotImplementedException("Lookups of the form /Variable are not supported."); } enumerator = null; return context.KnowledgeBase.ELRoot.TryLookup(arg0, out foundNode); }
/// <summary> /// Attempts to look up a child with the specified key. /// </summary> /// <param name="key">Key to search for</param> /// <param name="child">Child with that key, if found, else null.</param> /// <returns>True if child was found, else false and child is null.</returns> public bool TryLookup(object key, out ELNode child) { foreach (var c in Children) { if (Equals(c.Key, key)) { child = c; return(true); } } child = null; return(false); }
///// <summary> ///// Store an exclusive child inside this node. ///// </summary> ///// <param name="v">Bound variable holding the key for the child</param> ///// <param name="overwrite">If true, this will overwrite any existing child with a different value.</param> ///// <returns>The child node</returns> ///// <exception cref="KBExclusionException">If a non-exclusive child has already been written.</exception> //public ELNode StoreExclusive(Variable v, bool overwrite) //{ // return StoreExclusive(v.Value, overwrite); //} /// <summary> /// Store an exclusive child inside this node. /// </summary> /// <param name="key">Key for the child</param> /// <param name="overwrite">If true, this will overwrite any existing child with a different value.</param> /// <returns>The child node</returns> /// <exception cref="ELNodeExclusionException">If a non-exclusive child has already been written.</exception> public ELNode StoreExclusive(object key, bool overwrite) { switch (mode) { case ExclusionMode.Empty: { mode = ExclusionMode.Exclusive; var result = new ELNode(this, key); if (this.Children.Count == 0) { this.Children = new List <ELNode> { result } } ; else { this.Children.Add(result); } return(result); } case ExclusionMode.NonExclusive: throw new ELNodeExclusionException("Exclusive store on non-exclusive node.", this, key); case ExclusionMode.Exclusive: if (overwrite) { if (this.Children.Count > 0) { this.Children[0].OverwriteExclusive(key); } else { this.Children.Add(new ELNode(this, key)); } } else if (key != this.Children[0].Key) { throw new ELNodeExclusionException("Exclusive store doesn't match previous store.", this, key); } return(this.Children[0]); default: throw new InvalidOperationException("Invalid exclusion mode"); } }
private static bool TryExclusiveQueryEnumeratedParent( out ELNode foundNode, out ELNodeEnumerator enumerator, ELNodeEnumerator parentEnumerator, object key, LogicVariable v) { // Non-deterministic parent path // NonUniqueParent:Something foundNode = null; enumerator = (v == null) ? new ELNodeEnumeratorEnumerateParentAndLookupExclusiveKey(parentEnumerator, key) : (parentEnumerator.BindsVar(v)? (ELNodeEnumerator)new ELNodeEnumeratorPreboundVariable(parentEnumerator, v, true) : new ELNodeEnumeratorEnumerateParentAndBindVariable(parentEnumerator, v)); return true; }
private static bool TryExclusiveQuery( out ELNode foundNode, out ELNodeEnumerator enumerator, ELNode parentNode, ELNodeEnumerator parentEnumerator, object key, LogicVariable v) { // // Expression is Parent:Something // if (parentNode != null) { return TryExclusiveQueryDeterministicParent(out foundNode, out enumerator, parentNode, key, v); } return TryExclusiveQueryEnumeratedParent(out foundNode, out enumerator, parentEnumerator, key, v); }
///// <summary> ///// Store a non-exclusive child inside this node. ///// </summary> ///// <param name="v">Bound variable holding the key for the child</param> ///// <returns>The child node</returns> ///// <exception cref="KBExclusionException">If an exclusive child has already been written.</exception> //public ELNode StoreNonExclusive(Variable v) //{ // return StoreNonExclusive(v.Value); //} /// <summary> /// Store a non-exclusive child inside this node. /// </summary> /// <param name="key">Key for the new child</param> /// <returns>The child node</returns> /// <exception cref="ELNodeExclusionException">If an exclusive child has already been written.</exception> public ELNode StoreNonExclusive(object key) { ELNode result = null; switch (mode) { case ExclusionMode.Empty: { mode = ExclusionMode.NonExclusive; result = new ELNode(this, key); if (this.Children == EmptyChildren) { this.Children = new List <ELNode> { result } } ; else { this.Children.Add(result); } } break; case ExclusionMode.Exclusive: throw new ELNodeExclusionException("Non-exclusive store on exclusive node.", this, key); case ExclusionMode.NonExclusive: foreach (var c in this.Children) { if (c.Key == key) { return(c); } } this.Children.Add(result = new ELNode(this, key)); break; } return(result); }
private float RenderAt(ELNode node, float x, float y) { stringBuilder.Length = 0; var go = node.Key as GameObject; stringBuilder.Append(go != null ? ('$' + go.name) : (node.Key == null? "null" : node.Key.ToString())); stringBuilder.Append(node.ModeString); var suppressChildren = node.Children.Count > 1 && !displayChildren.Contains(node); if (suppressChildren) { stringBuilder.Append(" ..."); } var key = new GUIContent(stringBuilder.ToString()); var size = Style.CalcSize(key); if (mouseClicked && mouseClickY >= y && mouseClickY < y + size.y) { ToggleNode(node); } GUI.Label(new Rect(x, y, size.x, size.y), key, Style); x += size.x; if (node.Children.Count == 0 || suppressChildren) { y += size.y; } else { foreach (var child in node.Children) { y = this.RenderAt(child, x, y); } } return(y); }
private static bool TryExclusiveQueryDeterministicParent( out ELNode foundNode, out ELNodeEnumerator enumerator, ELNode parentNode, object key, LogicVariable v) { // Deterministic parent path // UniqueParent:Something if (parentNode.IsNonExclusive) { throw new ELNodeExclusionException("Exclusive query of an non-exclusive node", parentNode, key); } if (v == null) { // Deterministic child path // UniqueParent:Key enumerator = null; return parentNode.TryLookup(key, out foundNode); } // Enumerated child path // UniqueParent:Variable if (parentNode.Children.Count > 0) { foundNode = null; enumerator = new ELNodeEnumeratorBindAndUnbindVariable(parentNode.Children[0], v); return true; } // parentNode is exclusive, but is childless, so we can't match. foundNode = null; enumerator = null; return false; }
public ELNodeEnumeratorLogicVariableFromNode(ELNode parentNode, LogicVariable v) { this.parentNode = parentNode; this.variable = v; childIndex = 0; }
internal ELNode(ELNode parent, object key) { Key = key; Parent = parent; Children = EmptyChildren; }
/// <summary> /// A do-nothing procedure used to make clear that a / % expression in C# is really intended to do a store. /// </summary> /// <param name="ignore">The ELNode that got stored.</param> public static void Store(ELNode ignore) { // Does nothing }
public ELNodeEnumeratorBindFixedNodeToVariable(ELNode node, LogicVariable variableToBind) { this.node = node; this.variableToBind = variableToBind; }
public void SetKB(KnowledgeBase kb) { root = kb.ELRoot; displayChildren.Add(root); WindowTitle = kb.Name + " KB"; }
public ELNodeEnumeratorBindAndUnbindVariable(ELNode child, LogicVariable v) { this.child = child; this.variable = v; }
public void SetKB(KnowledgeBase kb) { root = kb.ELRoot; displayChildren.Add(root); }