This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/python/swig/yap4py/yapi.py

235 lines
6.8 KiB
Python
Raw Normal View History

2018-02-26 21:38:19 +00:00
import readline
2018-03-18 00:44:08 +00:00
from yap4py.yap import *
2018-03-17 10:38:56 +00:00
from os.path import join, dirname
from collections import namedtuple
import sys
yap_lib_path = dirname(__file__)
bindvars = namedtuple('bindvars', 'list')
2018-07-21 01:56:48 +01:00
compile = namedtuple('compile', 'file')
2018-03-17 10:38:56 +00:00
jupyter_query = namedtuple('jupyter_query', 'vars dict')
2018-07-21 01:56:48 +01:00
library = namedtuple('library', 'listfiles')
prolog_library = namedtuple('prolog_library', 'listfiles')
2018-03-17 10:38:56 +00:00
python_query = namedtuple('python_query', 'vars dict')
set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value')
2018-07-21 01:56:48 +01:00
show_answer = namedtuple('show_answer', 'vars dict')
v0 = namedtuple('v', 'slot')
yap_query = namedtuple('yap_query', 'query owner')
yapi_query = namedtuple('yapi_query', 'vars dict')
2017-09-06 02:15:22 +01:00
class Engine( YAPEngine ):
2017-11-09 12:14:41 +00:00
2018-01-27 10:17:27 +00:00
def __init__(self, args=None,self_contained=False,**kwargs):
2017-09-06 02:15:22 +01:00
# type: (object) -> object
if not args:
args = EngineArgs(**kwargs)
2018-07-31 15:18:56 +01:00
args.setEmbedded(True)
2018-01-27 10:17:27 +00:00
if self_contained:
2018-03-17 10:38:56 +00:00
yap_lib_path = dirname(__file__)
args.setYapShareDir(join(yap_lib_path, "prolog"))
2018-03-02 21:18:24 +00:00
args.setYapPLDIR(yap_lib_path)
2018-03-17 10:38:56 +00:00
args.setSavedState(join(yap_lib_path, "startup.yss"))
2017-11-09 12:14:41 +00:00
YAPEngine.__init__(self, args)
2018-07-21 01:56:48 +01:00
self.run(compile(library('yapi')),m="user",release=True)
2017-09-06 02:15:22 +01:00
2018-05-25 12:30:31 +01:00
def run(self, g, m=None, release=False):
2017-09-06 02:15:22 +01:00
if m:
2018-05-26 00:22:27 +01:00
self.mgoal(g, m, release)
2017-09-06 02:15:22 +01:00
else:
2018-07-21 01:56:48 +01:00
self.goal(g, release)
2017-09-06 02:15:22 +01:00
2018-07-21 01:56:48 +01:00
def prolog_library(self, file):
g = prolog_library(file)
self.run(g)
2018-07-10 23:21:19 +01:00
class JupyterEngine( Engine ):
def __init__(self, args=None,self_contained=False,**kwargs):
# type: (object) -> object
if not args:
args = EngineArgs(**kwargs)
args.jupyter = True
Engine.__init__(self, args)
2018-07-17 11:43:57 +01:00
self.errors = None
2018-07-24 20:18:41 +01:00
try:
self.run(compile(library('jupyter')),"user")
self.run(compile(library('complete')),"user")
self.run(compile(library('verify')),"user")
except:
pass
2018-07-10 23:21:19 +01:00
2017-09-06 02:15:22 +01:00
class EngineArgs( YAPEngineArgs ):
""" Interface to Engine Options class"""
def __init__(self, args=None,**kwargs):
super().__init__()
class Predicate( YAPPredicate ):
""" Interface to Generic Predicate"""
2018-02-26 21:38:19 +00:00
def __init__(self, t, module=None):
super().__init__(t)
2017-09-06 02:15:22 +01:00
2018-05-31 00:15:48 +01:00
class Query (YAPQuery):
2018-02-26 21:38:19 +00:00
"""Goal is a predicate instantiated under a specific environment """
2018-03-02 21:18:24 +00:00
def __init__(self, engine, g):
2018-05-31 00:15:48 +01:00
super().__init__(g)
2018-05-29 09:59:28 +01:00
self.engine = engine
2018-05-31 00:15:48 +01:00
self.port = "call"
2017-09-06 02:15:22 +01:00
def __iter__(self):
return self
2018-12-16 02:21:54 +00:00
def done(self):
return self.port == "fail" or self.port == "exit"
2018-02-26 21:38:19 +00:00
def __next__(self):
2018-12-16 02:21:54 +00:00
self.answer = {}
if self.port == "fail" or self.port == "exit":
raise StopIteration()
if self.next():
return self.answer
raise StopIteration()
2018-06-01 08:37:25 +01:00
2018-03-17 10:38:56 +00:00
def name( name, arity):
2017-11-08 09:29:01 +00:00
try:
2018-03-17 10:38:56 +00:00
if arity > 0 and name.isidentifier(): # and not keyword.iskeyword(name):
2017-11-08 09:29:01 +00:00
s = []
for i in range(arity):
s += ["A" + str(i)]
2018-03-17 10:38:56 +00:00
return namedtuple(name, s)
2017-11-08 09:29:01 +00:00
except:
2018-03-17 10:38:56 +00:00
return None
2017-11-08 09:29:01 +00:00
class PrologPredicate( YAPPrologPredicate ):
""" Interface to Prolog Predicate"""
2018-03-17 10:38:56 +00:00
class v(YAPVarTerm,v0):
2017-09-06 02:15:22 +01:00
def __init__(self):
2018-03-17 10:38:56 +00:00
YAPVarTerm.__init__()
2017-09-06 02:15:22 +01:00
def binding(self):
return self.term()
class YAPShell:
2018-05-25 12:30:31 +01:00
2018-03-17 10:38:56 +00:00
def numbervars( self ):
Dict = {}
2018-05-26 00:22:27 +01:00
self.engine.goal(show_answer( self, Dict), True)
2018-03-17 10:38:56 +00:00
return Dict
# rc = self.q.namedVarsVector()
# self.q.r = self.q.goal().numbervars()
# o = []
# for i in rc:
# if len(i) == 2:
# do = str(i[0]) + " = " + str( i[1] ) + "\n"
# o += do
# else:
# do = str(i[0]) + " = " + str( i[1] ) + "\n"
# o += do
# return o
def query_prolog(self, query):
2018-05-25 12:30:31 +01:00
g = None
2018-03-02 21:18:24 +00:00
#import pdb; pdb.set_trace()
2017-09-06 02:15:22 +01:00
#
# construct a query from a one-line string
# q is opaque to Python
#
2018-02-26 21:38:19 +00:00
#q = engine.query(python_query(self, s))
2017-09-06 02:15:22 +01:00
#
# # vs is the list of variables
# you can print it out, the left-side is the variable name,
# the right side wraps a handle to a variable
2018-12-16 02:21:54 +00:00
# import pdb; pdb.set_trace()
2017-09-06 02:15:22 +01:00
# #pdb.set_trace()
# atom match either symbols, or if no symbol exists, sttrings, In this case
# variable names should match strings
#for eq in vs:
# if not isinstance(eq[0],str):
# print( "Error: Variable Name matches a Python Symbol")
# return
2018-03-24 22:56:52 +00:00
try:
engine = self.engine
2018-12-16 02:21:54 +00:00
bindings = []
2018-03-24 22:56:52 +00:00
loop = False
2018-12-16 02:21:54 +00:00
q = Query( engine, python_query( engine, query) )
for answer in q:
bindings += [answer]
if g.done():
return bindings
2018-03-24 22:56:52 +00:00
if loop:
continue
2018-05-30 21:54:12 +01:00
s = input("more(;), all(*), no(\\n), python(#)? ").lstrip()
2018-03-24 22:56:52 +00:00
if s.startswith(';') or s.startswith('y'):
continue
elif s.startswith('#'):
try:
exec(s.lstrip('#'))
except:
raise
elif s.startswith('*') or s.startswith('a'):
loop = True
continue
else:
break
2018-05-25 12:30:31 +01:00
if self.q:
2018-05-29 09:59:28 +01:00
self.q.close()
2018-05-30 08:12:51 +01:00
self.q = None
2018-03-24 22:56:52 +00:00
print("No (more) answers")
2018-12-16 02:21:54 +00:00
return bindings
2018-03-26 11:03:08 +01:00
except Exception as e:
2018-05-25 12:30:31 +01:00
if not self.q:
2018-05-24 12:00:10 +01:00
return False, None
2018-05-29 09:59:28 +01:00
self.q.close()
2018-05-30 08:12:51 +01:00
self.q = None
print("Exception",e)
e.errorNo = 0
2018-05-30 13:07:45 +01:00
raise
2017-09-06 02:15:22 +01:00
def live(self, engine, **kwargs):
loop = True
2018-02-26 21:38:19 +00:00
self.q = None
2017-09-06 02:15:22 +01:00
while loop:
try:
s = input("?- ")
if not s:
2018-05-30 08:12:51 +01:00
continue
2017-09-06 02:15:22 +01:00
else:
2018-03-17 10:38:56 +00:00
self.query_prolog(s)
2017-09-06 02:15:22 +01:00
except SyntaxError as err:
print("Syntax Error error: {0}".format(err))
2018-05-30 13:07:45 +01:00
continue
2017-09-06 02:15:22 +01:00
except EOFError:
return
except RuntimeError as err:
print("YAP Execution Error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
engine.close()
#
# initialize engine
# engine = yap.YAPEngine();
# engine = yap.YAPEngine(yap.YAPParams());
#
def __init__(self, engine, **kwargs):
2018-03-17 10:38:56 +00:00
self.engine = engine
2018-05-24 21:45:38 +01:00
2018-03-17 10:38:56 +00:00
self.live(engine)
2018-05-24 12:00:10 +01:00
self.q = None
2017-09-06 02:15:22 +01:00
def main():
engine = Engine()
YAPShell(engine)
if __name__ == "__main__":
main()