{ "cells": [ { "cell_type": "markdown", "id": "ffb0f1e5-557b-4b3a-892b-c6f0942e647b", "metadata": {}, "source": [ "This notebook shows the use of Macaulay2 with a SageMath kernel." ] }, { "cell_type": "markdown", "id": "84aceffa-7a07-4d04-8a48-1a8ad2e0845a", "metadata": {}, "source": [ "# 1. Resultants" ] }, { "cell_type": "markdown", "id": "66419cab-4d13-4f04-8ae7-fd2b1dd07b1c", "metadata": {}, "source": [ "We work with polynomials with integer coefficients in `x` and `y`. So, our polynomial ring `R` is `ZZ[x,y]`." ] }, { "cell_type": "code", "execution_count": 1, "id": "90bb1048-58be-44a7-93ff-c0794657b2e9", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "R\n", "\n", "PolynomialRing\n" ] } ], "source": [ "%%macaulay2\n", "R = ZZ[x,y]" ] }, { "cell_type": "code", "execution_count": 2, "id": "45cdccf9-a38e-4d22-85b9-b12f9716701d", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "%%macaulay2\n", "p = 4*y^2 - 4 + 4*x*y + x^2;" ] }, { "cell_type": "markdown", "id": "d17af91e-aa39-4926-b304-7fc9c6d5d220", "metadata": {}, "source": [ "Using the semincolon at the end suppresses the output." ] }, { "cell_type": "code", "execution_count": 3, "id": "e46eff6f-cb33-44b6-9fe5-f8c5b661fd00", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 2 2\n", "4x - 4x*y + y - 4\n", "\n", "R\n" ] } ], "source": [ "%%macaulay2\n", "q = 4*x^2 - 4*x*y + y^2 - 4" ] }, { "cell_type": "code", "execution_count": 4, "id": "defdc0d6-ccb2-4d44-b7cb-3843c6f0e76d", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 4 2\n", "625y - 1000y + 144\n", "\n", "R\n" ] } ], "source": [ "%%macaulay2\n", "rx = resultant(p,q,x)" ] }, { "cell_type": "markdown", "id": "3e8e0554-50d0-4928-924f-6d64afac8798", "metadata": {}, "source": [ "The resultant is the determinant of the *Sylvester matrix*." ] }, { "cell_type": "code", "execution_count": 5, "id": "913316cf-6927-4562-a20d-c30badd6948a", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{-3} | 1 4y 4y2-4 0 |\n", "{-2} | 0 1 4y 4y2-4 |\n", "{-3} | 4 -4y y2-4 0 |\n", "{-2} | 0 4 -4y y2-4 |\n", "\n", " 4 4\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "M = sylvesterMatrix(p,q,x)" ] }, { "cell_type": "code", "execution_count": 6, "id": "db962950-f80d-4068-829e-205d90ba13d6", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 4 2\n", "625y - 1000y + 144\n", "\n", "R\n" ] } ], "source": [ "%%macaulay2\n", "determinant(M)" ] }, { "cell_type": "markdown", "id": "93627d26-6ac5-4e4e-8c76-83593fc91fa8", "metadata": {}, "source": [ "# 2. Solving Polynomial Systems Numerically" ] }, { "cell_type": "markdown", "id": "8e61bd8f-d24f-4c04-9ac6-fd4e0a996cbd", "metadata": {}, "source": [ "For the commands in this section to work, the executable `phc` must be available in the path. This executable can be found from the assets of the tags of the github release of PHCpack." ] }, { "cell_type": "code", "execution_count": 7, "id": "8a322b6d-86e3-4ef3-89b4-de326d26454f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PHCpack\n", "\n", "Package\n" ] } ], "source": [ "%%macaulay2\n", "loadPackage(\"PHCpack\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "9c5d93a5-d725-418a-87af-b7b3040dcf29", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "R\n", "\n", "PolynomialRing\n" ] } ], "source": [ "%%macaulay2 \n", "R = CC[x,y]" ] }, { "cell_type": "code", "execution_count": 9, "id": "7124971d-bd61-4dce-9f3e-a0b736b1cd0a", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 2 2 2 2\n", "{x + 4x*y + 4y - 4, 4x - 4x*y + y - 4}\n", "\n", "List\n" ] } ], "source": [ "%%macaulay2\n", "F = {4*y^2 - 4 + 4*x*y + x^2,\n", " 4*x^2 - 4*x*y + y^2 - 4}" ] }, { "cell_type": "code", "execution_count": 10, "id": "86b9b151-3145-42df-ab01-5e4cc925c0cf", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{{.4, -1.2}, {-1.2, -.4}, {1.2, .4}, {-.4, 1.2}}\n", "\n", "List\n" ] } ], "source": [ "%%macaulay2\n", "s = solveSystem(F)" ] }, { "cell_type": "markdown", "id": "f1077ce0-28d0-4141-aeb7-b2fce927b693", "metadata": {}, "source": [ "# 3. The Ideal of a Monomial Curve" ] }, { "cell_type": "markdown", "id": "2565edcb-a7e1-4be8-ba71-231f99b92c05", "metadata": {}, "source": [ "Following one of the tutorials of Macaulay2\n", "written by David Eisenbud and Michael Stillman.\n", "\n", "Our first example considers the rational quartic curve\n", "defined parametrically in affine coordinates as\n", "\n", "$$\n", " t \\mapsto (t, t^3, t^4).\n", "$$" ] }, { "cell_type": "markdown", "id": "a2740a90-bcbd-492f-be1d-30bbb628b705", "metadata": {}, "source": [ "Let us first compute its ideal as follows:\n", "\n", "1. We work modulo 31991, in ${\\mathbb K} = {\\mathbb Z}_{31991}$.\n", "\n", "2. In projective 3-space, we make a polynomial ring in\n", " four variables ${\\mathbb R} = {\\mathbb K}[a,b,c,d]$.\n", "\n", "3. With the degrees 1, 3, and 4 of the parametric representation\n", " of the quartic, we can ask Macaulay2 for the ideal of the quartic:\n", "\n", " $$\n", " I = \\langle b c - a d, c^3 - b d^2, a c^2 - b^2 d, b^3 - a^2 c \\rangle. \n", " $$" ] }, { "cell_type": "code", "execution_count": 11, "id": "b4951dd2-bab0-48c0-a52a-d72d13bb42c2", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "KK\n", "\n", "QuotientRing\n" ] } ], "source": [ "%%macaulay2\n", "KK = ZZ/31991" ] }, { "cell_type": "code", "execution_count": 12, "id": "a9b4a055-c832-4490-88d8-06fa2f1ca824", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "R\n", "\n", "PolynomialRing\n" ] } ], "source": [ "%%macaulay2\n", "R = KK[a..d]" ] }, { "cell_type": "code", "execution_count": 13, "id": "b6104cc4-601f-4373-87dc-75e989d0a690", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 3 2 2 2 3 2\n", "ideal (b*c - a*d, c - b*d , a*c - b d, b - a c)\n", "\n", "Ideal of R\n" ] } ], "source": [ "%%macaulay2\n", "I = monomialCurveIdeal(R,{1,3,4})" ] }, { "cell_type": "markdown", "id": "a36cf8fc-683f-4e46-973b-7e9d268ab12d", "metadata": {}, "source": [ "In ${\\mathbb K}[a,b,c,d]$, the ideal\n", "\n", "$$\n", " I = \\langle b c - a d, c^3 - b d^2, a c^2 - b^2 d, b^3 - a^2 c \\rangle\n", "$$\n", "\n", "contains all polynomials that vanish on the curve $(t, t^3, t^4)$,\n", "\n", "or $[1:t:t^3:t^4] \\in {\\mathbb P}^3$, set $a=1$, $b=t$, $c=t^3$, $d=t^4$." ] }, { "cell_type": "code", "execution_count": 14, "id": "8c601ad6-c443-4ee7-82b3-23355676c75d", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "| bc-ad c3-bd2 ac2-b2d b3-a2c |\n", "\n", " 1 4\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "J = groebnerBasis I" ] }, { "cell_type": "code", "execution_count": 15, "id": "ae9f9538-2d08-4b64-94e8-a7a5720e9f15", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "%%macaulay2\n", "dim I" ] }, { "cell_type": "code", "execution_count": 16, "id": "e68ec1f1-1a39-45b9-8f08-94ba7e20cfac", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n" ] } ], "source": [ "%%macaulay2\n", "degree I" ] }, { "cell_type": "markdown", "id": "3069ee1a-7209-42bc-ab6c-f7528e8553dd", "metadata": {}, "source": [ "Let us compute the kernel and co-kernel of the generators of this ideal." ] }, { "cell_type": "code", "execution_count": 17, "id": "98702749-5f90-4001-bc0e-7575740621a2", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "| bc-ad c3-bd2 ac2-b2d b3-a2c |\n", "\n", " 1 4\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "gens I" ] }, { "cell_type": "code", "execution_count": 18, "id": "c98ccef4-3ea5-445f-b8cd-26efeb7c7032", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cokernel | bc-ad c3-bd2 ac2-b2d b3-a2c |\n", "\n", " 1\n", "R-module, quotient of R\n" ] } ], "source": [ "%%macaulay2\n", "M = coker gens I" ] }, { "cell_type": "code", "execution_count": 19, "id": "ca49abf2-2787-4b7e-8789-082fcaf33f18", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "image {2} | c2 bd ac b2 |\n", " {3} | -b -a 0 0 |\n", " {3} | d c -b -a |\n", " {3} | 0 0 -d -c |\n", "\n", " 4\n", "R-module, submodule of R\n" ] } ], "source": [ "%%macaulay2\n", "ker gens I" ] }, { "cell_type": "markdown", "id": "adbbfbe9-f43a-4dab-8bdb-23fa8e66a939", "metadata": {}, "source": [ "The degree of the Hilbert polynomial gives the dimension." ] }, { "cell_type": "code", "execution_count": 20, "id": "b0b0a01b-2c0a-4bb2-bf79-7a3209ed2ee0", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "- 3*P + 4*P\n", " 0 1\n", "\n", "ProjectiveHilbertPolynomial\n" ] } ], "source": [ "%%macaulay2\n", "hilbertPolynomial M" ] }, { "cell_type": "code", "execution_count": 21, "id": "a48f97ec-1ddc-4613-8a1f-f131387534fd", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 2 3 4 5\n", " 1 - T - 3T + 4T - T\n", "i11:-----------------------\n", " 4\n", " (1 - T)\n", "\n", "Expression of class BinaryOperation\n" ] } ], "source": [ "%%macaulay2\n", "i11 : hilbertSeries M" ] }, { "cell_type": "markdown", "id": "faf7d6a1-20f8-4e20-95a1-fda69f60c84f", "metadata": {}, "source": [ "To conclude this tutorial section, we compute free resolutions and Betti tables." ] }, { "cell_type": "code", "execution_count": 22, "id": "137883cd-4d7c-4754-b49d-8fbc0d9ad789", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1 4 4 1\n", "R <-- R <-- R <-- R <-- 0\n", " \n", "0 1 2 3 4\n", "\n", "ChainComplex\n" ] } ], "source": [ "%%macaulay2\n", "mres = res M" ] }, { "cell_type": "code", "execution_count": 23, "id": "949f3dbf-c4a6-4692-bef6-bafdf0ea9403", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 0 1 2 3\n", "total: 1 4 4 1\n", " 0: 1 . . .\n", " 1: . 1 . .\n", " 2: . 3 4 1\n", "\n", "BettiTally\n" ] } ], "source": [ "%%macaulay2\n", "betti mres" ] }, { "cell_type": "markdown", "id": "100c9e59-8a90-4c41-beb5-142b1fb8bbd5", "metadata": {}, "source": [ "# 4. Elimination: Projecting the Twisted Cubic" ] }, { "cell_type": "markdown", "id": "d7b3daa2-accb-4d0f-8010-bc72c19e6d7f", "metadata": {}, "source": [ "The twisted cubic is a space curve defined parametrically as\n", "\n", "$$\n", " t \\mapsto (t, t^2, t^3)\n", "$$\n", "or by the equations $y = x^2$ and $z = x^3$, in affine coordinates.\n", "\n", "Consider the three 2-by-2 minors of the matrix\n", "\n", "$$\n", " \\left[\n", " \\begin{array}{ccc}\n", " x_0 & x_1 & x_2 \\\\\n", " x_1 & x_2 & x_3\n", " \\end{array}\n", " \\right]\n", "$$\n", "\n", "in the ring ${\\mathbb R} = {\\mathbb K}[x_0,x_1,x_2,x_3]$ and define\n", "the ideal\n", "\n", "$$\n", " I = \\langle\n", " \\left|\n", " \\begin{array}{cc}\n", " x_0 & x_1 \\\\\n", " x_1 & x_2\n", " \\end{array}\n", " \\right|,\n", " \\left|\n", " \\begin{array}{cc}\n", " x_0 & x_2 \\\\\n", " x_1 & x_3\n", " \\end{array}\n", " \\right|,\n", " \\left|\n", " \\begin{array}{cc}\n", " x_1 & x_2 \\\\\n", " x_2 & x_3\n", " \\end{array}\n", " \\right| \\rangle.\n", "$$\n", "\n", "Then we work in projective coordinates $[x_0:x_1:x_2:x_3] \\in {\\mathbb P}^3$." ] }, { "cell_type": "markdown", "id": "15320443-b85d-430a-9c3d-f0321e78a734", "metadata": {}, "source": [ "Let us make first the equations of the twisted cubic." ] }, { "cell_type": "code", "execution_count": 24, "id": "70227951-702b-4e55-95f8-2816f316dbb7", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "R\n", "\n", "PolynomialRing\n" ] } ], "source": [ "%%macaulay2\n", "R = KK[x0, x1, x2, x3]" ] }, { "cell_type": "code", "execution_count": 25, "id": "e790f818-f3a0-4838-a811-5ae00ec61b91", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "| x0 x1 x2 x3 |\n", "\n", " 1 4\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "v = vars(R)" ] }, { "cell_type": "code", "execution_count": 26, "id": "c16563cf-3aa8-4ce6-a7b5-8894f350bd43", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "| x0 x1 x2 |\n", "| x1 x2 x3 |\n", "\n", " 2 3\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "M = map(R^2, 3, (i,j)->v_(0,i+j))" ] }, { "cell_type": "code", "execution_count": 27, "id": "bd13cafe-2ec9-4a99-ade4-c188889df36e", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "| -x1^2+x0x2 -x1x2+x0x3 -x2^2+x1x3 |\n", "\n", " 1 3\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "I = gens minors(2, M)" ] }, { "cell_type": "markdown", "id": "2a3d99b3-4b7a-40d1-9875-d79b12acd0ca", "metadata": {}, "source": [ "To project the twisted cubic, we do the following:\n", "\n", "1. We define the center of the projection, as the point defined by\n", "\n", " $$\n", " \\langle x_0 + x_3, x_1, x_2 \\rangle.\n", " $$\n", "\n", "2. We set up a ring map\n", "\n", " * from the polynomial ring in the three variables, representing the plane,\n", "\n", " * to the quotient ring,\n", "\n", " taking the variables to the three linear forms\n", " that define the projection center.\n", "\n", "3. We compute the kernel of this map." ] }, { "cell_type": "markdown", "id": "10c43c85-3b20-4adb-86f4-db102dcc497d", "metadata": {}, "source": [ "Defining the center, variables, quotient ring is done below." ] }, { "cell_type": "code", "execution_count": 28, "id": "ce2f0a46-a234-40b8-8a32-954cea024513", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ideal (x0 + x3, x1, x2)\n", "\n", "Ideal of R\n" ] } ], "source": [ "%%macaulay2\n", "pideal = ideal(x0+x3, x1, x2)" ] }, { "cell_type": "code", "execution_count": 29, "id": "1ce8d570-e1ec-4d77-8c96-10c2271e2516", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "S1\n", "\n", "PolynomialRing\n" ] } ], "source": [ "%%macaulay2\n", "S1 = KK[y1, y2, y3]" ] }, { "cell_type": "code", "execution_count": 31, "id": "0ea9b3cc-1372-4690-aba4-b881af83ec94", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Rbar\n", "\n", "QuotientRing\n" ] } ], "source": [ "%%macaulay2\n", "Rbar = R/(ideal I)" ] }, { "cell_type": "markdown", "id": "0192f2cf-3e0f-4e75-a53e-3e72bca75bf6", "metadata": {}, "source": [ "Then, we let Macaulay2 define the map and compute its kernel." ] }, { "cell_type": "code", "execution_count": 33, "id": "697d2e4c-5cc1-493a-a2a9-ecc4d9537db4", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "map (Rbar, S1, {x0 + x3, x1, x2})\n", "\n", "RingMap Rbar <--- S1\n" ] } ], "source": [ "%%macaulay2\n", "f = map(Rbar, S1, matrix(Rbar,{{x0+x3, x1,x2}}))" ] }, { "cell_type": "code", "execution_count": 34, "id": "1032992a-c281-4596-a158-3fdb09f3bc3f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 3 3\n", "ideal(y2 - y1*y2*y3 + y3 )\n", "\n", "Ideal of S1\n" ] } ], "source": [ "%%macaulay2\n", "J1 = ker f" ] }, { "cell_type": "markdown", "id": "1ab34119-1323-4751-bab5-1dc8ce528dbb", "metadata": {}, "source": [ "# 5. quotients and saturation" ] }, { "cell_type": "markdown", "id": "beb33320-a701-437d-8c47-103742faf4e7", "metadata": {}, "source": [ "For $I$ and $J$ ideals in some ring $R$, the ideal quotient is\n", "\n", "$$\n", " (I:J) = \\{ \\ f \\in R \\ | f J \\subset I \\ \\}.\n", "$$\n", "\n", "We consider the case where $J$ is generated by one polynomial $g$.\n", "\n", "This case arises in the problem of homogenizing an ideal.\n", "\n", "Consider again the twisted cubic $t \\mapsto (t, t^2, t^3)$.\n", "\n", "Using $(a,b,c)$ as affine coordinates, the homogenization of $b = a^2$\n", "and $c = a^3$ happens with the addition of a fourth variable $d$ and\n", "leads to\n", "\n", "$$\n", " b d - a = 0, \\quad c d^2 - a^3 = 0.\n", "$$\n", " \n", "Problem: these two forms do not define the projective closure\n", "of the twisted cubic, because it contains $d = 0$ as well.\n", "\n", "To get the ideal of the closure we must remove unwanted components." ] }, { "cell_type": "code", "execution_count": 35, "id": "d08dd184-8723-4d24-bc2d-52e6b954af51", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "R\n", "\n", "PolynomialRing\n" ] } ], "source": [ "%%macaulay2\n", "R = KK[a,b,c,d]" ] }, { "cell_type": "code", "execution_count": 36, "id": "60ecdc59-0709-4f3a-a694-69f336a5bd97", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 2 3 2\n", "ideal (- a + b*d, - a + c*d )\n", "\n", "Ideal of R\n" ] } ], "source": [ "%%macaulay2\n", "I1 = ideal(d*b-a^2, d^2*c-a^3)" ] }, { "cell_type": "code", "execution_count": 37, "id": "fb38c533-9eef-4ea6-9f62-3011e551d36f", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "| a2-bd abd-cd2 b2d2-acd2 |\n", "\n", " 1 3\n", "Matrix R <--- R\n" ] } ], "source": [ "%%macaulay2\n", "gens gb I1" ] }, { "cell_type": "code", "execution_count": 38, "id": "48644872-38a1-403b-9d0c-8752533faa14", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(| a2-bd ab-cd b2-ac |, 2)\n", "\n", "Sequence\n" ] } ], "source": [ "%%macaulay2\n", "I2 = divideByVariable(gens gb I1,d)" ] }, { "cell_type": "code", "execution_count": 39, "id": "0fb9bff7-3ec5-45d5-a039-83787ef7177e", "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 2 2\n", "ideal (b - a*c, a*b - c*d, a - b*d)\n", "\n", "Ideal of R\n" ] } ], "source": [ "%%macaulay2\n", "saturate(I1, d)" ] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.5", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 5 }