Skip to main content

Distributional Compositional Python

Project description

snake equation

Distributional Compositional Python

readthedocs Build Status codecov pylint Score PyPI version

discopy computes natural language meaning in pictures.

Features

Diagrams & Recipes

Diagrams are the core data structure of discopy, they are generated by the following grammar:

diagram ::= Box(name, dom=type, cod=type)
    | diagram @ diagram
    | diagram >> diagram
    | Id(type)

type ::= Ty(name) | type.l | type.r | type @ type | Ty()

Mathematically, string diagrams (also called tensor networks or Penrose notation) are a graphical calculus for computing the arrows of the free monoidal category. For example, if we take ingredients as types and cooking steps as boxes then a diagram is a recipe:

from discopy import Ty, Box, Id

egg, white, yolk = Ty('egg'), Ty('white'), Ty('yolk')
crack = Box('crack', egg, white @ yolk)
swap = lambda x, y: Box('swap', x @ y, y @ x)
merge = lambda x: Box('merge', x @ x, x)

crack_two_eggs = crack @ crack\
    >> Id(white) @ swap(yolk, white) @ Id(yolk)\
    >> merge(white) @ merge(yolk)
crack_two_eggs.draw()

crack two eggs

Snakes & Words

There are two special kinds of boxes that allows to bend wires and draw snakes: cups and caps, which satisfy the snake equations or triangle identities. That is, discopy diagrams are the arrows of the free rigid monoidal category, up to diagram.normal_form().

from discopy import Cup, Cap

x = Ty('x')
left_snake = Id(x) @ Cap(x.r, x) >> Cup(x, x.r) @ Id(x)
right_snake =  Cap(x, x.l) @ Id(x) >> Id(x) @ Cup(x.l, x)
assert left_snake.normal_form() == Id(x) == right_snake.normal_form()

In particular, discopy can draw the grammatical structure of natural language sentences given by reductions in a pregroup grammar, see Lambek (2008) for an introduction.

from discopy import pregroup, Word

s, n = Ty('s'), Ty('n')
Alice, Bob = Word('Alice', n), Word('Bob', n)
loves = Word('loves', n.r @ s @ n.l)

sentence = Alice @ loves @ Bob >> Cup(n, n.r) @ Id(s) @ Cup(n.l, n)
pregroup.draw(sentence)

snake equation

Functors & Meanings

Functors compute the meaning of a diagram, given a meaning for each box. As a special case, free functors (i.e. from the free monoidal category to itself) can fill in a box with a complex diagram.

love_box = Box('loves', n @ n, s)
love_ansatz = Cap(n.r, n) @ Cap(n, n.l) >> Id(n.r) @ love_box @ Id(n.l)
ob, ar = {s: s, n: n}, {Alice: Alice, Bob: Bob, loves: love_ansatz}
F = RigidFunctor(ob, ar)
F(sentence).to_gif('docs/imgs/autonomisation.gif')

autonomisation

Functors into the category of matrices evaluate a diagram as a tensor network using numpy or jax.numpy. Once applied to pregroup diagrams, this makes discopy an implementation of the compositional distributional (DisCo) models of Clark, Coecke, Sadrzadeh (2008).

import numpy as np
from discopy import MatrixFunctor

ob = {s: 1, n: 2}
ar = {Alice: [1, 0], loves: [0, 1, 1, 0], Bob: [0, 1]}
F = MatrixFunctor(ob, ar)

assert F(sentence) == np.array([1])

Getting Started

pip install discopy

Documentation

The documentation is hosted at readthedocs.io, you can also checkout the notebooks for a demo!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

discopy-0.2.tar.gz (31.3 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page