Re: Accessing PowerLoom from Haskell

Anders NĂ¥sell <[email protected]> Fri, 28 Aug 2015 09:44:55 +0200
Newsgroups gmane.comp.ai.powerloom
Message-ID <[email protected]>
Hans,
Thanks for your reply.

1. Has PowerLoom a C API? I thought it only had C++? That is good news beca=
use my understanding is that Haskell is easier to interface with C than C++.

1b. I have experimented with this solution and appends some Haskell code at=
 the end of this mail, starting a =

PowerLoom process and communicate with it over a pseudo terminal. This migh=
t be a path for initial experimenting but i think a C binding would be bett=
er if this is to be used.

...

4. Ok, so I guess that it would require one of Haskells object systems, if =
they would cover the case, but
I suppose it would not be terse idiomatic Haskell and therefor perhaps brin=
gs no advantages over a C binding.

CODE FOR 1b

module Main where                                                          =
     =

import System.IO                                                           =
     =

import System.Process                                                      =
     =

import Control.Monad                                                       =
     =

import System.Posix.Terminal                                               =
     =

import System.Posix.IO                                                     =
     =

import Control.Applicative                                                 =
     =

import Control.Exception                                                   =
     =

                                                                           =
     =

initPowerLoom :: IO (Handle, ProcessHandle)                                =
     =

initPowerLoom =3D do                                                       =
       =

-- create a pseudo terminal                                                =
     =

    (master, slave) <- openPseudoTerminal                                  =
     =

-- stop echoing                                                            =
     =

    slaveattr <- flip withoutMode EnableEcho <$> getTerminalAttributes slav=
e    =

    setTerminalAttributes slave slaveattr Immediately                      =
     =

-- convert file descriptors to values of type Handle                       =
     =

    hMaster <- fdToHandle master                                           =
     =

    hSlave <- fdToHandle slave                                             =
     =

-- create a PowerLoom subprocess. powerloom must be in the PATH            =
     =

    (_, _, _, phPowerLoom) <-                                              =
     =

        createProcess (proc "powerloom" [])                                =
     =

           { std_in  =3D UseHandle hSlave                                  =
       =

           , std_out =3D UseHandle hSlave                                  =
       =

           , std_err =3D UseHandle hSlave                                  =
       =

           }                                                               =
     =

-- read init text                                                          =
     =

    readToPowerLoomPrompt hMaster ""                                       =
     =

    return (hMaster, phPowerLoom)                                          =
     =

                                                                           =
     =

                                                                           =
     =

exitPowerLoom :: (Handle, ProcessHandle) -> IO ()                          =
     =

exitPowerLoom (h, ph) =3D do                                               =
       =

    hPutStrLn h "exit"                                                     =
     =

    hPutStrLn h "yes"                                                      =
     =

    e <- waitForProcess ph                                                 =
     =

    putStrLn (show e)                                                      =
     =

    hClose h                                                               =
     =

                                                                           =
     =

withPowerLoom :: ((Handle, ProcessHandle) -> IO ()) -> IO ()               =
     =

withPowerLoom =3D bracket initPowerLoom exitPowerLoom                      =
       =

                                                                           =
     =

readToPowerLoomPrompt :: Handle -> String -> IO String                     =
     =

-- read until PowerLoom prompt, |=3D                                       =
       =

readToPowerLoomPrompt h str =3D do                                         =
       =

  c <- hGetChar h                                                          =
     =

  if c =3D=3D '|' then do                                                  =
         =

      c2 <- hGetChar h                                                     =
     =

      if c2 =3D=3D '=3D'                                                   =
           =

        then return (reverse (c:c2:str))                                   =
     =

        else (readToPowerLoomPrompt h (c:c2:str))                          =
     =

    else (readToPowerLoomPrompt h (c:str))                                 =
     =

                                                                           =
     =

runPowerLoomCommand :: Handle -> String -> IO String                       =
     =

runPowerLoomCommand h str =3D do                                           =
       =

-- write to pseudo terminal                                                =
     =

    hPutStrLn h str                                                        =
     =

    readToPowerLoomPrompt h ""                                             =
     =

                                                                           =
     =

main =3D do                                                                =
       =

  withPowerLoom $ \ (hMaster, _) -> do                                     =
     =

    runPowerLoomCommand hMaster "(defconcept person)"                      =
     =

    runPowerLoomCommand hMaster "(assert (person Charlie))"                =
     =

    runPowerLoomCommand hMaster "(retrieve all (person ?p))" >>=3D putStrLn=
  =



Sincerely
Anders

Den 2015-08-20 23:41, Hans Chalupsky skrev:
> Anders,
> =

> what you found in the archive is basically correct.  Unfortunately, I don=
't know much about Haskell besides that it is a functional language, but he=
re are some pointers:
> =

> 1. If Haskell has a foreign function interface that allows you to call ei=
ther C, C++ or Java functions, then you can use that to call functions in t=
he PowerLoom API (PLI).  The Wikipedia page says that Haskell 2010 added a =
foreign function interface, so that might be a way to go.
> =

> 1b. If you are working in Linux/Unix, and Haskell has a way to easily spa=
wn Unix subprocesses that can be communicated with via their IO streams, yo=
u can spawn a Unix process that runs the PowerLoom read/eval/print loop, an=
d you can then send input expressions and read results from your Haskell pa=
rent process.
> =

> 2. There is a simple TCP-based PowerLoom socket server in  powerloom-x.y.=
z/sources/logic/PowerLoomServer.java that you can play with.  This code is =
a bit old but should still work or should be easily fixable to make it work.
> =

> 3. The directory powerloom-x.y.z/sources/powerloom-server/plsoap/ contain=
s some documentation on how to setup and use the PowerLoom SOAP server
> =

> 4. Writing a STELLA to Haskell translator is probably the most involved o=
ption and only advisable if you have a use case that absolutely requires a =
pure-Haskell production system.  Unless Haskell has similar object-oriented=
 features such as C++ and Java, this would be a difficult way to go.
> =

> Some time ago, Mark Watson has written a JRuby wrapper for PowerLoom that=
 you could look at for inspiration (http://blog.markwatson.com/2007/10/more=
-fun-with-jruby-using-powerloom.html).  He also mentions Haskell on his web=
 page, so he might have some more suggestions on how to go about this.  Sim=
ply search for PowerLoom on his blog for some more PowerLoom-related info.
> =

> Hope that helps.  You can send me mail privately if you run into any road=
blocks with whatever approach you choose.
> =

> Hans
> =

> On 08/20/2015 12:59 AM, Anders N=E5sell wrote:
>> I am looking for ways to access PowerLoom from Haskell
>> and found a mail in the list:
>>
>> On Jun 17, 2008, at 7:55 PM, Rich Morin wrote:
>> 1.  Just create a combined application. ...
>> 2.  Use a tcp-stream based server. ...
>> 3.  You could use the PowerLoom SOAP server
>>
>> Is there a documentation of the tcp-stream based server protocol?
>>
>> I there a documentation of PowerLooms XML-SOAP API or
>> is the Java source code the place to look?
>>
>> And finally, since STELLA is transcompiled, would it
>> be possible to compile it to Haskell or are there any
>> conceptual differences between STELLA and Haskell that
>> would make it impossible or hard? If possible how many lines
>> of codes are the existing transcompilers? What was approximately
>> the effort in man hours for the existing transcompilers?
>>
>>
>>
>> _______________________________________________
>> powerloom-forum mailing list
>> [email protected]
>> http://mailman.isi.edu/mailman/listinfo/powerloom-forum
> =