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); }
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)); }
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); }
private static IEnumerable <CutState> DeleteSuccessive(ELNodeEnumerator enumerator) { while (enumerator.MoveNext()) { enumerator.Current.DeleteSelf(); yield return(CutState.Continue); } }
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); } }
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); }
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; }
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)); }
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; }
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); }
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; }
public ELNodeEnumeratorEnumerateParentAndLookupExclusiveKey(ELNodeEnumerator parentEnumerator, object key) { this.parentEnumerator = parentEnumerator; this.key = key; }
public ELNodeEnumeratorPreboundVariable(ELNodeEnumerator parentEnumerator, LogicVariable variable, bool exclusive) { this.parentEnumerator = parentEnumerator; this.variable = variable; this.exclusive = exclusive; }
public ELNodeEnumeratorFixedChildFromParentEnumerator(ELNodeEnumerator parentEnumerator, object childKey) { this.parentEnumerator = parentEnumerator; this.childKey = childKey; }
private static System.Collections.Generic.IEnumerable<CutState> DeleteSuccessive(ELNodeEnumerator enumerator) { while (enumerator.MoveNext()) { enumerator.Current.DeleteSelf(); yield return CutState.Continue; } }
public ELNodeEnumeratorEnumerateParentAndBindVariable(ELNodeEnumerator parentEnumerator, LogicVariable variable) { this.parentEnumerator = parentEnumerator; this.variable = variable; }
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); }
public ELNodeEnumeratorLogicVariableFromParentEnumerator(ELNodeEnumerator parentEnumerator, LogicVariable v) { this.parentEnumerator = parentEnumerator; this.variable = v; childIndex = -1; }
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; }
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; }