Output from Prolog to Python
Updated 08 Oct 2002
Upper levels:
Amzi Python Interface 0.2...
4. Manual

 4.4. Output from Prolog to Python

 [ Prev - Up - Next ] 

This can be achieved in two ways. The first is by calling Python from Prolog. For example you might have a Python function 'writeToWindow'; then the code:

  ...
  python(writeToWindow(S))
  ...
would pass S to the Python-defined function writeToWindow.

The other is by redirecting the output of the Prolog write and nl predicates. If nothing is done, the output of these predicates will go to the DOS window that Python was called from (I haven't figured out how to make it go to an IDLE window yet).

Or the engine method .setOutput() can be used, whose argument is some callable object taking a single parameter that can do something with the output. For example:

eng.setOutput(<outputfunc>)

This might be an instance of a class with a call method:

class OutputBuffer:
    def __init__(self):
        self.text=""

    def __call__(self,txt):
    #
    # Python string operations seem to involve massive
    # copying, perhaps something more efficient could be
    # worked put for long sequences of appends that would
    # produce fill up large buffers, such as reallocate
    # a new buffer twice as big whenever the old one fills
    # up (what Python does for lists).  Or something. 
    # Anyway the use of a format string is supposed to 
    # be much faster than '+', according to Grayson
    # (Tkinter book).
    #
        self.text="%s%s"%(self.text,txt)

    def clear(self):
        self.text=""

  .
  .
  .

output = OutputBuffer()
eng.setOutput(output)
Code for a Python file illustrating this method can be found in Tests/testoutput.py

This can be made a bit slicker by subclassing AmziEngine so that its constructor takes an output function as an optional argument:

class MyEngine(AmziProlog.AmziEngine):

    def __init__ (self, initfiles, output=None):
        AmziProlog.AmziEngine.__init__(self, initfiles)
        self.output = output
        if output is not None:
            self.setOutput(output)

    def spill(self):
        print self.output.text
This is also illustrated in Tests/testoutput.py.

This would allow an unlimited number of engines, each with its own output function. Unfortunately, I don't know how to make it so that an attribute can be added freely to a C-defined class such as AmziEngine, only to a Python-defined subclass thereof.

The Amzi lsapi's support input redirection as well as output redirection, but I haven't impemented this because my applications don't need it (they're not Prolog listeners), and I have no sense of what the requirements for a good general solution would be.


 [ Prev - Top - Next ]