Skip to main content

Setfield

PyPI - Version GitHub Actions Workflow Status Coverage Status License: MIT pre-commit

Setfield logo (a baseball field with bases numbered in von Neumann ordinal notation

Setfield is a small Python library providing a framework for expressing a field of sets construction. Also known as a (Boolean) set algebra, this represents the common notion of "overlapping subsets," with the ability to perform setwise operations like union, intersection, and complement.

Applications include:

  • Instantiating ontologies like a hierarchy of topics.
  • Writing domain-specific languages involving boolean operations.
  • Pedagogical applications to aid in learning predicate logic.

Two advantages of setfield over ordinary Python sets are:

  1. The presence of an ambient universe set makes the complement well-defined.
  2. Compositional constructs like union-of-ranges and boolean operators can be used to make set construction and membership querying more efficient in both time and memory.

Installation

The library is available on PyPI. To install:

pip install setfield

Usage

Suppose we have a collection (universe) of movies and want to organize them by genre, allowing some movies to belong to multiple genres. We can create a field of sets like so:

from setfield import Subset

movies = {
    'Alien',
    'Blade Runner',
    'Casablanca',
    'Dunkirk',
    'Frankenstein',
    'Her',
    'Interstellar',
    'The Shining',
}

# construct subsets
sci_fi = Subset(movies, {'Alien', 'Blade Runner', 'Her', 'Interstellar'})
horror = Subset(movies, {'Alien', 'Frankenstein', 'The Shining'})
romance = Subset(movies, {'Casablanca', 'Her', 'Interstellar'})

# check setwise relationships
assert sci_fi < movies
assert 'Her' in horror | romance
assert 'Frankenstein' in horror - sci_fi
assert sci_fi & horror == {'Alien'}
assert 'Dunkirk' in ~(sci_fi | horror | romance)

Parsing Boolean Expressions

We can also use setfield to create a miniature Domain-Specific Language (DSL) for boolean expressions with our custom field of sets. This is useful if we want to provide a way for users to express set combinations with a simple, natural syntax. Here's an example, continuing with movie genres:

from setfield import safe_eval_boolean_expr

genres = {
    'sci_fi': sci_fi,
    'horror': horror,
    'romance': romance,
}

def movies_for_genre(genre: str) -> Subset[str]:
    """Get the movies for a given genre, raising a ValueError if the genre is unknown."""
    if genre in genres:
        return genres[genre]
    raise ValueError(f'unknown genre: {genre}')

def interpret_genres(expr: str) -> Subset[str]:
    """Interpret a boolean expression involving genres."""
    return safe_eval_boolean_expr(expr, eval_name=movies_for_genre)


assert interpret_genres('sci_fi & horror') == {'Alien'}
assert interpret_genres('horror - sci_fi') == {'Frankenstein', 'The Shining'}
assert interpret_genres('~(sci_fi | horror | romance)') == {'Dunkirk'}

As the name suggests, safe_eval_boolean_expr is "safe" in that it will not execute arbitrary Python code—it evaluates names exclusively with the provided eval_name function and then applies boolean operations to the results.

Union of Ranges

If we're concerned with integer subsets, there is a RangeUnionSubset data structure which is often more efficient than a typical Subset (which stores all of its elements in a set). This consists of an ordered sequence of non-overlapping ranges, or [start, stop) pairs.

As an example:

from setfield import RangeUnionSubset

subset = RangeUnionSubset(range(100), [range(0, 10), range(50, 75)])

assert len(subset) == 35
assert 9 in subset
assert 20 not in subset
assert 55 in subset

# complement is calculated efficiently
print(~subset)
# RangeUnionSubset(universe_range=range(0, 100), ranges=[range(10, 50), range(75, 100)])

# likewise with intersections, unions, and differences
subset2 = RangeUnionSubset(range(100), [range(40, 60)])

print(subset & subset2)
# RangeUnionSubset(universe_range=range(0, 100), ranges=[range(50, 60)])

print(subset | subset2)
# RangeUnionSubset(universe_range=range(0, 100), ranges=[range(0, 10), range(40, 75)])

print(subset - subset2)
# RangeUnionSubset(universe_range=range(0, 100), ranges=[range(0, 10), range(60, 75)])

License

This library is open-source and licensed under the MIT License.

Contributions are welcome!

Metadata

Release files for setfield 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for setfield 0.2.5
File Size Uploaded
setfield-0.2.5.tar.gz 20.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for setfield 0.2.5
File Interpreter ABI Platform
setfield-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 35.5 kB

Release files / setfield-0.2.5.tar.gz

Download URL setfield-0.2.5.tar.gz
Size 20.6 kB
Tags Source
SHA-256 checksum
How to use checksums
ec910a01f2707c557c81dc21fcb402a6c6574b9d52856303ddef5a1179301fdc
BLAKE2b-256 checksum
How to use checksums
71bb7b5d606523d99f9288fb7cb797c33574361545745c29cdbe266767ced480
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.5 cpython/3.13.11 HTTPX/0.28.1

Release files / setfield-0.2.5-py3-none-any.whl

Download URL setfield-0.2.5-py3-none-any.whl
Size 14.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
46a7b470bcca0655607751d3654ed508fc6e76d5862c8590aac927791fca1495
BLAKE2b-256 checksum
How to use checksums
02381782962f20a7ad901bdeff498fb5dad565f6ebf7d0029934b5ee2e599f3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.5 cpython/3.13.11 HTTPX/0.28.1

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page