Пример #1
0
        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");
        }
Пример #2
0
        /// <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&lt;IList&lt;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());
        }
Пример #3
0
        /// <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));
        }
Пример #4
0
        /// <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
Пример #5
0
        /// <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&lt;IList&lt;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());
        }
Пример #6
0
        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
Пример #7
0
 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);
     }
 }
Пример #8
0
 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);
     }
 }
Пример #9
0
 protected override void WriteAtomGroup(XmlElement target, AtomGroup atomGroup)
 {
     WriteAtomGroup(target, atomGroup, "And", "Or");
 }
Пример #10
0
        /// <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);
                        }
                    }
                }
            }
        }
Пример #11
0
 protected abstract void WriteAtomGroup(XmlElement target, AtomGroup atomGroup);
Пример #12
0
        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);
                        }
                    }
                }
            }
        }