Input and output¶
Python streams (io.StringIO, files, sys.stdout, ...) are accepted wherever logic code reads or
writes: by parsers, and by solvers' input and output channels.
See also: Read and write streams.
Solvers write on Python's sys.stdout by default, so output appears in the notebook:
In [1]:
Copied!
from tuprolog.solve.prolog import prolog_solver
prolog_solver().solve_once("write('Hello from Prolog!'), nl").is_yes
from tuprolog.solve.prolog import prolog_solver
prolog_solver().solve_once("write('Hello from Prolog!'), nl").is_yes
Hello from Prolog!
Out[1]:
True
Output can be captured in a Python stream instead, and input read from one (read/1 comes with IOLib, see below):
In [2]:
Copied!
import io
from tuprolog.solve.libs import IOLib
output = io.StringIO()
solver = prolog_solver(libraries=IOLib, std_in=io.StringIO("likes(bart, skate). "), std_out=output)
solver.solve_once("read(T), write(got(T)), nl")
output.getvalue()
import io
from tuprolog.solve.libs import IOLib
output = io.StringIO()
solver = prolog_solver(libraries=IOLib, std_in=io.StringIO("likes(bart, skate). "), std_out=output)
solver.solve_once("read(T), write(got(T)), nl")
output.getvalue()
Out[2]:
'got(likes(bart, skate))\n'
Theories can be read from files (or any text stream):
In [3]:
Copied!
import os
import tempfile
from tuprolog.theory.parsing import read_theory
with tempfile.NamedTemporaryFile("w", suffix=".pl", delete=False) as file:
file.write("color(red). color(green). color(blue).\n")
try:
with open(file.name) as source:
colors = read_theory(source)
finally:
os.remove(file.name)
list(prolog_solver(static_kb=colors).query("color(C)"))
import os
import tempfile
from tuprolog.theory.parsing import read_theory
with tempfile.NamedTemporaryFile("w", suffix=".pl", delete=False) as file:
file.write("color(red). color(green). color(blue).\n")
try:
with open(file.name) as source:
colors = read_theory(source)
finally:
os.remove(file.name)
list(prolog_solver(static_kb=colors).query("color(C)"))
Out[3]:
[{'C': 'red'}, {'C': 'green'}, {'C': 'blue'}]
IOLib¶
IOLib (used above for read/1) adds ISO Prolog's stream predicates (open/3, read/2,
write/2, close/1, ...), so Prolog code can manage files on its own, naming them by URIs for portability:
In [4]:
Copied!
from pathlib import Path
path = Path(tempfile.mkdtemp(), "out.txt")
solver = prolog_solver(libraries=IOLib)
# IOLib opens files by URI (e.g. file:///tmp/out.txt), which works on every OS
solver.solve_once(f"open('{path.as_uri()}', write, S), write(S, hello(world)), nl(S), close(S)")
print(path.read_text())
path.unlink()
from pathlib import Path
path = Path(tempfile.mkdtemp(), "out.txt")
solver = prolog_solver(libraries=IOLib)
# IOLib opens files by URI (e.g. file:///tmp/out.txt), which works on every OS
solver.solve_once(f"open('{path.as_uri()}', write, S), write(S, hello(world)), nl(S), close(S)")
print(path.read_text())
path.unlink()
hello(world)