Haskell

From OpenCog
Jump to: navigation, search

The page reviews the Haskell bindings for OpenCog.

You can find the main code in: /opencog/haskell

For in depth information on the implementation and project details: Haskell Bindings - GSoC 2015

For Haddock documentation: opencog-atomspace-0.1.0.0

Requirements

To use the Haskell bindings, it is necessary to have installed:

To install Stack, you should follow Download instructions.

Or you can use the octool tool, installing dependencies (octool -d).

Installation

To check if you have proper ghc version installed. Run:

cd <ATOMSPACE_ROOT>/opencog/haskell
stack setup

Then, go through the normal process of building[1] and installing[2] the AtomSpace.

This will automatically build the haskell library.

If you want to use this library in some project you should include it to the package list on the project stack.yaml config file. For example:

 ...
 packages:
 - <ATOMSPACE_ROOT>/opencog/haskell
 ...

On the other hand, if you simply want to compile some code using this library, you should compile with:

export STACK_YAML=<ATOMSPACE_ROOT>/opencog/haskell/stack.yaml
stack ghc example.hs

For using ghci:

export STACK_YAML=<ATOMSPACE_ROOT>/opencog/haskell/stack.yaml
stack ghci

Or, to avoid defining STACK_YAML every time, you can include this library to your local environment, adding this library path to your package list in your local config file: ~/.stack/global/stack.yaml ,and then running:

stack install opencog-atomspace

Then you can compile simple .hs files with:

stack ghc example.hs

Possible errors

  • It is necessary to previously build and install the AtomSpace, because the opencog-atomspace haskell library depends on the haskell-atomspace C wrapper library.

So, if you have a problem like "haskell-atomspace library not found" , first of all, you should ensure it was properly installed when installing the AtomSpace.

  • If when running "stack ghc" or "stack build" you get an error about "Missing C library: haskell-atomspace", you should add the flag:
 --extra-lib-dir=/usr/local/lib/opencog (with proper library location).
  • If when running "stack ghci" you get an error about "lhaskell-atomspace not found", you should add the flags:
 --ghc-options -lhaskell-atomspace
  • If when using "stack ghci" you see that ghci is interpreting the code: "[..] Compiling ... (..., interpreted )"

Then, a better option is to compile the package to object code, so it is loaded, which runs faster. All you have to do is to execute only one time:

stack ghci --ghc-options -fobject-code

On future uses, ghci will automatically load the compiled package.

  • If you find problems when building haskell libraries. One good option is to remove the directory:
<ATOMSPACE_ROOT>/opencog/haskell/.stack-work

It is automatically created when building, and sometimes becomes inconsistent.

Initial Implementation

Haskell bindings are composed of:

  • atomspace-cwrapper: a shared library, C wrapper for the atomspace main class. It is built and installed like all the atomspace libraries.
  • opencog-atomspace: a haskell package that links with the haskell-atomspace library and offers an API for haskell programming on the atomspace.

Usage

To use the opencog-atomspace haskell library, we just import the modules like:

  import OpenCog.AtomSpace
  ...

Examples

You can find many examples in : /examples/haskell

Documentation

Haddock documentation is available online on: opencog-atomspace-0.1.0.0

To generate proper Haddock documentation on your own, you should go to the build directory and execute:

 make doxygen

Then you can open the OpenCog documentation (build/doc/html/index.html), go to "OpenCog source code documentation - Libraries - Haskell bindings library" and click on the "opencog-atomspace" link.

NOTE: Documentation can be REALLY useful. There you can see the complete definition of Haskell bindings, including data types that are automatically generated by template haskell, and are not available in the code.

AtomSpace Environment

The main idea is to build programs that work on an AtomSpace on the Monad 'AtomSpace'.

Then, we can run this programs with the function runOnNewAtomSpace:

  runOnNewAtomSpace :: AtomSpace a -> IO a

It creates a new C++ atomspace behind, does all the computation, and finally deletes it.

Note that AtomSpace is an instance of the type class: MonadIO.

So, we can lift IO actions inside the monad AtomSpace, through the use of liftIO.

For example:

  import OpenCog.AtomSpace.Api
  import Control.Monad.IO.Class

  prog :: AtomSpace ()
  prog = do
           liftIO $ putStrLn "hello world"
           ...

  main :: IO ()
  main = runOnNewAtomSpace prog

Multiple AtomSpaces

The simplest option to work in an AtomSpace is to use runOnNewAtomSpace as mentioned before.

By doing that, you can work freely in the monad AtomSpace and you don't have to specify the atomspace instance everytime, because it is implicit.

But, sometimes, you want to work with multiples atomspaces, or maybe you want to do interactive evaluation using GHCi.

For that, you can create new AtomSpaces (from a optionally given parent atomspace) with the function:

  newAtomSpace :: Maybe AtomSpaceObj -> IO AtomSpaceObj

To work over an atomspace, you can use the infix operator <:

  (<:) :: AtomSpaceObj -> AtomSpace a -> IO a

For example:

  main :: IO ()
  main = do
      parentAS <- newAtomSpace Nothing
      childAS  <- newAtomSpace (Just parentAS)
    
      parentAS <: insert (Node "ConceptNode" "GenConcept" noTv)
      childAS  <: do
          insert (Node "ConceptNode" "PrivateConcept1" (stv 1 1))
          insert (Node "ConceptNode" "PrivateConcept2" (stv 0.5 1))
      parentAS <: program
      childAS  <: debug
      parentAS <: remove (Node "ConceptNode" "GenConcept" noTv)

  program :: AtomSpace ()
  program = do
      s <- get (Node "ConceptNode" "GenConcept" noTv)
      ...

Atom type

Atom is the main data type to represent the different types of atoms.

Main functions:

insert

Function to insert atoms to the atomspace. To create new atoms or just to update the mutable information of a specific atom.

insert :: Atom -> AtomSpace ()

get

Function to get an atom back from the atomspace (With updated mutable information).

get :: Atom -> AtomSpace (Maybe Atom)

remove

Function to remove atoms from the atomspace.

remove :: Atom -> AtomSpace Bool

printAtom

Function to show the given atom in opencog notation.

printAtom :: Atom -> IO ()

debug

Debug function to print the state of the atomspace on stderr.

debug :: AtomSpace ()

cogBind

Function to use the Pattern Matcher. (Note: Before using it, you should insert the bind link to the atomspace).

cogBind :: Atom -> AtomSpace (Maybe Atom)

evaluate

Used to evaluate things like a SatisfactionLink. (Note: Before using it, you should insert the atom into the atomspace).

evaluate :: Atom -> AtomSpace (Maybe TruthVal)

execute

Used to execute any kind of FunctionLink. (Note: Before using it, you should insert the atom into the atomspace).

execute :: Atom -> AtomSpace (Maybe Atom)

See Also