0
votes

I am trying to use python's (3.8) subprocess library to communicate with swipl (Prolog interpreter). (I'm using MAC OSx)

More about Prolog: https://www.swi-prolog.org

Online Prolog interpreter: https://swish.swi-prolog.org

I want to be able to load a bunch of facts and rules into the knowledge base. Separately I want the ability to ask multiple questions in the interpreter and then receive the answer.

I've already tried the communicate function, but it doesn't fulfill the requirement of being able to send and receive data multiple times since the communication line is close after the first call.

Right now when I run the program I think it loads in the write and then when it gets to the stdout.read() it runs the line and then stalls out. Not sure exactly what is going on and how I can get the output of the calls.

import os
import signal
import subprocess

# NOTE: stderr=subprocess.PIPE makes the swipl intro in terminal go away
p = subprocess.Popen('swipl', stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, universal_newlines=True)
# The communicate() method returns a tuple (stdoutdata, stderrdata).

p.stdin.write('assert(car(honda, 18000, red)).')
p.stdin.write('assert(car(toyota, 18000, white)).')
p.stdin.write('assert(car(ford, 25000, red)).')
p.stdin.write('assert(car(acura, 50000, white)).')
p.stdin.write('assert(car(bmw, 60000, red)).')
p.stdin.write('[user]. recommendcar(Age, Car) :- Age =< 25, car(Car, Cost, red), Cost =< 30000 .')
p.stdin.write('recommendcar(20, X).')
output = p.stdout.read()
print(output)

p.kill()
1
You may have already found this, but just in case: pyswip a Python - SWI-Prolog bridge. - Paul Brown
Thanks Paul! I was using that originally, but I had lots of errors setting it up. So my teacher recommended me to use this - Jonathan Ishii
also too many issues using pyswip with Flask and python. Apparently pyswip does not play nicely in multi threading - Benny Abramovici

1 Answers

0
votes

Try:

p.stdin.write('assertz(car(honda, 18000, red)).')
p.stdin.write('assertz(car(toyota, 18000, white)).')
p.stdin.write('assertz(car(ford, 25000, red)).')
p.stdin.write('assertz(car(acura, 50000, white)).')
p.stdin.write('assertz(car(bmw, 60000, red)).')
p.stdin.write('assertz((recommendcar(Age, Car) :- Age =< 25, car(Car, Cost, red), Cost =< 30000)).')
p.stdin.write('recommendcar(20, X).')