class lambeq.pregroups.TextDiagramPrinter(word_spacing: int = 2, discopy_types: bool = False, compress_layers: bool = True, use_ascii: bool = False)[source]

Bases: object

A text printer for pregroup diagrams.

ASCII_CHAR_SET: dict[str, str] = {'BAR': '|', 'BOTTOM_L_CORNER': '\\', 'BOTTOM_R_CORNER': '/', 'DOT': ' ', 'LINE': '_', 'TOP_L_CORNER': '\xa0', 'TOP_R_CORNER': '\xa0'}
UNICODE_CHAR_SET: dict[str, str] = {'BAR': '│', 'BOTTOM_L_CORNER': '╰', 'BOTTOM_R_CORNER': '╯', 'DOT': '·', 'LINE': '─', 'TOP_L_CORNER': '╭', 'TOP_R_CORNER': '╮'}
__init__(word_spacing: int = 2, discopy_types: bool = False, compress_layers: bool = True, use_ascii: bool = False) None[source]

Initialise a text diagram printer.

word_spacingint, default: 2

The number of spaces between the words of the diagrams.

discopy_typesbool, default: False

Whether to represent types in DisCoPy form (using @ as the monoidal product).

compress_layersbool, default: True

Whether to draw boxes in the same layer when they can occur simultaneously, otherwise, draw one box per layer.

use_ascii: bool, default: False

Whether to draw using ASCII characters only, for compatibility reasons.

diagram2str(diagram: discopy.rigid.Diagram) str[source]

Produces a string that contains a graphical representation of the input diagram using text characters. The diagram is expected to be in pregroup form, i.e. all words must precede morphisms.

diagram: :py:class:`discopy.rigid.Diagram`

The diagram to be printed.


String that contains the graphical representation of the diagram.


If input is not a pregroup diagram.

draw_layer(layer: list[_Morphism], wires: dict[int, int]) list[str][source]
lambeq.pregroups.create_pregroup_diagram(words: list[Word], cod: Ty, morphisms: list[tuple[type, int, int]]) Diagram[source]

Create a discopy.rigid.Diagram from cups and swaps.

>>> n, s = Ty('n'), Ty('s')
>>> words = [Word('she', n), Word('goes', n.r @ s @ n.l),
...          Word('home', n)]
>>> morphisms = [(Cup, 0, 1), (Cup, 3, 4)]
>>> diagram = create_pregroup_diagram(words, Ty('s'), morphisms)
wordslist of discopy.grammar.pregroup.Word

A list of Word s corresponding to the words of the sentence.


The output type of the diagram.

morphisms: list of tuple[type, int, int]
A list of tuples of the form:

(morphism, start_wire_idx, end_wire_idx).

Morphisms can be Cup s or Swap s, while the two numbers define the indices of the wires on which the morphism is applied.


The generated pregroup diagram.


If the provided morphism list does not type-check properly.

lambeq.pregroups.diagram2str(diagram: discopy.rigid.Diagram, word_spacing: int = 2, discopy_types: bool = False, compress_layers: bool = True, use_ascii: bool = False) str[source]

Produces a string that graphically represents the input diagram with text characters, without the need of first creating a printer. For specific arguments, see the constructor of the TextDiagramPrinter class.

lambeq.pregroups.is_pregroup_diagram(diagram: discopy.rigid.Diagram) bool[source]

Check if a diagram is a pregroup diagram.

Adapted from discopy.grammar.pregroup.draw.


The diagram to be checked.


Whether the diagram is a pregroup diagram.

lambeq.pregroups.remove_cups(diagram: discopy.rigid.Diagram) discopy.rigid.Diagram[source]

Remove cups from a discopy.rigid.Diagram.

Diagrams with less cups become circuits with less post-selection, which results in faster QML experiments.


The diagram from which cups will be removed.


Diagram with some cups removed.

lambeq.pregroups.remove_swaps(diagram: discopy.rigid.Diagram) discopy.rigid.Diagram[source]

Produce a proper pregroup diagram by removing any swaps.

Direct conversion of a CCG derivation into a string diagram form may introduce swaps, caused by cross-composition rules and unary rules that may change types and the directionality of composition at any point of the derivation. This method removes swaps, producing a valid pregroup diagram (in J. Lambek’s sense) as follows:

  1. Eliminate swap morphisms by swapping the actual atomic types of the words.

  2. Scan the new diagram for any detached parts, and remove them by merging words together when possible.


The input diagram.


A copy of the input diagram without swaps.


If the input diagram is not in DisCoPy’s “pregroup” form, i.e. when words do not strictly precede the morphisms.


The method trades off diagrammatic simplicity and conformance to a formal pregroup grammar for a larger vocabulary, since each word is associated with more types than before and new words (combined tokens) are added to the vocabulary. Depending on the size of your dataset, this might lead to data sparsity problems during training.


In the following example, “am” and “not” are combined at the CCG level using cross composition, which introduces the interwoven pattern of wires.

I       am            not        sleeping
─  ───────────  ───────────────  ────────
n  n.r·s·s.l·n  s.r·n.r.r·n.r·s   n.r·s
│   │  │  │  ╰─╮─╯    │    │  │    │  │
│   │  │  │  ╭─╰─╮    │    │  │    │  │
│   │  │  ╰╮─╯   ╰─╮──╯    │  │    │  │
│   │  │  ╭╰─╮   ╭─╰──╮    │  │    │  │
│   │  ╰──╯  ╰─╮─╯    ╰─╮──╯  │    │  │
│   │        ╭─╰─╮    ╭─╰──╮  │    │  │
│   ╰────────╯   ╰─╮──╯    ╰╮─╯    │  │
│                ╭─╰──╮    ╭╰─╮    │  │
╰────────────────╯    ╰─╮──╯  ╰────╯  │
                      ╭─╰──╮          │
                      │    ╰──────────╯

Applying the remove_swaps() method will return:

I     am not    sleeping
─  ───────────  ────────
n  n.r·s·s.l·n   n.r·s
╰───╯  │  │  ╰────╯  │
       │  ╰──────────╯

removing the swaps and combining “am” and “not” into one token.