Nettlesome: Simplified Semantic Reasoning in Python
I’m happy to announce I’ve published a new Python package called Nettlesome, for creating computable semantic tags that describe the contents of documents. When you browse through Nettlesome’s documentation, you’ll see a lot of concepts that look like refugees from logic programming, like Terms and Predicates. And yet Nettlesome doesn’t have any way to create a set of assertions about which Statements imply one another, nor does it have a function for theorem proving. So why does Nettlesome exist, and what gap does it fill?
Nettlesome originated as a spinoff of my primary Python project, AuthoritySpoke. AuthoritySpoke is a library that enables semantic reasoning with legal data. But I eventually found that AuthoritySpoke needed distinct layers: the top layer of legal analysis was built atop a layer of general-purpose semantic reasoning tasks, such as testing whether quantitative statements imply or contradict one another. Moving the general-purpose features to the separate Nettlesome package should help keep the code more organized. It also means that I have the freedom to make AuthoritySpoke more specific and limited, because I know Nettlesome will exist separately to support other projects that might develop in other directions. This way, AuthoritySpoke doesn’t have to be a library for “all legal analysis”. It can be limited to just common law jurisdictions, just the United States, just the judicial branch of government, or whatever. Nettlesome, on the other hand, can be a “legaltech” package without the baggage of any particular legal system or legal industry.
Separating Nettlesome into its own package has also made it easier for me to integrate Nettlesome with Sympy, the Python library for symbolic math. In the short term, importing Sympy has helped me delete some poorly-written math functions of mine, and replace them with some well-written imported code I’ll hopefully never need to help maintain. But in the longer term I think future versions of Nettlesome (and AuthoritySpoke) can lean on Sympy to enable more complex math calculations, like finding the sum of the different parts of a monetary judgment or a criminal sentence. I’ve already found the Pint package to be easy to use and integrate. Pint supports calculations with quantities measured in all the familiar units from a physics class: minutes, kilometers per hour, square feet, ounces, and so on. Here’s an example calculation where Pint, Sympy, and Nettlesome are all working together:
>>> from nettlesome import Comparison, Entity, Statement
>>> under_1mi = Comparison("the distance from $site1 to $site2 was", sign="<", expression="1 mile")
>>> under_2km = Comparison("the distance from $site1 to $site2 was", sign="<", expression="2 kilometers")
>>> meeting = Entity("the political convention")
>>> protest = Entity("the free speech zone")
>>> under_1mi_to_protest = Statement(under_1mi, terms=[protest, meeting])
>>> under_2km_to_protest = Statement(under_2km, terms=[meeting, protest])
>>> str(under_1mi_to_protest)
'the statement that the distance from <the free speech zone> to <the political convention> was less than 1 mile'
>>> str(under_2km_to_protest)
'the statement that the distance from <the political convention> to <the free speech zone> was less than 2 kilometer'
>>> under_1mi_to_protest.implies(under_2km_to_protest)
True
>>> under_2km_to_protest.implies(under_1mi_to_protest)
False
>>> under_1mi_to_protest.contradicts(under_2km_to_protest)
False
>>> under_2km_to_protest.contradicts(under_1mi_to_protest)
False
So please check out the introduction and examples in Nettlesome’s documentation, import Nettlesome from the Python Package Index, try it out, and open a Github issue for any bugs, suggestions, concerns, or feature requests.