Basic Usage

This document will give an overview of how to use Penman as a tool and as a library. For motivation, here’s an example of its tool usage:

$ penman --indent 3 --compact <<< '(s / sleep :polarity - :ARG0 (i / i))'
(s / sleep :polarity -
   :ARG0 (i / i))

And here’s an example of its library usage:

>>> from penman import PENMANCodec
>>> codec = PENMANCodec()
>>> g = codec.decode('(s / sleep-01 :polarity - :ARG0 (i / i))')
>>> g.triples.remove(('s', ':polarity', '-'))
>>> print(PENMANCodec().encode(g))
(s / sleep-01
   :ARG0 (i / i))

Using Penman as a Tool

Once installed (see Installation and Setup), the penman command becomes available. It allows you to perform some basic tasks with PENMAN graphs without having to write any Python code. Run penman --help to get a synposis of its usage:

$ penman --help
usage: penman [-h] [-V] [-v] [-q] [--model FILE | --amr] [--indent N]
              [--compact] [--triples] [--rearrange KEY] [--canonicalize-roles]
              [--reify-edges] [--reify-attributes] [--indicate-branches]
              [FILE [FILE ...]]

Read and write graphs in the PENMAN notation.

positional arguments:
  FILE                  read graphs from FILEs instead of stdin

optional arguments:
  -h, --help            show this help message and exit
  -V, --version         show program's version number and exit
  -v, --verbose         increase verbosity
  -q, --quiet           suppress output on <stdout> and <stderr>
  --model FILE          JSON model file describing the semantic model
  --amr                 use the AMR model

formatting options:
  --indent N            indent N spaces per level ("no" for no newlines)
  --compact             compactly print node attributes on one line
  --triples             print graphs as triple conjunctions

normalization options:
  --rearrange KEY       sort or randomize the order of relations on each node
  --canonicalize-roles  canonicalize role forms
  --reify-edges         reify all eligible edges
  --reify-attributes    reify all attributes
  --indicate-branches   insert triples to indicate tree structure

The penman command can read input from stdin or from one or more files. Currently it always outputs to stdout. Options are available to customize the formatting of the output, such as for controlling indentation. Normalization options allow one to transform the graph in predefined ways prior to serialization. For example:

$ penman --amr --indent=3 --reify-edges <<< '(a / apple :quant 3)'
(a / apple
   :ARG1-of (_ / have-quant-91
      :ARG2 3))

Using Penman as a Library

While the command-line utility is convenient, it does not expose all the functionality that the Penman package has. For more sophisticated uses, the API allows one to directly inspect trees and graphs, construct and manipulate trees and graphs, further customize serialization, interface with other systems, etc.

For example:

>>> from penman import PENMANCodec
>>> codec = PENMANCodec()
>>> g = codec.decode('(b / bark-01 :ARG0 (d / dog))')
>>> g.attributes()
[Attribute(source='b', role=':instance', target='bark-01'), Attribute(source='d', role=':instance', target='dog')]
>>> g.edges()
[Edge(source='b', role=':ARG0', target='d')]
>>> g.variables()
{'d', 'b'}
>>> print(codec.encode(g, top='d'))
(d / dog
   :ARG0-of (b / bark-01))
>>> g.triples.append(('b', ':polarity', '-'))
>>> print(codec.encode(g))
(b / bark-01
   :ARG0 (d / dog)
   :polarity -)

Importing directly from the penman module allows for basic usage of the library, but anything more advanced can take advantage of the full API. See the API documentation for more information.