102 lines
2.9 KiB
Python
102 lines
2.9 KiB
Python
|
|
||
|
import yap
|
||
|
import sys
|
||
|
# debugging support.
|
||
|
import pdb
|
||
|
|
||
|
def query_prolog(engine, s):
|
||
|
|
||
|
def answer(q):
|
||
|
try:
|
||
|
return q.next()
|
||
|
except Exception as e:
|
||
|
print(e.args[1])
|
||
|
return False
|
||
|
|
||
|
#
|
||
|
#construct a query from a one-line string
|
||
|
# 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
|
||
|
vs = q.namedVars()
|
||
|
# 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
|
||
|
ask = True
|
||
|
# launch the query
|
||
|
while answer(q):
|
||
|
# this new vs should contain bindings to vars
|
||
|
vs= q.namedVars()
|
||
|
#numbervars
|
||
|
i=0
|
||
|
# iteratw
|
||
|
for eq in vs:
|
||
|
name = eq[0]
|
||
|
# 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
|
||
|
binding = yap.T(eq[1])
|
||
|
if binding.isVar():
|
||
|
binding.unify(name)
|
||
|
else:
|
||
|
i = binding.numberVars(i, True)
|
||
|
print(name + " = " + binding.text())
|
||
|
#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():
|
||
|
engine = yap.YAPEngine()
|
||
|
loop = True
|
||
|
pdb.set_trace()
|
||
|
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());
|
||
|
#live()
|