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/yapi.py

218 lines
5.6 KiB
Python
Raw Normal View History

2017-05-02 03:34:56 +01:00
2017-05-02 07:38:23 +01:00
import os.path
2017-05-02 03:34:56 +01:00
import sys
# debugging support.
2017-05-19 09:56:37 +01:00
# import pdb
2017-05-02 07:38:23 +01:00
from collections import namedtuple
from yap import *
2017-07-01 23:25:22 +01:00
class Engine( YAPEngine ):
2017-07-01 23:25:22 +01:00
def __init__(self, args=None,**kwargs):
# type: (object) -> object
if not args:
2017-07-01 23:25:22 +01:00
args = EngineArgs(**kwargs)
yap_lib_path = os.path.dirname(__file__)
args.setYapShareDir(os.path.join(yap_lib_path,"prolog"))
args.setYapLibDir(yap_lib_path)
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') ) )
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"""
2017-07-01 23:25:22 +01:00
def __init__(self, args=None,**kwargs):
super().__init__()
2017-07-06 01:04:06 +01:00
class Predicate( YAPPredicate ):
""" Interface to Generic Predicate"""
2017-07-01 23:25:22 +01:00
class Predicate:
"""Goal is a predicate instantiated under a specific environment """
def __init__( self, name, args, module=None, engine = None):
self = namedtuple( name, args )
if module:
self.p = YAPPredicate( name, len(self), module )
else:
self.p = YAPPredicate( name, len(self) )
self.e = engine
2017-07-06 01:04:06 +01:00
2017-07-01 23:25:22 +01:00
def goals( self, engine):
self.e = engine
def __iter__(self):
return PrologTableIter(self.e, self.p)
def holds(self):
return self.e.run(self._make_())
class PrologTableIter:
def __init__(self, e, goal):
try:
self.e = e
self.q = e.YAPQuery(goal)
except:
print('Error')
def __iter__(self):
# Iterators are iterables too.
# Adding this functions to make them so.
return self
def next(self):
if self.q.next():
return goal
else:
self.q.close()
self.q = None
raise StopIteration()
2017-07-06 01:04:06 +01:00
class PrologPredicate( YAPPrologPredicate ):
""" Interface to Prolog Predicate"""
2017-07-06 01:04:06 +01:00
2017-06-05 13:06:12 +01:00
global engine, handler
2017-05-02 07:38:23 +01:00
yap_lib_path = os.path.dirname(__file__)
2017-06-05 13:06:12 +01:00
use_module = namedtuple('use_module', 'file')
bindvars = namedtuple('bindvars', 'list')
library = namedtuple('library', 'list')
v = namedtuple( 'v', 'slot')
2017-05-19 09:56:37 +01:00
yap_query = namedtuple( 'yap_query', 'query owner')
2017-06-05 13:06:12 +01:00
jupyter_query = namedtuple( 'jupyter_query', 'vars dict')
python_query = namedtuple( 'python_query', 'vars dict')
yapi_query = namedtuple( 'yapi_query', 'vars dict')
2017-06-06 12:47:59 +01:00
show_answer = namedtuple( 'show_answer', 'vars dict')
set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value')
2017-05-02 07:38:23 +01:00
2017-06-06 12:47:59 +01:00
def v():
return yap.YAPVarTerm()
2017-05-02 07:38:23 +01:00
2017-06-05 13:06:12 +01:00
def numbervars( q ):
Dict = {}
if True:
2017-06-06 12:47:59 +01:00
engine.goal(show_answer( q.namedVars(), Dict))
2017-06-05 13:06:12 +01:00
return Dict
rc = q.namedVarsVector()
q.r = q.goal().numbervars()
print( rc )
2017-05-14 11:36:09 +01:00
o = []
for i in rc:
2017-06-05 13:06:12 +01:00
if len(i) == 2:
do = str(i[0]) + " = " + str( i[1] ) + "\n"
o += do
print(do)
2017-05-14 11:36:09 +01:00
else:
2017-06-05 13:06:12 +01:00
do = str(i[0]) + " = " + str( i[1] ) + "\n"
o += do
print(do)
2017-05-14 11:36:09 +01:00
return o
2017-05-02 03:34:56 +01:00
2017-06-05 13:06:12 +01:00
def answer(q):
try:
2017-06-06 12:47:59 +01:00
v = q.next()
if v:
print( bindings )
return v
2017-06-05 13:06:12 +01:00
except Exception as e:
print(e.args[1])
return False
2017-05-02 03:34:56 +01:00
2017-06-05 13:06:12 +01:00
def query_prolog(engine, s):
2017-07-06 01:04:06 +01:00
# import pdb; pdb.set_trace()
2017-05-02 03:34:56 +01:00
#
2017-05-02 07:38:23 +01:00
# construct a query from a one-line string
2017-05-02 03:34:56 +01:00
# q is opaque to Python
2017-06-06 12:47:59 +01:00
bindings = {}
q = engine.query(python_query(s, bindings))
2017-05-02 03:34:56 +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
2017-05-02 07:38:23 +01:00
# pdb.set_trace()
2017-05-19 09:56:37 +01:00
# #pdb.set_trace()
2017-05-02 03:34:56 +01:00
# atom match either symbols, or if no symbol exists, sttrings, In this case
# variable names should match strings
2017-05-02 07:38:23 +01:00
#for eq in vs:
# if not isinstance(eq[0],str):
# print( "Error: Variable Name matches a Python Symbol")
# return
2017-06-06 12:47:59 +01:00
ask = True
2017-05-02 03:34:56 +01:00
# launch the query
while answer(q):
# deterministic = one solution
if q.deterministic():
# done
q.close()
2017-05-19 09:56:37 +01:00
return True, True
2017-05-02 03:34:56 +01:00
if ask:
s = input("more(;), all(*), no(\\n), python(#) ?").lstrip()
if s.startswith(';') or s.startswith('y'):
continue
elif s.startswith('#'):
try:
exec(s.lstrip('#'))
except:
raise
elif s.startswith('*') or s.startswith('a'):
ask = False
continue
else:
break
print("No (more) answers")
q.close()
return
2017-05-14 11:36:09 +01:00
def live(**kwargs):
2017-05-02 03:34:56 +01:00
loop = True
while loop:
try:
s = input("?- ")
if not s:
loop = False
2017-05-08 18:51:29 +01:00
else:
query_prolog(engine, s)
2017-05-02 03:34:56 +01:00
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());
2017-05-08 18:51:29 +01:00
#
#
2017-07-01 23:25:22 +01:00
def boot_yap(**kwargs):
2017-07-06 01:04:06 +01:00
return Engine(**kwargs)
2017-05-08 18:51:29 +01:00
if __name__ == "__main__":
2017-06-05 13:06:12 +01:00
engine = boot_yap()
handler = numbervars
live()