public void AtomGroupOrderedMemberOrdering() { AtomGroup child = new AtomGroup(AtomGroup.LogicalOperator.Or, atom2_2, atomF); AtomGroup parent = new AtomGroup(AtomGroup.LogicalOperator.And, child, atom3); Assert.AreEqual(child, parent.OrderedMembers[1], "First member match"); Assert.AreEqual(atom3, parent.OrderedMembers[0], "Second member match"); }
/// <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>An <code>IList<IList<PositiveMatchResult>></code> object containing the results.</returns> public IList <IList <PositiveMatchResult> > ProcessAtomGroup(AtomGroup AG) { List <IList <PositiveMatchResult> > runResult = new List <IList <PositiveMatchResult> >(); if (AG.Operator == AtomGroup.LogicalOperator.And) { ProcessAnd(AG, runResult, 0, new List <PositiveMatchResult>()); } else if (AG.Operator == AtomGroup.LogicalOperator.Or) { ProcessOr(AG, runResult, new List <PositiveMatchResult>()); } else { throw new BREException("Processor encountered unsupported logical operator: " + AG.Operator); } return(runResult.AsReadOnly()); }
/// <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)); }
/// <summary> /// Processes an OR atom group. /// </summary> /// <param name="AG"></param> /// <param name="processResult"></param> /// <param name="resultStack"></param> private void ProcessOr(AtomGroup AG, IList <IList <PositiveMatchResult> > processResult, IList <PositiveMatchResult> resultStack) { foreach (var member in AG.OrderedMembers) { var ag = member as AtomGroup; if (ag != null) { if (ag.Operator == AtomGroup.LogicalOperator.Or) { throw new BREException("Nested Or unexpectedly found in atom group:" + member); } IList <IList <PositiveMatchResult> > subProcessResult = new List <IList <PositiveMatchResult> >(); ProcessAnd(ag, subProcessResult, 0, resultStack); foreach (var 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 var atomToRun = Populate((Atom)member, resultStack, false); // return results found for the first atom that produces data IEnumerator results = ProcessAtom(atomToRun, null); if (results == null) { continue; } while (results.MoveNext()) { var result = (Fact)results.Current; IList <PositiveMatchResult> tempResultStack = new List <PositiveMatchResult>(); tempResultStack.Add(new PositiveMatchResult((Atom)member, result)); processResult.Add(tempResultStack); } } } } //ProcessOr
/// <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>An <code>IList<IList<PositiveMatchResult>></code> object containing the results.</returns> public IList <IList <PositiveMatchResult> > ProcessAtomGroup(AtomGroup AG) { var runResult = new List <IList <PositiveMatchResult> >(); switch (AG.Operator) { case AtomGroup.LogicalOperator.And: ProcessAnd(AG, runResult, 0, new List <PositiveMatchResult>()); break; case AtomGroup.LogicalOperator.Or: ProcessOr(AG, runResult, new List <PositiveMatchResult>()); break; default: throw new BREException("Processor encountered unsupported logical operator: " + AG.Operator); } return(runResult.AsReadOnly()); }
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); } } } } } //ProcessOr
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); } }
protected void WriteAtomGroup(XmlElement target, AtomGroup atomGroup, string andElement, string orElement) { if (atomGroup.Members.Length != 1) { var op = Document.CreateElement((atomGroup.Operator == AtomGroup.LogicalOperator.And)?andElement:orElement, DatalogNamespaceURL); target.AppendChild(op); foreach (var t in atomGroup.Members) { var atom = t as Atom; if (atom != null) { WriteAtom(op, atom, false); } else if (t is AtomGroup) { WriteAtomGroup(op, (AtomGroup)t); } } } else { WriteAtom(target, (Atom)atomGroup.Members[0], false); } }
protected override void WriteAtomGroup(XmlElement target, AtomGroup atomGroup) { WriteAtomGroup(target, atomGroup, "And", "Or"); }
/// <summary> /// Processes an AND atom group. /// </summary> /// <param name="AG"></param> /// <param name="processResult"></param> /// <param name="depth"></param> /// <param name="resultStack"></param> private void ProcessAnd(AtomGroup AG, IList <IList <PositiveMatchResult> > processResult, int depth, IList <PositiveMatchResult> resultStack) { if (AG.OrderedMembers[depth] is AtomGroup) { if (((AtomGroup)AG.OrderedMembers[depth]).Operator == AtomGroup.LogicalOperator.And) { throw new BREException("Nested And unexpectedly found in atom group:" + AG.OrderedMembers[depth]); } IList <IList <PositiveMatchResult> > subProcessResult = new List <IList <PositiveMatchResult> >(); ProcessOr((AtomGroup)AG.OrderedMembers[depth], subProcessResult, resultStack); foreach (IList <PositiveMatchResult> resultRow in subProcessResult) { foreach (PositiveMatchResult rpRow in resultRow) { if (resultStack.Count == 0) { IList <PositiveMatchResult> tempResultStack = new List <PositiveMatchResult>(resultStack); tempResultStack.Add(rpRow); if (depth < (AG.OrderedMembers.Count - 1)) { ProcessAnd(AG, processResult, depth + 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 (PositiveMatchResult pmr in resultStack) { if (rpRow.Source.IsIntersecting(pmr.Source)) { ignore = true; break; } if (!ignore) { IList <PositiveMatchResult> tempResultStack = new List <PositiveMatchResult>(resultStack); tempResultStack.Add(rpRow); if (depth < (AG.OrderedMembers.Count - 1)) { ProcessAnd(AG, processResult, depth + 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.OrderedMembers[depth], resultStack, false); IList <Fact> excludedFacts = new List <Fact>(); foreach (PositiveMatchResult pmr in resultStack) { if (((Atom)AG.OrderedMembers[depth]).IsIntersecting(pmr.Source)) { excludedFacts.Add(pmr.Fact); } } // then get the matching facts IEnumerator results = ProcessAtom(atomToRun, excludedFacts); if (results != null) { while (results.MoveNext()) { Fact result = (Fact)results.Current; IList <PositiveMatchResult> tempResultStack = new List <PositiveMatchResult>(resultStack); tempResultStack.Add(new PositiveMatchResult((Atom)AG.OrderedMembers[depth], result)); if (depth < (AG.OrderedMembers.Count - 1)) { ProcessAnd(AG, processResult, depth + 1, tempResultStack); } else { processResult.Add(tempResultStack); } } } } }
protected abstract void WriteAtomGroup(XmlElement target, AtomGroup atomGroup);
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); } } } } }