/// <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="SwiPrologException">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), "PrologQuery.NextSolution() _name is required"); Contract.Requires(!string.IsNullOrEmpty(_name), "PrologQuery.NextSolution() _name is required"); IntPtr p = libswipl.PL_predicate(_name, _av.Size, _module); var atom = libswipl.PL_new_atom_wchars(_module); IntPtr m = libswipl.PL_new_module(atom); libswipl.PL_unregister_atom(atom); _qid = libswipl.PL_open_query(m /* was IntPtr.Zero */, libswipl.PL_Q_CATCH_EXCEPTION, p, _av.A0); } int rval = libswipl.PL_next_solution(_qid); if (0 == rval) { // error uintptr_t ex; // term_t if ((ex = libswipl.PL_exception(_qid)) > 0) { _qid = 0; // to avoid an AccessViolationException on Dispose. E.g. if the query is mispelled. var etmp = new SwiPrologException(new SwiPrologTerm(ex)); etmp.Throw(); } } if (rval <= 0) { Free(false); } return(rval > 0); }
internal static void PL_close_query(uintptr_t qid) { if (IsValid) { SafeNativeMethods.PL_close_query(qid); } }
internal static void PL_close_foreign_frame(uintptr_t fid_t) { if (IsValid) { SafeNativeMethods.PL_close_foreign_frame(fid_t); } }
internal static string PL_atom_wchars(uintptr_t tAtom) { // see http://www.mycsharp.de/wbb2/thread.php?threadid=51100 int dummyLen = 0; return(Marshal.PtrToStringUni(SafeNativeMethods.PL_atom_wchars(tAtom, ref dummyLen))); }
/// <summary>called by Dispose</summary> private void Free() { if (_fid > 0 && libswipl.PL_is_initialised(IntPtr.Zero, IntPtr.Zero) != 0) { libswipl.PL_close_foreign_frame(_fid); } _fid = 0; }
internal static int PL_get_wchars(uintptr_t term, out string s, uint flags) { var dummyLen = 0; var ps = IntPtr.Zero; var iRet = SafeNativeMethods.PL_get_wchars(term, ref dummyLen, ref ps, flags); s = Marshal.PtrToStringUni(ps); return(iRet); }
/// <summary> /// Discards the query, but does not delete any of the data created by the query if discardData is false. /// It just invalidate qid, allowing for a new PlQuery object in this context. /// </summary> /// <remarks>see <see href="http://gollem.science.uva.nl/SWI-Prolog/Manual/foreigninclude.html#PL_cut_query()"/></remarks> /// <param name="discardData">if true all bindings of the query are destroyed</param> private void Free(bool discardData) { if (_qid > 0 && libswipl.PL_is_initialised(IntPtr.Zero, IntPtr.Zero) != 0) { try { if (discardData) { // <"leider werden dann die gebundenen variablen der query wieder frei e.g. in PlCall(goal)"/> // unfortunately this statement detaches the bound variables of the query e.g. in PlCall(goal) libswipl.PL_close_query(_qid); } else { libswipl.PL_cut_query(_qid); } } catch (AccessViolationException ex) { TraceAccessViolationException(ex); } } _qid = 0; }
internal static extern int PL_get_arg(int index, uintptr_t t, uintptr_t a);
internal static extern uintptr_t PL_exception(uintptr_t qid);
internal static extern int PL_unify(uintptr_t t1, uintptr_t t2);
internal static extern int PL_get_list(uintptr_t termL, uintptr_t termH, uintptr_t termT);
internal static extern int PL_unify_list(uintptr_t termL, uintptr_t termH, uintptr_t termT);
internal static extern int PL_is_number(uintptr_t term_t);
internal static extern int PL_wchars_to_term([In] string chars, uintptr_t term);
internal static extern int PL_cons_list(uintptr_t list, uintptr_t head, uintptr_t tail);
internal static extern int PL_is_list(uintptr_t term_t);
internal static extern int PL_is_atomic(uintptr_t term_t);
internal static extern void PL_cons_functor_v(uintptr_t term, uintptr_t functor_t, uintptr_t termA0);
internal static extern uintptr_t PL_copy_term_ref(uintptr_t term_t);
internal static extern uintptr_t PL_new_functor(uintptr_t atom, int a);
internal static extern int PL_unify_nil(uintptr_t term_t);
internal static extern int PL_is_variable(uintptr_t term_t);
internal static extern int PL_get_nil(uintptr_t term_t);
internal static extern int PL_is_string(uintptr_t term_t);
internal static extern int PL_unify_wchars(uintptr_t t1, int type, int len, string atom);
internal static extern int PL_is_integer(uintptr_t term_t);
internal static extern int PL_raise_exception(uintptr_t exceptionTerm);
internal static extern int PL_is_float(uintptr_t term_t);
internal static extern int PL_get_name_arity(uintptr_t t, ref uintptr_t name, ref int arity);
internal static extern int PL_is_compound(uintptr_t term_t);