Beispiel #1
0
        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;
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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;
 }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
 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)))
 {
 }
Beispiel #9
0
 private void ToggleNode(ELNode node)
 {
     if (displayChildren.Contains(node))
     {
         displayChildren.Remove(node);
     }
     else
     {
         displayChildren.Add(node);
     }
 }
Beispiel #10
0
        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);
        }
Beispiel #11
0
 /// <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);
 }
Beispiel #12
0
        ///// <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");
            }
        }
Beispiel #13
0
        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;
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        ///// <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);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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;
        }
Beispiel #18
0
 public ELNodeEnumeratorLogicVariableFromNode(ELNode parentNode, LogicVariable v)
 {
     this.parentNode = parentNode;
     this.variable = v;
     childIndex = 0;
 }
Beispiel #19
0
 internal ELNode(ELNode parent, object key)
 {
     Key      = key;
     Parent   = parent;
     Children = EmptyChildren;
 }
Beispiel #20
0
 /// <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
 }
Beispiel #21
0
 public ELNodeEnumeratorBindFixedNodeToVariable(ELNode node, LogicVariable variableToBind)
 {
     this.node = node;
     this.variableToBind = variableToBind;
 }
Beispiel #22
0
 public void SetKB(KnowledgeBase kb)
 {
     root = kb.ELRoot;
     displayChildren.Add(root);
     WindowTitle = kb.Name + " KB";
 }
Beispiel #23
0
 public ELNodeEnumeratorBindAndUnbindVariable(ELNode child, LogicVariable v)
 {
     this.child = child;
     this.variable = v;
 }
Beispiel #24
0
 public void SetKB(KnowledgeBase kb)
 {
     root = kb.ELRoot;
     displayChildren.Add(root);
 }