예제 #1
0
        /// <summary>
        /// Provide the next solution to the query. Prolog exceptions are mapped to C# exceptions.
        /// </summary>
        /// <returns>return true if successful and false if there are no (more) solutions.</returns>
        /// <remarks>
        /// <para>If the query is closed it will be opened. If the last solution was generated the query will be closed.</para>
        /// <para>If an exception is thrown while parsing (open) the query the _qid is set to zero.</para>
        /// </remarks>
        /// <exception cref="PlException">Is thrown if <see href="http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_next_solution()">SWI-Prolog Manual PL_next_solution()</see> returns false </exception>
        public bool NextSolution()
        {
            if (0 == _qid)
            {
                Check.Require(!string.IsNullOrEmpty(_name), "PlQuery.NextSolution() _name is required");

                IntPtr p = LibPl.PL_predicate(_name, _av.Size, _module);
                _qid = LibPl.PL_open_query((IntPtr)0, LibPl.PL_Q_CATCH_EXCEPTION, p, _av.A0);
            }
            int rval = LibPl.PL_next_solution(_qid);

            if (0 == rval)
            {                 // error
                uintptr_t ex; // term_t
                if ((ex = LibPl.PL_exception(_qid)) > 0)
                {
                    _qid = 0;   // to avoid an AccessViolationException on Dispose. E.g. if the query is miss spelled.
                    var etmp = new PlException(new PlTerm(ex));
                    etmp.Throw();
                }
            }
            if (rval <= 0)
            {
                Free(false);
            }

            return(rval > 0);
        }
예제 #2
0
        private void CheckForException()
        {
            uint ex = libpl.PL_exception(_qid); // term_t

            if (ex > 0)
            {
                PlTerm      exceptionTerm = new PlTerm(ex);
                PlException etmp          = new PlException(exceptionTerm);
                _qid = 0; // to avoid an AccessViolationException on Dispose. E.g. if the query is miss spelled.
                etmp.Throw();
            }
        }