Skip to content

Instantly share code, notes, and snippets.

@hsk
Created December 20, 2018 14:37
Show Gist options
  • Select an option

  • Save hsk/da22273c05e25358f2eee25921de585d to your computer and use it in GitHub Desktop.

Select an option

Save hsk/da22273c05e25358f2eee25921de585d to your computer and use it in GitHub Desktop.
Jupyter-Lab SWI-Prolog change files
from pyswip import Prolog
from pyswip import Functor
from pyswip.prolog import PrologError
DEFAULT_LIMIT = 10
ini = False
def init(prolog):
global ini
if ini: return prolog
ini = True
prolog.assertz("""get_labapp(A) :- retract(outs(A))""")
prolog.assertz("""(?- V) :- setup_call_cleanup((
retractall(outs(_)),
new_memory_file(H),
open_memory_file(H,write,O),
set_output(O)
),call(V),(
close(O),
memory_file_to_atom(H,A),
free_memory_file(H),
asserta(outs(A))
))""")
return prolog
def format_value(value):
output = ""
if isinstance(value, list):
output = "[ " + ", ".join([format_value(val) for val in value]) + " ]"
elif isinstance(value, Functor) and value.arity == 2:
output = "{0}{1}{2}".format(value.args[0], value.name, value.args[1])
else:
output = "{}".format(value)
return output
def format_result(result):
result = list(result)
if len(result) == 0:
return "false."
if len(result) == 1 and len(result[0]) == 0:
return "true."
output = ""
for res in result:
tmpOutput = []
for var in res:
tmpOutput.append(var + " = " + format_value(res[var]))
output += ", ".join(tmpOutput) + " ;\n"
output = output[:-3] + " ."
return output
def run(code):
prolog = Prolog()
output = []
ok = True
tmp = ""
isQuery = False
for line in code.split("\n"):
line = line.strip()
if line == "" or line[0] == "%":
continue
if line[:2] == "?-":
isQuery = True
#line = line[2:]
tmp += " " + line
if tmp[-1] == ".":
# End of statement
tmp = tmp[:-1] # Removes "."
maxresults = DEFAULT_LIMIT
# Checks for maxresults
if tmp[-1] == "}":
tmp = tmp[:-1] # Removes "."
limitStart = tmp.rfind('{')
if limitStart == -1:
ok = False
output.append("ERROR: Found '}' before '.' but opening '{' is missing!")
else:
limit = tmp[limitStart+1:]
try:
maxresults = int(limit)
except:
ok = False
output.append("ERROR: Invalid limit {" + limit + "}!")
tmp = tmp[:limitStart]
try:
if isQuery:
result = init(prolog).query(tmp, maxresult=maxresults)
res=format_result(result)
result.close()
result2=prolog.query("get_labapp(R)")
res2=list(result2)[0]["R"]
result2.close()
if len(res2)>0 and res2[-1] != "\n": res2 += "\n"
output.append(res2+res)
else:
prolog.assertz('(' + tmp + ')')
except PrologError as error:
ok = False
output.append("ERROR: {}".format(error))
tmp = ""
isQuery = False
return output, ok
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment