Author

Owen Lynch

Published

2023-11-14

Abstract

Announcing the first version of InterTypes: a package for cross-language serialization for ADTs and ACSets

This is a crosspost from the AlgebraicJulia blog.

1 Motivation

Part of the AlgebraicJulia vision for scientific computing is that a scientific model should be piece of data that can be inspected, analyzed, passed between programming languages, and saved in a database.

In order to do this, we need to make sure that different languages can load and save the models.

One way to do this would be to define a data type for “all scientific models”, and then implement that data type in each programming language we care about. But this is clearly ridiculous; there is no one data type that can encompass every single scientific model. Moreover, often we want to specify that we only want a certain type of scientific model.

Another approach would be to manually implement, for each type of scientific model, types in every language we care about. However, this is an m \times n problem, where m is the number of languages and n is the number of types of scientific models. Moreover, it is error-prone (because there are subtle differences between the type systems of different languages), and would be a massive drag on rapid iteration; any new type of model or change to a modeling framework needs to be implemented across many different languages.

The better way to do it would be to define your types once, in a language-agnostic way, and then generate the types in each language automatically along with serialization/deserialization code. This sort of system has been done before: see

The relevant XKCD is, of course,

So why make a new one? Well, I want to support ACSets natively, as many of our scientific models are built on top of them (Patterson, Lynch, and Fairbanks 2021). And it seemed that modifying an existing system would be more work than building a new one from scratch. But more importantly, I find that building this kind of thing from scratch gives you a much better picture of the kind of design decisions that go into this, and thus if I end up trying to modify a pre-existing one later down the line I’ll have a better idea of how to go about it.

One difference between InterTypes and these other formats is that I don’t intend (at least at first) to have a custom serialization format that goes along with it. The main feature of InterType is to generate the data structures in each programming language. Currently we have serialization/deserialization to JSON (including 64-bit integer support!), but we could also support other serialization formats. The whole point of InterTypes is that you shouldn’t have to think about the underlying serialization details. Along with this, from an intertype specification one can generate a JSONSchema file that describes the JSON produced by the automatically generated serialization.

2 Use

WARNING: InterTypes is alpha-quality software, and not only are there certainly bugs but also the interface to it may change radically.

The core of InterTypes is the intertype schema, which declares a collection of types that can refer to one another. An intertype schema is a file ending in .it. Currently, we use the Julia parser to parse the .it file, and we use Julia to generate code for all languages. However, we hope to in the future to produce a standalone binary that will parse the .it file and generate the code in other languages. So although .it files look like Julia, most features of Julia will not work with in an intertype schema; for instance, you cannot define functions in an intertype schema, or refer to types that are defined outside of an intertype schema.

There are 4 fundamental building blocks of InterTypes.

  1. Primitive types.
  • Int32/Int64/UInt32/UInt64 for integer numbers. We have 32 bit and 64 bit integers, because only 32 bit integers are safe to put in JSON numbers and 64 bit integers must be put in JSON strings.
  • Bool for booleans.
  • Float64 for floating point numbers.
  • String for strings.
  • Symbol for symbols. In languages that don’t have symbols, this is the same as String.
  • Vector{T} for representing sequences (arrays and lists) of type T
  • Binary for sequences of raw bytes without a numeric interpretation. In Julia, this maps to Vector{UInt8}, but we think of it as a binary blob rather than a sequence of values.
  • Dict{K,V} for representing dictionaries with key type K and value type V.
  1. Structs. A struct has a list of fields and each field has a name and a type. This looks like:
struct Point2D
  x::Float64
  y::Float64
end
  1. Sum types, also known as “tagged unions”. A sum type has a list of variants, and each variant is a record containing fields. This looks like
@sum Op begin
  Plus
  Mul
end

@sum Term begin
  Constant(val::Float64)
  App(op::Op, arg1::Term, arg2::Term)
end
  1. ACSets. ACSets are handled a little differently than they work in Julia, in order to paper over the fact that I have yet to fully figure out Python’s (and pydantic’s, which is the validation/serialization framework) support for generic types. When you declare the schema, you have to specify a concrete type for every AttrType. Then, when you declare an instance of the schema, you do not get a generic instance like you do in Julia; you get an instance with attribute types fixed to the supplied types. This looks like:
struct EdgeData
  name::Symbol
  length::UInt64
end

@schema SchGraph begin
  (E,V)::Ob
  (src, tgt)::Hom(E, V)
end

@schema SchWeightedGraph <: SchGraph begin
  Weight::AttrType(EdgeData) # note that we provide a type here
  weight::Attr(E, Weight)
end

@abstract_acset_type AbstractGraph

@acset_type EDWeightedGraph(SchWeightedGraph,
                            generic=WeightedGraph, index=[:src, :tgt]) <: AbstractGraph

This is equivalent to the Julia code

struct EdgeData
  name::Symbol
  length::UInt64
end

@schema SchGraph begin
  (E,V)::Ob
  (src, tgt)::Hom(E, V)
end

@schema SchWeightedGraph <: SchGraph begin
  Weight::AttrType # note that there is no type here
  weight::Attr(E, Weight)
end

@abstract_acset_type AbstractGraph

@acset_type WeightedGraph(SchWeightedGraph, index=[:src, :tgt]) <: AbstractGraph

const EDWeightedGraph = WeightedGraph{EdgeData}

However in the Python code, no data structure with the name WeightedGraph is produced; only EDWeightedGraph. This is because the Python and Julia ACSets code were written pre-intertype, so their handling of attrtypes weren’t fully compatible, and we had to get something working; hopefully in the future Python and Julia will be more congruous. This is a good first issue for someone familiar with types in Python/pydantic!

To use an intertype schema, one “declares an intertype module” like so:

@intertypes "weightedgraph.it" module weightedgraph end

Then weightedgraph is a module that contains an export for each type defined in weightedgraph.it. It also contains a Meta variable, which stores the parsed intertype definition. This can then be used to write out generated python code, via

generate_python_module(weightedgraph, ".")

which writes a python file called weightedgraph.py in the current directory. This python file imports both acsets and intertypes, so in order to use it one must have the py-acsets library installed, and also a copy of intertypes.py, which can be produced with

write("intertypes.py", InterTypes.INTERTYPE_PYTHON_MODULE)

In a similar manner, a JSONSchema definition for the json produced by intertypes can be produced with

generate_jsonschema_module(weightedgraph, ".")

which writes a JSONSchema file called weightedgraph_schema.json in the current directory. This is a file which has a JSONSchema def for each type in the intertype definition file.

Intertype modules can refer to one another. For instance, we could write another file called twoweightedgraphs.it with contents of:

struct TwoWeightedGraphs
  g1::weightedgraph.EDWeightedGraph
  g2::weightedgraph.EDWeightedGraph
end

and then import it like:

@intertypes "twoweightedgraphs.it" module twoweightedgraphs
  import ..weightedgraph
end

In fact, weightedgraph.it and twoweightedgraphs.it could be in completely different packages; as long as the first package exports the weightedgraph Julia module this will work fine.

For more examples of how to use intertypes, it would probably be best to refer to the test file.

3 Future Work

There are a lot of directions I’m excited to take intertypes in.

First of all, I need to write more documentation beyond this blog post.

After that, I plan to add support for Scala, TypeScript, and Rust. Scala in particular would solve a lot of problems between AlgebraicJulia and Semagrams, so I’m going to tackle that next.

Thirdly, I’d like to think about integrating GATlab with InterType, so that scientific models with algebraic expressions in them can be first-class.

Longer down the road, I want to investigate combinatorial data structures beyond acsets, as laid out in array systems and combinatorial data structures via finite existential types, and also think about structured version control for intertypes in line with chit.

But finally, I want to use intertypes to make the vision at the beginning a reality, a vision where scientific models can be passed around between programming languages and stored in databases. This is beyond a technical vision; this is a social vision; I hope to reshape how people think about scientific models. If you are interested in this, please reach out on the category theory zulip, julia zulip, localcharts, or github issues.

References

Alagic, Suad, and Mara Alagic. 1991. “Joins as Pullbacks.” In Third Workshop on Foundations of Models and Languages for Data and Objects, Aigen, Austria, 23.-27. September 1991, edited by Jutta Göers, Andreas Heuer, and Gunter Saake, 91/3:197–207. Informatik-Berichte Des IfI. Technische Universität Clausthal.
Awodey, Steve. 2010. Category Theory. 2nd ed. Oxford Logic Guides. London, England: Oxford University Press.
Baez, John C., and Kenny Courser. 2019. “Structured Cospans.”
Baez, John C., and Jade Master. 2020. “Open Petri Nets.” Mathematical Structures in Computer Science 30 (3): 314–41. https://doi.org/10.1017/s0960129520000043.
Baez, John C., and Blake S. Pollard. 2017. “A Compositional Framework for Reaction Networks.” https://doi.org/10.1142/S0129055X17500283.
Baez, John, and Mike Stay. 2011. Physics, Topology, Logic and Computation: A Rosetta Stone. Springer.
Bailer-Jones, Daniela M. 2009. Scientific Models in Philosophy of Science. University of Pittsburgh Press. https://doi.org/10.2307/j.ctt5vkdnq.
Benedikt, Michael, George Konstantinidis, Giansalvatore Mecca, Boris Motik, Paolo Papotti, Donatello Santoro, and Efthymia Tsamoura. 2017. “Benchmarking the Chase.” In Proceedings of the 36th ACM SIGMOD-SIGACT-SIGAI Symposium on Principles of Database Systems. ACM. https://doi.org/10.1145/3034786.3034796.
Bonchi, Filippo, Fabio Gadducci, Aleks Kissinger, Pawel Sobocinski, and Fabio Zanasi. 2020. “String Diagram Rewrite Theory i: Rewriting with Frobenius Structure.”
Brachman, Ronald, and Hector Levesque. 2004. Knowledge Representation and Reasoning. Elsevier. https://doi.org/10.1016/b978-1-55860-932-7.x5083-3.
Brown, Kristopher, Evan Patterson, Tyler Hanks, and James Fairbanks. 2022. “Computational Category-Theoretic Rewriting.” In Graph Transformation, 155–72. Springer International Publishing. https://doi.org/10.1007/978-3-031-09843-7_9.
———. 2023. “Computational Category-Theoretic Rewriting.” Journal of Logical and Algebraic Methods in Programming, 100888. https://doi.org/10.1016/j.jlamp.2023.100888.
Brown, Kristopher, and David I. Spivak. 2023. “Dynamic Tracing: A Graphical Language for Rewriting Protocols.” https://arxiv.org/abs/2304.14950.
Cartmell, John. 1986. “Generalised Algebraic Theories and Contextual Categories.” Annals of Pure and Applied Logic 32: 209–43. https://doi.org/10.1016/0168-0072(86)90053-9.
Cicala, Daniel. 2020. “Rewriting Structured Cospans.”
Courser, Kenny. 2020. “Open Systems: A Double Categorical Perspective.”
Datseris, George, Jonas Isensee, Sebastian Pech, and Tamás Gál. 2020. DrWatson: The Perfect Sidekick for Your Scientific Inquiries.” Journal of Open Source Software 5 (54): 2673. https://doi.org/10.21105/joss.02673.
DeVille, Lee, and Eugene Lerman. 2012. “Dynamics on Networks of Manifolds.” https://doi.org/10.3842/SIGMA.2015.022.
Ehrig, H., M. Pfender, and H. J. Schneider. 1973. “Graph-Grammars: An Algebraic Approach.” In 14th Annual Symposium on Switching and Automata Theory (Swat 1973). IEEE. https://doi.org/10.1109/swat.1973.11.
Eisenbud, David, and Joe Harris. 2000. The Geometry of Schemes. Vol. 197. Graduate Texts in Mathematics. New York: Springer-Verlag. https://doi.org/10.1007/b97680.
Ellis-Monaghan, Joanna A., and Iain Moffatt. 2013. Graphs on Surfaces. Springer New York. https://doi.org/10.1007/978-1-4614-6971-1.
Fong, Brendan. 2015. “Decorated Cospans.”
Fong, Brendan, and David I Spivak. 2018a. “Graphical Regular Logic.”
———. 2018b. “Seven Sketches in Compositionality: An Invitation to Applied Category Theory.”
Fong, Brendan, and David I. Spivak. 2019. “Hypergraph Categories.” Journal of Pure and Applied Algebra 223 (11): 4746–77. https://doi.org/10.1016/j.jpaa.2019.02.014.
Ghallab, Malik, Adele E. Howe, Craig A. Knoblock, Drew McDermott, Ashwin Ram, Manuela M. Veloso, Daniel S. Weld, and David E. Wilkins. 1998. “PDDL-the Planning Domain Definition Language.” In.
Ghallab, Malik, Dana Nau, and Paolo Traverso. 2004. Automated Planning. Elsevier. https://doi.org/10.1016/b978-1-55860-856-6.x5000-5.
Goguen, Joseph A. 2021. “Theorem Proving and Algebra.” arXiv:2101.02690 [Cs], January. http://arxiv.org/abs/2101.02690.
Gross, Jonathan L., and Thomas W. Tucker. 1987. Topological Graph Theory. USA: Wiley-Interscience.
Hammack, Richard, Wilfried Imrich, and Sandi Klavžar. 2011. Handbook of Product Graphs. CRC Press. https://doi.org/10.1201/b10959.
Hartke, Stephen G., and A. J. Radcliffe. 2009. McKay’s Canonical Graph Labeling Algorithm.” American Mathematical Society. https://doi.org/10.1090/conm/479/09345.
Hell, Pavol, and Jaroslav Nesetril. 2004. Graphs and Homomorphisms. Oxford University Press. https://doi.org/10.1093/acprof:oso/9780198528173.001.0001.
Johnstone, Peter T. 2002. Sketches of an Elephant: A Topos Theory Compendium, Volume 1. Oxford, England: Clarendon Press.
Kato, Akihiko. 1983. AN ABSTRACT RELATIONAL MODEL AND NATURAL JOIN FUNCTORS .” Bulletin of Informatics and Cybernetics 20 (3/4): 95–106. https://doi.org/10.5109/13349.
Kock, Joachim. 2020. “Whole-Grain Petri Nets and Processes.” https://doi.org/10.1145/3559103.
Lando, Sergei K., and Alexander K. Zvonkin. 2004. Graphs on Surfaces and Their Applications. Springer Berlin Heidelberg. https://doi.org/10.1007/978-3-540-38361-1.
Lane, Saunders Mac. 1978. Categories for the Working Mathematician. Springer New York. https://doi.org/10.1007/978-1-4757-4721-8.
Lawvere, F. William. 1973. “Metric Spaces, Generalized Logic, and Closed Categories.” Rendiconti Del Seminario Matematico e Fisico Di Milano 43 (1): 135–66. https://doi.org/10.1007/bf02924844.
———. 1986. “Categories of Spaces May Not Be Generalized Spaces as Exemplified by Directed Graphs.” In. http://tac.mta.ca/tac/reprints/articles/9/tr9abs.html.
Libkind, Sophie. 2020. “An Algebra of Resource Sharing Machines.”
Marcolli, Matilde, and Alexander Port. 2015. “Graph Grammars, Insertion Lie Algebras, and Quantum Field Theory.” Mathematics in Computer Science 9 (4): 391–408. https://doi.org/10.1007/s11786-015-0236-y.
Markl, M., S. Merkulov, and S. Shadrin. 2009. “Wheeled PROPs, Graph Complexes and the Master Equation.” Journal of Pure and Applied Algebra 213 (4): 496–535. https://doi.org/10.1016/j.jpaa.2008.08.007.
McKay, Brendan D., and Adolfo Piperno. 2014. “Practical Graph Isomorphism, II.” Journal of Symbolic Computation 60 (January): 94–112. https://doi.org/10.1016/j.jsc.2013.09.003.
Mishra, Priti, and Margaret H. Eich. 1992. “Join Processing in Relational Databases.” ACM Computing Surveys 24 (1): 63–113. https://doi.org/10.1145/128762.128764.
Mohar, Bojan, and Carsten Thomassen. 2001. “Graphs on Surfaces.” In Johns Hopkins Series in the Mathematical Sciences.
Myers, David Jaz. 2022. Categorical Systems Theory. https://github.com/DavidJaz/DynamicalSystemsBook.
Niu, Nelson, and David I Spivak. n.d. “Polynomial Functors: A General Theory of Interaction.”
Patterson, Evan. 2017. “Knowledge Representation in Bicategories of Relations.”
Patterson, Evan, Owen Lynch, and James Fairbanks. 2021. “Categorical Data Structures for Technical Computing.” https://doi.org/10.32408/compositionality-4-5.
Reyes, Gonzalo E., and Houman Zolfaghari. 1996. “Bi-Heyting Algebras, Toposes and Modalities.” Journal of Philosophical Logic 25 (1): 25–43. https://doi.org/10.1007/bf00357841.
Reyes, Marie La Palme, Gonzalo E. Reyes, and Houman Zolfaghari. 2004. “Generic Figures and Their Glueings: A Constructive Approach to Functor Categories.” In. https://marieetgonzalo.files.wordpress.com/2004/06/generic-figures.pdf.
Riehl, Emily. 2016. Category Theory in Context. Mineola, NY: Dover Publications. http://www.math.jhu.edu/~eriehl/context.pdf.
Schultz, Patrick, David I. Spivak, and Christina Vasilakopoulou. 2016. “Dynamical Systems and Sheaves.”
Schultz, Patrick, David I. Spivak, Christina Vasilakopoulou, and Ryan Wisnesky. 2016. “Algebraic Databases.”
Selinger, Peter. 2011. “A Survey of Graphical Languages for Monoidal Categories.” New Structures for Physics, 289–355.
Simon, Herbert A. 1988. “The Science of Design: Creating the Artificial.” Design Issues 4 (1/2): 67. https://doi.org/10.2307/1511391.
Spivak, David I. 2014. Category Theory for the Sciences. The MIT Press. London, England: MIT Press.
Spivak, David I. 2009. “Higher-Dimensional Models of Networks.”
———. 2012. “Functorial Data Migration.” Information and Computation 217 (August): 31–51. https://doi.org/10.1016/j.ic.2012.05.001.
———. 2013. “The Operad of Wiring Diagrams: Formalizing a Graphical Language for Databases, Recursion, and Plug-and-Play Circuits.”
Spivak, David I., and Robert E. Kent. 2012. “Ologs: A Categorical Framework for Knowledge Representation.” Edited by Chris Mavergames. PLoS ONE 7 (1): e24274. https://doi.org/10.1371/journal.pone.0024274.
Tarski, Alfred. 1994. Introduction to Logic and to the Methodology of Deductive Sciences. 4th ed. Oxford Logic Guides. New York, NY: Oxford University Press.
“The Structure of Scientific Revolutions, (Third Edition).” 1997. Computers & Mathematics with Applications 33 (5): 129. https://doi.org/10.1016/s0898-1221(97)82935-5.
Vagner, Dmitry, David I. Spivak, and Eugene Lerman. 2014. “Algebras of Open Dynamical Systems on the Operad of Wiring Diagrams.”
Vakil, Ravi. 2017. “The Rising Sea.” https://math.stanford.edu/~vakil/216blog/FOAGnov1817public.pdf.

Comments