Skip to content

Commit

Permalink
Some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
yuce committed Oct 27, 2024
1 parent cc850b2 commit d56528f
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 129 deletions.
169 changes: 57 additions & 112 deletions src/pyswip/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,8 +531,8 @@ def check_and_call(*args):
PL_version.restype = c_uint

PL_VERSION = PL_version(PL_VERSION_SYSTEM)
if PL_VERSION < 80200:
raise Exception("swi-prolog >= 8.2.0 is required")
if PL_VERSION < 80400:
raise Exception("swi-prolog >= 8.4.0 is required")
except AttributeError:
raise Exception("swi-prolog version number could not be determined")

Expand All @@ -548,103 +548,60 @@ def check_and_call(*args):
# /* PL_unify_term( arguments */


if PL_VERSION < 80200:
# constants (from SWI-Prolog.h)
# PL_unify_term() arguments
PL_VARIABLE = 1 # nothing
PL_ATOM = 2 # const char
PL_INTEGER = 3 # int
PL_FLOAT = 4 # double
PL_STRING = 5 # const char *
PL_TERM = 6 #
# PL_unify_term()
PL_FUNCTOR = 10 # functor_t, arg ...
PL_LIST = 11 # length, arg ...
PL_CHARS = 12 # const char *
PL_POINTER = 13 # void *
# /* PlArg::PlArg(text, type) */
# define PL_CODE_LIST (14) /* [ascii...] */
# define PL_CHAR_LIST (15) /* [h,e,l,l,o] */
# define PL_BOOL (16) /* PL_set_feature() */
# define PL_FUNCTOR_CHARS (17) /* PL_unify_term() */
# define _PL_PREDICATE_INDICATOR (18) /* predicate_t (Procedure) */
# define PL_SHORT (19) /* short */
# define PL_INT (20) /* int */
# define PL_LONG (21) /* long */
# define PL_DOUBLE (22) /* double */
# define PL_NCHARS (23) /* unsigned, const char * */
# define PL_UTF8_CHARS (24) /* const char * */
# define PL_UTF8_STRING (25) /* const char * */
# define PL_INT64 (26) /* int64_t */
# define PL_NUTF8_CHARS (27) /* unsigned, const char * */
# define PL_NUTF8_CODES (29) /* unsigned, const char * */
# define PL_NUTF8_STRING (30) /* unsigned, const char * */
# define PL_NWCHARS (31) /* unsigned, const wchar_t * */
# define PL_NWCODES (32) /* unsigned, const wchar_t * */
# define PL_NWSTRING (33) /* unsigned, const wchar_t * */
# define PL_MBCHARS (34) /* const char * */
# define PL_MBCODES (35) /* const char * */
# define PL_MBSTRING (36) /* const char * */

REP_ISO_LATIN_1 = 0x0000 # output representation
REP_UTF8 = 0x1000
REP_MB = 0x2000

else:
PL_VARIABLE = 1 # nothing
PL_ATOM = 2 # const char *
PL_INTEGER = 3 # int
PL_RATIONAL = 4 # rational number
PL_FLOAT = 5 # double
PL_STRING = 6 # const char *
PL_TERM = 7

PL_NIL = 8 # The constant []
PL_BLOB = 9 # non-atom blob
PL_LIST_PAIR = 10 # [_|_] term

# # PL_unify_term(
PL_FUNCTOR = 11 # functor_t, arg ...
PL_LIST = 12 # length, arg ...
PL_CHARS = 13 # const char *
PL_POINTER = 14 # void *
# PlArg::PlArg(text, type
PL_CODE_LIST = 15 # [ascii...]
PL_CHAR_LIST = 16 # [h,e,l,l,o]
PL_BOOL = 17 # PL_set_prolog_flag(
PL_FUNCTOR_CHARS = 18 # PL_unify_term(
_PL_PREDICATE_INDICATOR = 19 # predicate_t= Procedure
PL_SHORT = 20 # short
PL_INT = 21 # int
PL_LONG = 22 # long
PL_DOUBLE = 23 # double
PL_NCHARS = 24 # size_t, const char *
PL_UTF8_CHARS = 25 # const char *
PL_UTF8_STRING = 26 # const char *
PL_INT64 = 27 # int64_t
PL_NUTF8_CHARS = 28 # size_t, const char *
PL_NUTF8_CODES = 29 # size_t, const char *
PL_NUTF8_STRING = 30 # size_t, const char *
PL_NWCHARS = 31 # size_t, const wchar_t *
PL_NWCODES = 32 # size_t, const wchar_t *
PL_NWSTRING = 33 # size_t, const wchar_t *
PL_MBCHARS = 34 # const char *
PL_MBCODES = 35 # const char *
PL_MBSTRING = 36 # const char *
PL_INTPTR = 37 # intptr_t
PL_CHAR = 38 # int
PL_CODE = 39 # int
PL_BYTE = 40 # int
# PL_skip_list(
PL_PARTIAL_LIST = 41 # a partial list
PL_CYCLIC_TERM = 42 # a cyclic list/term
PL_NOT_A_LIST = 43 # Object is not a list
# dicts
PL_DICT = 44

REP_ISO_LATIN_1 = 0x0000 # output representation
REP_UTF8 = 0x00100000
REP_MB = 0x00200000
PL_VARIABLE = 1 # nothing
PL_ATOM = 2 # const char *
PL_INTEGER = 3 # int
PL_RATIONAL = 4 # rational number
PL_FLOAT = 5 # double
PL_STRING = 6 # const char *
PL_TERM = 7

PL_NIL = 8 # The constant []
PL_BLOB = 9 # non-atom blob
PL_LIST_PAIR = 10 # [_|_] term

# # PL_unify_term(
PL_FUNCTOR = 11 # functor_t, arg ...
PL_LIST = 12 # length, arg ...
PL_CHARS = 13 # const char *
PL_POINTER = 14 # void *
# PlArg::PlArg(text, type
PL_CODE_LIST = 15 # [ascii...]
PL_CHAR_LIST = 16 # [h,e,l,l,o]
PL_BOOL = 17 # PL_set_prolog_flag(
PL_FUNCTOR_CHARS = 18 # PL_unify_term(
_PL_PREDICATE_INDICATOR = 19 # predicate_t= Procedure
PL_SHORT = 20 # short
PL_INT = 21 # int
PL_LONG = 22 # long
PL_DOUBLE = 23 # double
PL_NCHARS = 24 # size_t, const char *
PL_UTF8_CHARS = 25 # const char *
PL_UTF8_STRING = 26 # const char *
PL_INT64 = 27 # int64_t
PL_NUTF8_CHARS = 28 # size_t, const char *
PL_NUTF8_CODES = 29 # size_t, const char *
PL_NUTF8_STRING = 30 # size_t, const char *
PL_NWCHARS = 31 # size_t, const wchar_t *
PL_NWCODES = 32 # size_t, const wchar_t *
PL_NWSTRING = 33 # size_t, const wchar_t *
PL_MBCHARS = 34 # const char *
PL_MBCODES = 35 # const char *
PL_MBSTRING = 36 # const char *
PL_INTPTR = 37 # intptr_t
PL_CHAR = 38 # int
PL_CODE = 39 # int
PL_BYTE = 40 # int
# PL_skip_list(
PL_PARTIAL_LIST = 41 # a partial list
PL_CYCLIC_TERM = 42 # a cyclic list/term
PL_NOT_A_LIST = 43 # Object is not a list
# dicts
PL_DICT = 44

REP_ISO_LATIN_1 = 0x0000 # output representation
REP_UTF8 = 0x00100000
REP_MB = 0x00200000

# /********************************
# * NON-DETERMINISTIC CALL/RETURN *
Expand Down Expand Up @@ -890,12 +847,6 @@ def PL_STRINGS_MARK():
PL_get_string_chars = _lib.PL_get_string
PL_get_string_chars.argtypes = [term_t, POINTER(c_char_p), c_int_p]

PL_get_chars = _lib.PL_get_chars # FIXME:
PL_get_chars.argtypes = [term_t, POINTER(c_char_p), c_uint]
PL_get_chars.restype = c_int

PL_get_chars = check_strings(None, 1)(PL_get_chars)

PL_get_integer = _lib.PL_get_integer
PL_get_integer.argtypes = [term_t, POINTER(c_int)]
PL_get_integer.restype = c_int
Expand Down Expand Up @@ -943,7 +894,6 @@ def PL_STRINGS_MARK():
PL_atom_chars.restype = c_char_p

PL_atom_wchars = _lib.PL_atom_wchars
PL_atom_wchars.argtypes = [atom_t, POINTER(c_size_t)]
PL_atom_wchars.restype = c_wchar_p

PL_predicate = _lib.PL_predicate
Expand Down Expand Up @@ -973,6 +923,7 @@ def PL_STRINGS_MARK():
PL_get_list.restype = c_int

PL_get_chars = _lib.PL_get_chars # FIXME
PL_get_wchars = _lib.PL_get_wchars

PL_close_query = _lib.PL_close_query
PL_close_query.argtypes = [qid_t]
Expand Down Expand Up @@ -1012,10 +963,6 @@ def PL_STRINGS_MARK():
PL_unify_atom.argtypes = [term_t, atom_t]
PL_unify_atom.restype = c_int

PL_unify_atom_chars = _lib.PL_unify_atom_chars
PL_unify_atom_chars.argtypes = [term_t, c_char_p]
PL_unify_atom_chars.restype = c_int

PL_unify_string_chars = _lib.PL_unify_string_chars
PL_unify_string_chars.argtypes = [term_t, c_char_p]
PL_unify_string_chars.restype = c_void_p
Expand Down Expand Up @@ -1174,8 +1121,6 @@ def PL_STRINGS_MARK():
PL_is_initialised = _lib.PL_is_initialised

intptr_t = c_long
ssize_t = intptr_t
wint_t = c_uint

PL_thread_self = _lib.PL_thread_self
PL_thread_self.restype = c_int
Expand Down
14 changes: 10 additions & 4 deletions src/pyswip/easy.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
PL_register_atom,
PL_atom_wchars,
PL_get_atom,
PL_get_wchars,
PL_unregister_atom,
PL_new_term_ref,
PL_compare,
Expand Down Expand Up @@ -72,6 +73,7 @@
PL_STRING,
PL_INTEGER,
PL_FLOAT,
PL_NIL,
PL_Q_NODEBUG,
PL_Q_CATCH_EXCEPTION,
PL_FA_NONDETERMINISTIC,
Expand All @@ -89,6 +91,7 @@
atom_t,
create_string_buffer,
c_char_p,
c_wchar_p,
functor_t,
c_int,
c_long,
Expand Down Expand Up @@ -120,7 +123,7 @@ def __init__(self, expected, got):
Exception.__init__(self, msg)


class Atom(object):
class Atom:
__slots__ = "handle", "chars"

def __init__(self, handleOrChars, chars=None):
Expand Down Expand Up @@ -306,7 +309,7 @@ def __hash__(self):
return self.handle


class Functor(object):
class Functor:
__slots__ = "handle", "name", "arity", "args", "__value", "a0"
func = {}

Expand Down Expand Up @@ -439,8 +442,9 @@ def putList(l, ls): # noqa: E741

def getAtomChars(t):
"""If t is an atom, return it as a string, otherwise raise InvalidTypeError."""
s = c_char_p()
if PL_get_chars(t, byref(s), CVT_ATOM | REP_UTF8):
s = c_wchar_p()
ln = c_size_t()
if PL_get_wchars(t, byref(ln), byref(s), CVT_ATOM | REP_UTF8):
return s.value
else:
raise InvalidTypeError("atom")
Expand Down Expand Up @@ -497,6 +501,8 @@ def getTerm(t):
p = PL_term_type(t)
if p < PL_TERM:
res = _getterm_router[p](t)
elif p == PL_NIL:
return []
elif PL_is_list(t):
res = getList(t)
elif p == PL_DICT:
Expand Down
14 changes: 14 additions & 0 deletions src/pyswip/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

__all__ = "PrologError", "NestedQueryError"

class PrologError(Exception):
pass


class NestedQueryError(PrologError):
"""
SWI-Prolog does not accept nested queries, that is, opening a query while the previous one was not closed.
As this error may be somewhat difficult to debug in foreign code, it is automatically treated inside PySwip
"""

pass
14 changes: 1 addition & 13 deletions src/pyswip/prolog.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
term_t,
control_t,
)
from pyswip.errors import PrologError, NestedQueryError


__all__ = "PrologError", "NestedQueryError", "Prolog"
Expand All @@ -67,19 +68,6 @@
RE_PLACEHOLDER = re.compile(r"%p")


class PrologError(Exception):
pass


class NestedQueryError(PrologError):
"""
SWI-Prolog does not accept nested queries, that is, opening a query while the previous one was not closed.
As this error may be somewhat difficult to debug in foreign code, it is automatically treated inside PySwip
"""

pass


def __initialize():
args = []
args.append("./")
Expand Down
1 change: 1 addition & 0 deletions tests/105.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prolog file with error
4 changes: 4 additions & 0 deletions tests/139.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:-op(800, fx, ¬).
:-op(802, xfy, ∨).

m_Proposition_Binary_x_y(XY, X, Y).
24 changes: 24 additions & 0 deletions tests/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import sys
import unittest

import pytest


class TestIssues(unittest.TestCase):
"""Each test method is named after the issue it is testing. The docstring
Expand Down Expand Up @@ -290,3 +292,25 @@ def test_functor_return(self):

soln = [s["Y"] for s in p.query("friend(john,Y), father(Y,kur)", maxresult=1)]
self.assertEqual(soln[0], "son(miki)")

@pytest.mark.skip("Skip until v0.3.3")
def test_issue_141(self):
from pyswip import Prolog
fixture = [
{"X": 1, "C": "x"},
{"X": 2, "C": "y"},
]
ls = list(Prolog.query("X = point{x:1,y:2}.C."))
self.assertEqual(fixture, ls)

@pytest.mark.skip("Skip until v0.3.3")
def test_issue_139(self):
from pyswip import Prolog
Prolog.consult("139.pl", relative_to=__file__)
list(Prolog.query(f"m_Proposition_Binary_x_y(∨(¬(p), q), A, B)."))

@pytest.mark.skip("Skip until v0.3.3")
def test_issue_105(self):
from pyswip import Prolog
self.assertRaises(Exception, lambda: Prolog.consult("105.pl", catcherrors=False))

0 comments on commit d56528f

Please sign in to comment.