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

246 lines
6.5 KiB
Python
Raw Normal View History

2017-09-06 02:15:22 +01:00
import os.path
import sys
import keyword
# debugging support.
# import pdb
from collections import namedtuple
2018-02-26 21:38:19 +00:00
import readline
2017-11-08 09:29:01 +00:00
from .yap import *
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-01-27 10:17:27 +00:00
if self_contained:
2017-11-08 09:29:01 +00:00
yap_lib_path = os.path.dirname(__file__)
2017-11-09 12:14:41 +00:00
args.setYapShareDir(os.path.join(yap_lib_path, "prolog"))
2017-11-08 09:29:01 +00:00
args.setYapLibDir(yap_lib_path)
2017-11-09 12:14:41 +00:00
args.setSavedState(os.path.join(yap_lib_path, "startup.yss"))
YAPEngine.__init__(self, args)
self.goal(set_prolog_flag('verbose', 'silent'))
self.goal(use_module(library('yapi')))
self.goal(set_prolog_flag('verbose', 'normal'))
2017-09-06 02:15:22 +01:00
def run(self, g, m=None):
if m:
self.mgoal(g, m)
else:
self.goal(g)
def f(self, g):
self.E.fun(g)
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-02-26 21:38:19 +00:00
class Goal(object):
"""Goal is a predicate instantiated under a specific environment """
def __init__(self, g, engine, module="user",program=None, max_answers=None ):
self.g = g
2017-09-06 02:15:22 +01:00
self.e = engine
def __iter__(self):
2018-02-26 21:38:19 +00:00
return PrologTableIter( self.e, self.g )
2017-09-06 02:15:22 +01:00
class PrologTableIter:
2018-02-26 21:38:19 +00:00
def __init__(self, e, query):
2017-09-06 02:15:22 +01:00
try:
self.e = e
2018-02-26 21:38:19 +00:00
self.q = e.query(python_query(self, query))
2017-09-06 02:15:22 +01:00
except:
print('Error')
def __iter__(self):
# Iterators are iterables too.
2018-02-26 21:38:19 +00:00
# - # Adding this functions to make them so.
2017-09-06 02:15:22 +01:00
return self
2018-02-26 21:38:19 +00:00
def __next__(self):
if not self.q:
raise StopIteration()
2017-09-06 02:15:22 +01:00
if self.q.next():
2018-02-26 21:38:19 +00:00
rc = self.q.bindings
if self.q.port == "exit":
self.close()
return rc
2017-09-06 02:15:22 +01:00
else:
2018-02-26 21:38:19 +00:00
if self.q:
self.close()
2017-09-06 02:15:22 +01:00
raise StopIteration()
2018-02-26 21:38:19 +00:00
def close(self):
self.q.close()
self.q = None
2017-11-08 09:29:01 +00:00
f2p = {"fails":{}}
2017-09-06 02:15:22 +01:00
for i in range(16):
2017-11-08 09:29:01 +00:00
f2p[i] ={}
2017-09-06 02:15:22 +01:00
global engine, handler
yap_lib_path = os.path.dirname(__file__)
use_module = namedtuple('use_module', 'file')
bindvars = namedtuple('bindvars', 'list')
library = namedtuple('library', 'list')
v = namedtuple( 'v', 'slot')
yap_query = namedtuple( 'yap_query', 'query owner')
jupyter_query = namedtuple( 'jupyter_query', 'vars dict')
python_query = namedtuple( 'python_query', 'vars dict')
yapi_query = namedtuple( 'yapi_query', 'vars dict')
show_answer = namedtuple( 'show_answer', 'vars dict')
set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value')
2017-11-08 09:29:01 +00:00
def named( name, arity):
try:
if arity > 0 and name.isidentifier() and not keyword.iskeyword(name):
s = []
for i in range(arity):
s += ["A" + str(i)]
f2p[arity][name] = namedtuple(name, s)
except:
f2p[fails][name] = True
class PrologPredicate( YAPPrologPredicate ):
""" Interface to Prolog Predicate"""
2017-09-06 02:15:22 +01:00
class v(YAPVarTerm):
def __init__(self):
super().__init__()
def binding(self):
return self.term()
def numbervars( q ):
Dict = {}
if True:
engine.goal(show_answer( q.namedVars(), Dict))
return Dict
rc = q.namedVarsVector()
q.r = 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
class YAPShell:
2018-02-26 21:38:19 +00:00
def query_prolog(self, engine, query):
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
# pdb.set_trace()
# #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
do_ask = True
2018-02-26 21:38:19 +00:00
self.e = engine
bindings = []
if not self.q:
self.it = PrologTableIter( self.e, query )
for bind in self.it:
bindings += [bind]
2017-09-06 02:15:22 +01:00
if do_ask:
2018-02-26 21:38:19 +00:00
print(bindings)
bindings = []
2017-09-06 02:15:22 +01:00
s = input("more(;), all(*), no(\\n), python(#) ?").lstrip()
2018-02-26 21:38:19 +00:00
else:
s = ";"
if s.startswith(';') or s.startswith('y'):
continue
elif s.startswith('#'):
try:
exec(s.lstrip('#'))
except:
raise
elif s.startswith('*') or s.startswith('a'):
do_ask = False
continue
else:
break
if self.q:
self.os = query
if bindings:
return True,bindings
2017-09-06 02:15:22 +01:00
print("No (more) answers")
2018-02-26 21:38:19 +00:00
return False, None
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:
loop = False
else:
self.query_prolog(engine, s)
except SyntaxError as err:
print("Syntax Error error: {0}".format(err))
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):
self.live(engine)
def main():
engine = Engine()
handler = numbervars
YAPShell(engine)
if __name__ == "__main__":
main()