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

121 lines
3.4 KiB
Python
Raw Normal View History

2017-05-02 03:34:56 +01:00
import yap
2017-05-02 07:38:23 +01:00
import os.path
2017-05-02 03:34:56 +01:00
import sys
# debugging support.
import pdb
2017-05-02 07:38:23 +01:00
from collections import namedtuple
yap_lib_path = os.path.dirname(__file__)
use_module = namedtuple( 'use_module', 'file')
bindvars = namedtuple( 'bindvars', 'list')
library = namedtuple( 'library', 'list')
v = namedtuple( '_', 'slot')
def numbervars( engine, l ):
return engine.fun(bindvars(l))
2017-05-02 03:34:56 +01:00
def query_prolog(engine, s):
def answer(q):
try:
return q.next()
except Exception as e:
print(e.args[1])
return False
#
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
q = engine.query(s)
# 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-02 03:34:56 +01:00
vs = q.namedVars()
2017-05-02 07:38:23 +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-05-02 03:34:56 +01:00
ask = True
# launch the query
while answer(q):
# this new vs should contain bindings to vars
vs= q.namedVars()
2017-05-02 07:38:23 +01:00
print( vs )
gs = numbervars( engine, vs)
print(gs)
2017-05-02 03:34:56 +01:00
i=0
2017-05-02 07:38:23 +01:00
# iterate
for eq in gs:
2017-05-02 03:34:56 +01:00
name = eq[0]
2017-05-02 07:38:23 +01:00
binding = eq[1]
2017-05-02 03:34:56 +01:00
# this is tricky, we're going to bind the variables in the term so thay we can
# output X=Y. The Python way is to use dictionares.
#Instead, we use the T function to tranform the Python term back to Prolog
2017-05-02 07:38:23 +01:00
if name != binding:
print(name + " = " + str(binding))
2017-05-02 03:34:56 +01:00
#ok, that was Prolog code
print("yes")
# deterministic = one solution
if q.deterministic():
# done
q.close()
return
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
def live():
2017-05-02 07:38:23 +01:00
args = yap.YAPEngineArgs()
args.setYapLibDir(yap_lib_path)
args.setYapShareDir(yap_lib_path)
#args.setYapPrologBootFile(os.path.join(yap_lib_path."startup.yss"))
engine = yap.YAPEngine( args )
engine.goal( use_module( library('yapi') ) )
2017-05-02 03:34:56 +01:00
loop = True
while loop:
try:
s = input("?- ")
if not s:
loop = False
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());
2017-05-02 07:38:23 +01:00
live()