Пример #1
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);
        }
Пример #2
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);
        }
Пример #3
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));
        }
Пример #4
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);
 }
Пример #5
0
 private static IEnumerable <CutState> DeleteSuccessive(ELNodeEnumerator enumerator)
 {
     while (enumerator.MoveNext())
     {
         enumerator.Current.DeleteSelf();
         yield return(CutState.Continue);
     }
 }
Пример #6
0
 public ELNodeEnumeratorBindEnumeratedNodesToVariable(ELNodeEnumerator nodeEnumerator, LogicVariable variableToBind)
 {
     this.nodeEnumerator = nodeEnumerator;
     this.variableToBind = variableToBind;
     if (nodeEnumerator.BindsVar(variableToBind))
     {
         throw new InvalidOperationException("Variable appears on both the LHS and RHS of >>: " + variableToBind.Name);
     }
 }
Пример #7
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;
        }
Пример #8
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);
        }
Пример #9
0
 public static bool TryNodeBindingQuery(
     out ELNodeEnumerator enumerator,
     object nodeExpression,
     LogicVariable variableToBind,
     PrologContext context)
 {
     // Decode the node expression
     ELNode foundNode;
     ELNodeEnumerator nodeEnumerator;
     if (!TryQuery(nodeExpression, context, out foundNode, out nodeEnumerator))
     {
         // Parent failed, so we fail
         enumerator = null;
         return false;
     }
     enumerator = (foundNode != null)
         ? (ELNodeEnumerator)new ELNodeEnumeratorBindFixedNodeToVariable(foundNode, variableToBind)
         : new ELNodeEnumeratorBindEnumeratedNodesToVariable(nodeEnumerator, variableToBind);
     return true;
 }
Пример #10
0
 public static bool TryNodeBindingQuery(
     out ELNodeEnumerator enumerator,
     object nodeExpression,
     LogicVariable variableToBind,
     PrologContext context)
 {
     // Decode the node expression
     ELNode foundNode;
     ELNodeEnumerator nodeEnumerator;
     if (!TryQuery(nodeExpression, context, out foundNode, out nodeEnumerator))
     {
         // Parent failed, so we fail
         enumerator = null;
         return false;
     }
     enumerator = (foundNode != null)
         ? (ELNodeEnumerator)new ELNodeEnumeratorBindFixedNodeToVariable(foundNode, variableToBind)
         : new ELNodeEnumeratorBindEnumeratedNodesToVariable(nodeEnumerator, variableToBind);
     return true;
 }
Пример #11
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));
        }
Пример #12
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;
        }
Пример #13
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);
        }
Пример #14
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;
 }
Пример #15
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));
        }
Пример #16
0
 public ELNodeEnumeratorEnumerateParentAndLookupExclusiveKey(ELNodeEnumerator parentEnumerator, object key)
 {
     this.parentEnumerator = parentEnumerator;
     this.key = key;
 }
Пример #17
0
 public ELNodeEnumeratorPreboundVariable(ELNodeEnumerator parentEnumerator, LogicVariable variable, bool exclusive)
 {
     this.parentEnumerator = parentEnumerator;
     this.variable = variable;
     this.exclusive = exclusive;
 }
Пример #18
0
 public ELNodeEnumeratorFixedChildFromParentEnumerator(ELNodeEnumerator parentEnumerator, object childKey)
 {
     this.parentEnumerator = parentEnumerator;
     this.childKey = childKey;
 }
Пример #19
0
 public ELNodeEnumeratorEnumerateParentAndLookupExclusiveKey(ELNodeEnumerator parentEnumerator, object key)
 {
     this.parentEnumerator = parentEnumerator;
     this.key = key;
 }
Пример #20
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);
        }
Пример #21
0
 private static System.Collections.Generic.IEnumerable<CutState> DeleteSuccessive(ELNodeEnumerator enumerator)
 {
     while (enumerator.MoveNext())
     {
         enumerator.Current.DeleteSelf();
         yield return CutState.Continue;
     }
 }
Пример #22
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);
        }
Пример #23
0
 public ELNodeEnumeratorPreboundVariable(ELNodeEnumerator parentEnumerator, LogicVariable variable, bool exclusive)
 {
     this.parentEnumerator = parentEnumerator;
     this.variable = variable;
     this.exclusive = exclusive;
 }
Пример #24
0
 private static System.Collections.Generic.IEnumerable<CutState> DeleteSuccessive(ELNodeEnumerator enumerator)
 {
     while (enumerator.MoveNext())
     {
         enumerator.Current.DeleteSelf();
         yield return CutState.Continue;
     }
 }
Пример #25
0
 public ELNodeEnumeratorFixedChildFromParentEnumerator(ELNodeEnumerator parentEnumerator, object childKey)
 {
     this.parentEnumerator = parentEnumerator;
     this.childKey = childKey;
 }
Пример #26
0
 public ELNodeEnumeratorEnumerateParentAndBindVariable(ELNodeEnumerator parentEnumerator, LogicVariable variable)
 {
     this.parentEnumerator = parentEnumerator;
     this.variable = variable;
 }
Пример #27
0
 public ELNodeEnumeratorBindEnumeratedNodesToVariable(ELNodeEnumerator nodeEnumerator, LogicVariable variableToBind)
 {
     this.nodeEnumerator = nodeEnumerator;
     this.variableToBind = variableToBind;
     if (nodeEnumerator.BindsVar(variableToBind))
         throw new InvalidOperationException("Variable appears on both the LHS and RHS of >>: "+ variableToBind.Name);
 }
Пример #28
0
 public ELNodeEnumeratorEnumerateParentAndBindVariable(ELNodeEnumerator parentEnumerator, LogicVariable variable)
 {
     this.parentEnumerator = parentEnumerator;
     this.variable = variable;
 }
Пример #29
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;
        }
Пример #30
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;
        }
Пример #31
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);
 }
Пример #32
0
 public ELNodeEnumeratorLogicVariableFromParentEnumerator(ELNodeEnumerator parentEnumerator, LogicVariable v)
 {
     this.parentEnumerator = parentEnumerator;
     this.variable = v;
     childIndex = -1;
 }
Пример #33
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;
        }
Пример #34
0
        private static IEnumerable<CutState> EnumerateAndBindNode(ELNodeEnumerator enumerator, object varToBindTo)
        {
            while (enumerator.MoveNext())
#pragma warning disable 414, 168, 219
                // ReSharper disable once UnusedVariable
                foreach (var ignore in Term.Unify(varToBindTo, enumerator.Current))
#pragma warning restore 414, 168, 219
                    yield return CutState.Continue;
        }
Пример #35
0
 public ELNodeEnumeratorLogicVariableFromParentEnumerator(ELNodeEnumerator parentEnumerator, LogicVariable v)
 {
     this.parentEnumerator = parentEnumerator;
     this.variable = v;
     childIndex = -1;
 }