Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atom names changed when querying lists #65

Open
ZvikaZ opened this issue Oct 3, 2019 · 3 comments
Open

Atom names changed when querying lists #65

ZvikaZ opened this issue Oct 3, 2019 · 3 comments

Comments

@ZvikaZ
Copy link

ZvikaZ commented Oct 3, 2019

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.

@tmitsi
Copy link

tmitsi commented Oct 4, 2019

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

@ZvikaZ
Copy link
Author

ZvikaZ commented Oct 24, 2019

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']

@ZvikaZ
Copy link
Author

ZvikaZ commented Oct 27, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants