/// <summary> /// Instantiates a new labelled Query based on an AtomGroup. /// </summary> /// <param name="label">The Label of the new Query.</param> /// <param name="atomGroup">The AtomGroup used in the new Query.</param> public Query(string label, AtomGroup atomGroup) { if ((null != label) && (String.Empty == label)) this.label = null; else this.label = label; this.atomGroup = atomGroup; }
/// <summary> /// Instantiates a new Implication. /// </summary> /// <param name="label">The label of the new implication.</param> /// <param name="priority">The priority of the new implication.</param> /// <param name="mutex">String.Empty or the label of an implication mutexed by the new one.</param> /// <param name="precondition">String.Empty or the label of an implication that preconditions the new one.</param> /// <param name="deduction">The Atom used as a prototype for what this Implication tries to proove.</param> /// <param name="atomGroup">The top level group of atoms used in the query part (pattern matching) of the new Implication.</param> /// <see cref="org.nxbre.ie.rule.ImplicationPriority"/> public Implication(string label, ImplicationPriority priority, string mutex, string precondition, Atom deduction, AtomGroup atomGroup) : this(label, (int)priority, mutex, precondition, deduction, atomGroup) { }
/// <summary> /// Instantiates a new labelled Query based on an AtomGroup. /// </summary> /// <param name="label">The Label of the new Query.</param> /// <param name="atomGroup">The AtomGroup used in the new Query.</param> public Query(string label, AtomGroup atomGroup) { if ((null != label) && (String.Empty == label)) { this.label = null; } else { this.label = label; } this.atomGroup = atomGroup; }
/// <summary> /// Instantiates a new Implication. /// </summary> /// <param name="label">The label of the new implication.</param> /// <param name="priority">The priority of the new implication.</param> /// <param name="mutex">String.Empty or the label of an implication mutexed by the new one.</param> /// <param name="precondition">String.Empty or the label of an implication that preconditions the new one.</param> /// <param name="deduction">The Atom used as a prototype for what this Implication tries to proove.</param> /// <param name="atomGroup">The top level group of atoms used in the query part (pattern matching) of the new Implication.</param> /// <see cref="org.nxbre.ie.rule.ImplicationPriority"/> public Implication(string label, int priority, string mutex, string precondition, Atom deduction, AtomGroup atomGroup) : this(label, priority, mutex, precondition, deduction, atomGroup, ImplicationAction.Assert) { }
/// <summary> /// Instantiates a new anonymous (non-labelled) Query based on an AtomGroup. /// </summary> /// <param name="atomGroup">The AtomGroup used in the new Query.</param> public Query(AtomGroup atomGroup) : this(null, atomGroup) { }
/// <summary> /// Instantiates a new Implication. /// </summary> /// <param name="label">The label of the new implication.</param> /// <param name="priority">The priority of the new implication.</param> /// <param name="mutex">String.Empty or the label of an implication mutexed by the new one.</param> /// <param name="precondition">String.Empty or the label of an implication that preconditions the new one.</param> /// <param name="deduction">The Atom used as a prototype for what this Implication tries to proove.</param> /// <param name="atomGroup">The top level group of atoms used in the query part (pattern matching) of the new Implication.</param> /// <param name="action">The implication action.</param> /// <see cref="org.nxbre.ie.rule.ImplicationAction"/> /// <see cref="org.nxbre.ie.rule.ImplicationPriority"/> public Implication(string label, int priority, string mutex, string precondition, Atom deduction, AtomGroup atomGroup, ImplicationAction action):base(label, atomGroup) { if (deduction.HasFunction) throw new BREException("Can not create Implication with functions in the Deduction: " + deduction.ToString()); if ((mutex != null) && (mutex == label)) throw new BREException("An Implication can not Mutex itself: " + mutex); if ((precondition != null) && (precondition == label)) throw new BREException("An Implication can not Pre-Condition itself: " + precondition); foreach(object member in AtomGroup.Members) if ((member is Atom) && (((Atom)member).HasNotStringIndividual)) throw new BREException("Can not create Implication with non-String individuals in the atoms: " + member.ToString()); if ((priority < (int)ImplicationPriority.Minimum) || (priority > (int)ImplicationPriority.Maximum)) throw new ArgumentOutOfRangeException("Priority must be in the [" + ImplicationPriority.Minimum + "-" + ImplicationPriority.Maximum + "] range."); if (action == ImplicationAction.Count) { if (deduction.IsFact) throw new BREException("A counting Implication must have one Variable predicate in its deduction atom."); int varCount = 0; foreach(IPredicate member in deduction.Members) { if (member is Variable) varCount++; if (varCount > 1) throw new BREException("A counting Implication must have only one Variable predicate in its deduction atom."); } } this.priority = priority; this.deduction = deduction; this.mutex = mutex; this.precondition = precondition; this.action = action; }
/// <summary> /// Instantiates a new Implication. /// </summary> /// <param name="label">The label of the new implication.</param> /// <param name="priority">The priority of the new implication.</param> /// <param name="mutex">String.Empty or the label of an implication mutexed by the new one.</param> /// <param name="precondition">String.Empty or the label of an implication that preconditions the new one.</param> /// <param name="deduction">The Atom used as a prototype for what this Implication tries to proove.</param> /// <param name="atomGroup">The top level group of atoms used in the query part (pattern matching) of the new Implication.</param> /// <see cref="org.nxbre.ie.rule.ImplicationPriority"/> public Implication(string label, int priority, string mutex, string precondition, Atom deduction, AtomGroup atomGroup):this(label, priority, mutex, precondition, deduction, atomGroup, ImplicationAction.Assert) {}
private void ProcessOr(AtomGroup AG, ArrayList processResult, ArrayList resultStack) { foreach(object member in AG.ResolvedMembers) { if (member is AtomGroup) { if (((AtomGroup)member).Operator == AtomGroup.LogicalOperator.Or) throw new BREException("Nested Or unexpectedly found in atom group:" + member); ArrayList subProcessResult = new ArrayList(); ProcessAnd((AtomGroup)member, subProcessResult, 0, resultStack); foreach(ArrayList resultRow in subProcessResult) processResult.Add(resultRow); } else if (member is Atom) { // resolve the functions and var parts of the atom // from all the previous facts in the result stack Atom atomToRun = Populate((Atom)member, resultStack, false); // return results found for the first atom that produces data IEnumerator results = ProcessAtom(atomToRun, null); if (results != null) { while(results.MoveNext()) { Fact result = (Fact)results.Current; ArrayList tempResultStack = new ArrayList(); tempResultStack.Add(new ResultPocket((Atom)member, result)); processResult.Add(tempResultStack); } } } } }
protected void WriteAtomGroup(XmlElement target, AtomGroup atomGroup, string andElement, string orElement) { if (atomGroup.Members.Length != 1) { XmlElement op = Document.CreateElement((atomGroup.Operator == AtomGroup.LogicalOperator.And)?andElement:orElement, DatalogNamespaceURL); target.AppendChild(op); for(int i=0; i<atomGroup.Members.Length; i++) { if (atomGroup.Members[i] is Atom) WriteAtom(op, (Atom)atomGroup.Members[i], false); else if (atomGroup.Members[i] is AtomGroup) WriteAtomGroup(op, (AtomGroup)atomGroup.Members[i]); } } else WriteAtom(target, (Atom)atomGroup.Members[0], false); }
public void AtomGroupMemberOrdering() { AtomGroup child = new AtomGroup(AtomGroup.LogicalOperator.Or, atom2_2, atomF); AtomGroup parent = new AtomGroup(AtomGroup.LogicalOperator.And, child, atom3); Assert.AreEqual(child, parent.Members[0], "First member match"); Assert.AreEqual(atom3, parent.Members[1], "Second member match"); }
private void WriteAtomGroup(XmlElement target, AtomGroup atomGroup) { if (atomGroup.Members.Length != 1) { XmlElement op = document.CreateElement((atomGroup.Operator == AtomGroup.LogicalOperator.And)?"and":"or", GetDatalogNamespaceURL()); target.AppendChild(op); for(int i=0; i<atomGroup.Members.Length; i++) { if (atomGroup.Members[i] is Atom) WriteAtom(op, (Atom)atomGroup.Members[i], false); else if (atomGroup.Members[i] is AtomGroup) WriteAtomGroup(op, (AtomGroup)atomGroup.Members[i]); } } else WriteAtom(target, (Atom)atomGroup.Members[0], false); }
/// <summary> /// Instantiates a new Implication. /// </summary> /// <param name="label">The label of the new implication.</param> /// <param name="priority">The priority of the new implication.</param> /// <param name="mutex">String.Empty or the label of an implication mutexed by the new one.</param> /// <param name="precondition">String.Empty or the label of an implication that preconditions the new one.</param> /// <param name="deduction">The Atom used as a prototype for what this Implication tries to proove.</param> /// <param name="atomGroup">The top level group of atoms used in the query part (pattern matching) of the new Implication.</param> /// <param name="action">The implication action.</param> /// <see cref="org.nxbre.ie.rule.ImplicationAction"/> /// <see cref="org.nxbre.ie.rule.ImplicationPriority"/> public Implication(string label, int priority, string mutex, string precondition, Atom deduction, AtomGroup atomGroup, ImplicationAction action) : base(label, atomGroup) { if (deduction.HasFunction) { throw new BREException("Can not create Implication with functions in the Deduction: " + deduction.ToString()); } if ((mutex != null) && (mutex == label)) { throw new BREException("An Implication can not Mutex itself: " + mutex); } if ((precondition != null) && (precondition == label)) { throw new BREException("An Implication can not Pre-Condition itself: " + precondition); } /* Commented out to solve bug #1469851 : this test was not necessary anymore as the engine can now handle typed data in implications * foreach(object member in AtomGroup.Members) * if ((member is Atom) && (((Atom)member).HasNotStringIndividual)) * throw new BREException("Can not create Implication with non-String individuals in the atoms: " + member.ToString()); */ if ((priority < (int)ImplicationPriority.Minimum) || (priority > (int)ImplicationPriority.Maximum)) { throw new ArgumentOutOfRangeException("Priority must be in the [" + ImplicationPriority.Minimum + "-" + ImplicationPriority.Maximum + "] range."); } if (action == ImplicationAction.Count) { if (deduction.IsFact) { throw new BREException("A counting Implication must have one Variable predicate in its deduction atom."); } int varCount = 0; foreach (IPredicate member in deduction.Members) { if (member is Variable) { varCount++; } if (varCount > 1) { throw new BREException("A counting Implication must have only one Variable predicate in its deduction atom."); } } } this.priority = priority; this.deduction = deduction; this.mutex = mutex; this.precondition = precondition; this.action = action; }
protected abstract void WriteAtomGroup(XmlElement target, AtomGroup atomGroup);
protected override AtomGroup NewAtomGroup(AtomGroup.LogicalOperator logicalOperator, object[] content) { if (equivalents.Count == 0) return new AtomGroup(logicalOperator, content); // if we have equivalent atoms, try to translate content into equivalent sub-groups ArrayList enrichedContent = new ArrayList(); foreach(object atomOrAtomGroup in content) { if (atomOrAtomGroup is Atom) { Atom atom = (Atom)atomOrAtomGroup; ArrayList atomEquivalents = Equivalent.GetAll(equivalents, atom, new ArrayList()); if (atomEquivalents.Count > 1) { if (logicalOperator == AtomGroup.LogicalOperator.Or) { // in an OR block, negative atoms are surrounded by AND if (atom.Negative) enrichedContent.Add(new AtomGroup(AtomGroup.LogicalOperator.And, atomEquivalents.ToArray())); else enrichedContent.AddRange(atomEquivalents); } else { // in an AND block, positive atoms are surrounded by OR if (atom.Negative) enrichedContent.AddRange(atomEquivalents); else enrichedContent.Add(new AtomGroup(AtomGroup.LogicalOperator.Or, atomEquivalents.ToArray())); } } else { // add atoms that have found no equivalents enrichedContent.AddRange(atomEquivalents); } } else { // directly add atom groups enrichedContent.Add(atomOrAtomGroup); } } return new AtomGroup(logicalOperator, content, enrichedContent.ToArray()); }
protected override void WriteAtomGroup(XmlElement target, AtomGroup atomGroup) { WriteAtomGroup(target, atomGroup, "And", "Or"); }
/// <summary> /// Runs an AtomGroup against the FactBase. /// </summary> /// <remarks> /// Each Atom in the group and sub-groups must have been registered. /// </remarks> /// <param name="AG">The AtomGroup to execute</param> /// <returns>A ProcessResults object containing the results.</returns> public ProcessResultSet ProcessAtomGroup(AtomGroup AG) { ArrayList runResult = new ArrayList(); if (AG.Operator == AtomGroup.LogicalOperator.And) ProcessAnd(AG, runResult, 0, new ArrayList()); else if (AG.Operator == AtomGroup.LogicalOperator.Or) ProcessOr(AG, runResult, new ArrayList()); else throw new BREException("Processor encountered unsupported logical operator: " + AG.Operator); return new ProcessResultSet(runResult); }
private void ProcessAnd(AtomGroup AG, ArrayList processResult, int parser, ArrayList resultStack) { if (AG.ResolvedMembers[parser] is AtomGroup) { if (((AtomGroup)AG.ResolvedMembers[parser]).Operator == AtomGroup.LogicalOperator.And) throw new BREException("Nested And unexpectedly found in atom group:" + AG.ResolvedMembers[parser]); ArrayList subProcessResult = new ArrayList(); ProcessOr((AtomGroup)AG.ResolvedMembers[parser], subProcessResult, resultStack); foreach(ArrayList resultRow in subProcessResult) { foreach(ResultPocket rpRow in resultRow) { if (resultStack.Count == 0) { ArrayList tempResultStack = (ArrayList)resultStack.Clone(); tempResultStack.Add(rpRow); if (parser < (AG.OrderedMembers.Length-1)) ProcessAnd(AG, processResult, parser+1, tempResultStack); else processResult.Add(tempResultStack); } else { // exclude similar results for similar atoms (the engine must produce combinations // of facts in this case) bool ignore = false; foreach(ResultPocket rp in resultStack) { if (rpRow.source.IsIntersecting(rp.source)) { ignore = true; break; } if (!ignore) { ArrayList tempResultStack = (ArrayList)resultStack.Clone(); tempResultStack.Add(rpRow); if (parser < (AG.OrderedMembers.Length-1)) ProcessAnd(AG, processResult, parser+1, tempResultStack); else processResult.Add(tempResultStack); } } } } } } else { // resolve the functions and var parts of the atom // from all the previous facts in the result stack Atom atomToRun = Populate((Atom)AG.ResolvedMembers[parser], resultStack, false); ArrayList excludedHashCodes = new ArrayList(); foreach(ResultPocket rp in resultStack) if (((Atom)AG.OrderedMembers[parser]).IsIntersecting(rp.source)) excludedHashCodes.Add(rp.fact.GetLongHashCode()); // then get the matching facts IEnumerator results = ProcessAtom(atomToRun, excludedHashCodes); if (results != null) { while(results.MoveNext()) { Fact result = (Fact)results.Current; ArrayList tempResultStack = (ArrayList)resultStack.Clone(); tempResultStack.Add(new ResultPocket((Atom)AG.OrderedMembers[parser], result)); if (parser < (AG.OrderedMembers.Length-1)) ProcessAnd(AG, processResult, parser+1, tempResultStack); else processResult.Add(tempResultStack); } } } }
protected virtual AtomGroup NewAtomGroup(AtomGroup.LogicalOperator logicalOperator, object[] content) { return new AtomGroup(logicalOperator, content); }