Skip to content

Commit

Permalink
Batch update
Browse files Browse the repository at this point in the history
  • Loading branch information
yuce committed May 20, 2018
1 parent 7b117c8 commit 0191582
Show file tree
Hide file tree
Showing 24 changed files with 124 additions and 746 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
__pycache__
*.swp
*.pyc
.coverage
*.BAC
.pytest_cache
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
language: python
python:
- "3.4"
- "3.5"
- "3.6"
- "nightly"
- "pypy"
sudo: required
before_install:
- sudo apt update && sudo apt install -y swi-prolog-nox
install:
- pip install test-requirements.txt coveralls
script:
- make cover
after_success:
- coveralls
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: cover test test-all

cover:
py.test --cov=pyswip tests integration_tests

test:
py.test tests --verbose

test-all:
py.test tests integration_tests --verbose
151 changes: 60 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,79 @@
PySWIP README
=============
# PySWIP README

:Version:
0.2.3
## What's New?

:Maintainer:
Rodrigo Starr <[email protected]>
* Updated

:Author:
Yuce Tekol <[email protected]>
Rodrigo Starr <[email protected]>

:Project Website:
http://code.google.com/p/pyswip

## Introduction

Introduction
------------

PySWIP is a Python - SWI-Prolog bridge enabling to query SWI-Prolog in your
Python programs. It features an (incomplete) SWI-Prolog foreign language
interface, a utility class that makes it easy querying with Prolog and also a
PySWIP is a Python - SWI-Prolog bridge enabling to query [SWI-Prolog](http://www.swi-prolog.org) in your Python programs.
It features an (incomplete) SWI-Prolog foreign language interface, a utility class that makes it easy querying with Prolog and also a
Pythonic interface.

Since PySWIP uses SWI-Prolog as a shared library and ctypes to access it, it
doesn't require compilation to be installed.

Note that this version of PySWIP is slightly incompatible with 0.1.x versions.

Requirements:
-------------
## Requirements:

* Python 2.3 and higher.
* ctypes 1.0 and higher.
* SWI-Prolog 5.6.x and higher (most probably other versions will also work).
* Python 3.5 and higher.
* SWI-Prolog 7.6.x and higher (most probably other versions will also work).
* libpl as a shared library.
* Works on Linux and Win32, should work for all POSIX.

Example (Using Prolog):
-----------------------

>>> from pyswip import Prolog
>>> prolog = Prolog()
>>> prolog.assertz("father(michael,john)")
>>> prolog.assertz("father(michael,gina)")
>>> list(prolog.query("father(michael,X)"))
[{'X': 'john'}, {'X': 'gina'}]
>>> for soln in prolog.query("father(X,Y)"):
... print soln["X"], "is the father of", soln["Y"]
...
michael is the father of john
michael is the father of gina

Since version 0.1.3 of PySWIP, it is possible to register a Python function as a
Prolog predicate through SWI-Prolog's foreign language interface.

Example (Foreign Functions):
----------------------------

from pyswip import Prolog, registerForeign

def hello(t):
print "Hello,", t
hello.arity = 1

registerForeign(hello)

prolog = Prolog()
prolog.assertz("father(michael,john)")
prolog.assertz("father(michael,gina)")
list(prolog.query("father(michael,X), hello(X)"))

Outputs:
Hello, john
Hello, gina

Since version 0.2, PySWIP contains a 'Pythonic' interface which allows writing
predicates in pure Python (*Note that interface is experimental.*)

Example (Pythonic interface):
-----------------------------

from pyswip import Functor, Variable, Query

assertz = Functor("assertz", 2)
father = Functor("father", 2)

call(assertz(father("michael","john")))
call(assertz(father("michael","gina")))

X = Variable()
q = Query(father("michael",X))
while q.nextSolution():
print "Hello,", X.value
q.closeQuery()

Outputs:
Hello, john
Hello, gina

The core functionality of ``Prolog.query`` is based on Nathan Denny's public
domain prolog.py found at
## Examples

### Using Prolog

```python
from pyswip import Prolog
prolog = Prolog()
prolog.assertz("father(michael,john)")
prolog.assertz("father(michael,gina)")
list(prolog.query("father(michael,X)")) == [{'X': 'john'}, {'X': 'gina'}]
for soln in prolog.query("father(X,Y)"):
print soln["X"], "is the father of", soln["Y"]
# michael is the father of john
# michael is the father of gina
```

### Foreign Functions

```python
from pyswip import Prolog, registerForeign
def hello(t):
print "Hello,", t
hello.arity = 1
registerForeign(hello)
prolog = Prolog()
prolog.assertz("father(michael,john)")
prolog.assertz("father(michael,gina)")
list(prolog.query("father(michael,X), hello(X)"))
```

### Pythonic interface (Experimental)

```python
from pyswip import Functor, Variable, Query
assertz = Functor("assertz", 2)
father = Functor("father", 2)
call(assertz(father("michael","john")))
call(assertz(father("michael","gina")))
X = Variable()
q = Query(father("michael",X))
while q.nextSolution():
print "Hello,", X.value
q.closeQuery()
# Outputs:
# Hello, john
# Hello, gina

```

The core functionality of ``Prolog.query`` is based on Nathan Denny's public domain prolog.py found at
http://www.ahsc.arizona.edu/~schcats/projects/docs/prolog-0.2.0.html

Install
-------
## Install

Please see ``INSTALL`` for detailed instructions.

4 changes: 2 additions & 2 deletions pyswip/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


# pyswip -- Python SWI-Prolog bridge
# Copyright (c) 2007-2012 Yüce Tekol
# Copyright (c) 2007-2018 Yüce Tekol
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -24,7 +24,7 @@


# PySWIP version
__VERSION__ = "0.2.3"
__VERSION__ = "0.3.0"

from pyswip.prolog import Prolog
from pyswip.easy import *
10 changes: 6 additions & 4 deletions pyswip/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


# pyswip -- Python SWI-Prolog bridge
# Copyright (c) 2007-2012 Yüce Tekol
# Copyright (c) 2007-2018 Yüce Tekol
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand All @@ -25,7 +25,6 @@
from __future__ import print_function

import os
import re
import sys
import glob
import warnings
Expand Down Expand Up @@ -158,6 +157,8 @@ def _findSwiplFromExec():


def _findSwiplWin():
import re

"""
This function uses several heuristics to gues where SWI-Prolog is installed
in Windows. It always returns None as the path of the resource file because,
Expand Down Expand Up @@ -303,9 +304,10 @@ def walk(path, name):


def get_swi_ver():
swi_ver = raw_input(
import re
swi_ver = input(
'Please enter you SWI-Prolog version in format "X.Y.Z": ')
match = re.match(r'[0-9]\.[0-9]\.[0-9]')
match = re.search(r'[0-9]\.[0-9]\.[0-9]')
if match is None:
raise InputError('Error, type normal version')

Expand Down
37 changes: 1 addition & 36 deletions pyswip/easy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


# pyswip.easy -- PySWIP helper functions
# Copyright (c) 2007-2012 Yüce Tekol
# Copyright (c) 2007-2018 Yüce Tekol
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -569,38 +569,3 @@ def closeQuery():
PL_close_query(Query.qid)
Query.qid = None
closeQuery = staticmethod(closeQuery)


def _test():
#from pyswip.prolog import Prolog
#p = Prolog()

#p = _prolog

assertz = Functor("assertz")
a = Functor("a_")
b = Functor("b_")

call(assertz(a(10)))
call(assertz(a([1,2,3])))
call(assertz(a(11)))
call(assertz(b(11)))
call(assertz(b(12)))

X = Variable()

#q = Query(a(X), ~b(X))
#q = Query(b(X), a(X))
#while q.nextSolution():
# print X.value
#print call(a(X),b(X))
#print call(_comma(~a(X),a(X)))
#q = Query(_comma(a(X), b(X)))
q = Query(a(X))
while q.nextSolution():
print(">", X.value)
q.closeQuery()

if __name__ == "__main__":
_test()

41 changes: 8 additions & 33 deletions pyswip/prolog.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def _initialize():
# result is a boolean variable (i.e. 0 or 1) indicating whether the
# initialisation was successful or not.
if not result:
raise PrologError("Could not initialize Prolog environment."
raise PrologError("Could not initialize the Prolog environment."
"PL_initialise returned %d" % result)

swipl_fid = PL_open_foreign_frame()
Expand Down Expand Up @@ -131,30 +131,31 @@ def __call__(self, query, maxresult, catcherrors, normalize):
PL_discard_foreign_frame(swipl_fid)
Prolog._queryIsOpen = False

@classmethod
def asserta(cls, assertion, catcherrors=False):
next(cls.query(assertion.join(["asserta((", "))."]), catcherrors=catcherrors))
asserta = classmethod(asserta)

@classmethod
def assertz(cls, assertion, catcherrors=False):
next(cls.query(assertion.join(["assertz((", "))."]), catcherrors=catcherrors))
assertz = classmethod(assertz)

@classmethod
def dynamic(cls, term, catcherrors=False):
next(cls.query(term.join(["dynamic((", "))."]), catcherrors=catcherrors))
dynamic = classmethod(dynamic)

@classmethod
def retract(cls, term, catcherrors=False):
next(cls.query(term.join(["retract((", "))."]), catcherrors=catcherrors))
retract = classmethod(retract)

@classmethod
def retractall(cls, term, catcherrors=False):
next(cls.query(term.join(["retractall((", "))."]), catcherrors=catcherrors))
retractall = classmethod(retractall)

@classmethod
def consult(cls, filename, catcherrors=False):
next(cls.query(filename.join(["consult('", "')"]), catcherrors=catcherrors))
consult = classmethod(consult)

@classmethod
def query(cls, query, maxresult=-1, catcherrors=True, normalize=True):
"""Run a prolog query and return a generator.
If the query is a yes/no question, returns {} for yes, and nothing for no.
Expand All @@ -170,31 +171,5 @@ def query(cls, query, maxresult=-1, catcherrors=True, normalize=True):
>>> print sorted(prolog.query("father(michael,X)"))
[{'X': 'gina'}, {'X': 'john'}]
"""
#assert cls.initialized
return cls._QueryWrapper()(query, maxresult, catcherrors, normalize)
query = classmethod(query)


def _test():
lines = [("assertz(father(michael,john)).","Michael is the father of John"),
("assertz(father(michael,gina)).","Michael is the father of Gina"),
("father(michael,john).","Is Michael father of John?"),
("father(michael,olivia).","Is Michael father of Olivia?"),
("father(michael,X).","Michael is the father of whom?"),
("father(X,Y).","Who is the father of whom?")]

prolog = Prolog()

for code, comment in lines:
print("?-", code, "[", comment, "]")
print(list(prolog.query(code)))

for r in prolog.query("father(X,Y)"):
print(r["X"], "is the father of", r["Y"])


if __name__ == "__main__":
#import doctest
#doctest.testmod()
_test()

Loading

0 comments on commit 0191582

Please sign in to comment.