pyswip
pyswip copied to clipboard
Atom names changed when querying lists
I'm Using Python 3.7.4, Pyswip from PIP. There seems to be a problem with Prolog atom names in lists.
Prolog code:
problem(Board) :-
Board = [black].
Python code:
prolog = Prolog()
prolog.consult("main.pl")
print(list(prolog.query("problem(X)")))
returns:
[{'X': [Atom('413701')]}]
If I change [black]. to black, it works OK.
Hello,
A good starting point is to format your result, as seen at https://github.com/targodan/jupyter-swi-prolog/blob/master/jswipl/swipl.py.
from pyswip import Prolog
from pyswip import Functor
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
prolog = Prolog()
prolog.consult("main.pl")
answer = list(prolog.query("problem(X)"))
print(format_result(answer))
returns:
X = [ black ] .
@yuce maybe this should be included on pyswip, or be better documented.
Best, Theodore
Thanks for this code. But it returns a string, that looks like a Python list in its content, but it's not a Python list.
I would expect it to return a list of strings.
I.e.,
X = ['black']
Based on @MitsiCash 's answer, I'm using this code:
def atoms_to_strings(answer):
if isinstance(answer, dict):
result = {}
for k in answer.keys():
result[k] = atoms_to_strings(answer[k])
elif isinstance(answer, list):
result = [atoms_to_strings(val) for val in answer]
elif isinstance(answer, Atom):
result = answer.value
elif isinstance(answer, int) or isinstance(answer, str):
result = answer
else:
print("Unsupported result from Prolog: " + str(type(answer)) + str(answer))
return result
I assume it might help others as well, @yuce , please incorporate this, or something similar.
Thanks