yuce / pyswip

PySwip is a Python-Prolog interface that enables querying SWI-Prolog in your Python programs.
https://pyswip.org
MIT License
482 stars 98 forks source link

How to access and edit knowledge base entries? #113

Closed marekyggdrasil closed 1 month ago

marekyggdrasil commented 3 years ago

This is a question from a total beginner in Prolog.

I know knowledge base entries or facts can be created as follows,

https://github.com/yuce/pyswip/blob/1ad3ce2d3fa4263273655f12bd9c4be07de2bd04/examples/father.py#L35-L37

I'm wondering how to edit the knowledge base, i.e change the facts.

For instance, I create variable Position and assign it a value 4

from pyswip import Prolog
prolog = Prolog()

prolog.assertz('Position := 4')

What is the best way to extract the value of Position? The way I found is

for soln in prolog.query("X := Position"):
    print('Position is', soln['Position'])

which outputs

Position is 4

but it seems a bit strange because I am creating a new variable to access an existing variable. Let's say now I want this value to be different, for instance I already run my queries and now I want Position to be 8

from pyswip import Prolog
prolog = Prolog()

prolog.assertz('Position := 4')
for soln in prolog.query("X := Position"):
    print('Position is', soln['Position'])

print('assigning a new value')
prolog.assertz('Position := 8')

for soln in prolog.query("X := Position"):
    print('Position is', soln['Position'])

which outputs

Position is 4
assigning a new value
Position is 4
Position is 8

so now Position takes two values, both 4 and 8. I can imagine why, probably Prolog is just storing what is true and I indicated the true statement for both values... Is there a way to ensure variable takes only one value that can be changed?

marekyggdrasil commented 3 years ago

Regarding editing entries

Once a value has been chosen for a variable, it cannot be altered by subsequent code; however, if the remainder of the clause cannot be satisfied, Prolog may backtrack and try another value for that variable.

ref: A Concise Introduction to Prolog - Variables section.

I supposed instead of assigning a new values rather would need to create a new instance of Prolog and run all the statements again apart from assigning value to Position variable and just assign a different value to it. Then actually it is no longer a variable but a constant.